Fixed seg fault for empty programs. Added more register optimizations.
[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 extern int debug_verbose;
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 /*
410     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
411                         __FUNCTION__,__LINE__,resIfx->lbl->key);
412 */
413   } else {
414     if(IC_TRUE(ifx)) {
415       resIfx->lbl = IC_TRUE(ifx);
416     } else {
417       resIfx->lbl = IC_FALSE(ifx);
418       resIfx->condition = 0;
419     }
420 /*
421     if(IC_TRUE(ifx)) 
422       DEBUGpic14_emitcode("; ***","ifx true is non-null");
423     if(IC_FALSE(ifx)) 
424       DEBUGpic14_emitcode("; ***","ifx false is non-null");
425 */
426   }
427
428   //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
429
430 }
431 /*-----------------------------------------------------------------*/
432 /* pointerCode - returns the code for a pointer type               */
433 /*-----------------------------------------------------------------*/
434 static int pointerCode (sym_link *etype)
435 {
436
437     return PTR_TYPE(SPEC_OCLS(etype));
438
439 }
440
441 /*-----------------------------------------------------------------*/
442 /* aopForSym - for a true symbol                                   */
443 /*-----------------------------------------------------------------*/
444 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
445 {
446     asmop *aop;
447     memmap *space= SPEC_OCLS(sym->etype);
448
449     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
450     /* if already has one */
451     if (sym->aop)
452         return sym->aop;
453
454     /* assign depending on the storage class */
455     /* if it is on the stack or indirectly addressable */
456     /* space we need to assign either r0 or r1 to it   */    
457     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
458         sym->aop = aop = newAsmop(0);
459         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
460         aop->size = getSize(sym->type);
461
462         /* now assign the address of the variable to 
463         the pointer register */
464         if (aop->type != AOP_STK) {
465
466             if (sym->onStack) {
467                     if ( _G.accInUse )
468                         pic14_emitcode("push","acc");
469
470                     pic14_emitcode("mov","a,_bp");
471                     pic14_emitcode("add","a,#0x%02x",
472                              ((sym->stack < 0) ?
473                               ((char)(sym->stack - _G.nRegsSaved )) :
474                               ((char)sym->stack)) & 0xff);
475                     pic14_emitcode("mov","%s,a",
476                              aop->aopu.aop_ptr->name);
477
478                     if ( _G.accInUse )
479                         pic14_emitcode("pop","acc");
480             } else
481                 pic14_emitcode("mov","%s,#%s",
482                          aop->aopu.aop_ptr->name,
483                          sym->rname);
484             aop->paged = space->paged;
485         } else
486             aop->aopu.aop_stk = sym->stack;
487         return aop;
488     }
489     
490     if (sym->onStack && options.stack10bit)
491     {
492         /* It's on the 10 bit stack, which is located in
493          * far data space.
494          */
495          
496       //DEBUGpic14_emitcode(";","%d",__LINE__);
497
498         if ( _G.accInUse )
499                 pic14_emitcode("push","acc");
500
501         pic14_emitcode("mov","a,_bp");
502         pic14_emitcode("add","a,#0x%02x",
503                  ((sym->stack < 0) ?
504                    ((char)(sym->stack - _G.nRegsSaved )) :
505                    ((char)sym->stack)) & 0xff);
506         
507         genSetDPTR(1);
508         pic14_emitcode ("mov","dpx1,#0x40");
509         pic14_emitcode ("mov","dph1,#0x00");
510         pic14_emitcode ("mov","dpl1, a");
511         genSetDPTR(0);
512         
513         if ( _G.accInUse )
514             pic14_emitcode("pop","acc");
515             
516         sym->aop = aop = newAsmop(AOP_DPTR2);
517         aop->size = getSize(sym->type); 
518         return aop;
519     }
520
521     //DEBUGpic14_emitcode(";","%d",__LINE__);
522     /* if in bit space */
523     if (IN_BITSPACE(space)) {
524         sym->aop = aop = newAsmop (AOP_CRY);
525         aop->aopu.aop_dir = sym->rname ;
526         aop->size = getSize(sym->type);
527         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
528         return aop;
529     }
530     /* if it is in direct space */
531     if (IN_DIRSPACE(space)) {
532         sym->aop = aop = newAsmop (AOP_DIR);
533         aop->aopu.aop_dir = sym->rname ;
534         aop->size = getSize(sym->type);
535         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
536         return aop;
537     }
538
539     /* special case for a function */
540     if (IS_FUNC(sym->type)) {   
541         sym->aop = aop = newAsmop(AOP_IMMD);    
542         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
543         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
544         strcpy(aop->aopu.aop_immd,sym->rname);
545         aop->size = FPTRSIZE; 
546         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
547         return aop;
548     }
549
550
551     /* only remaining is far space */
552     /* in which case DPTR gets the address */
553     sym->aop = aop = newAsmop(AOP_PCODE);
554
555     aop->aopu.pcop = popGetImmd(sym->rname,0,0);
556     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
557     PCOI(aop->aopu.pcop)->index = 0;
558
559     DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
560                         sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
561
562     allocDirReg (IC_LEFT(ic));
563
564     aop->size = FPTRSIZE; 
565 /*
566     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
567     sym->aop = aop = newAsmop(AOP_DPTR);
568     pic14_emitcode ("mov","dptr,#%s", sym->rname);
569     aop->size = getSize(sym->type);
570
571     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
572 */
573
574     /* if it is in code space */
575     if (IN_CODESPACE(space))
576         aop->code = 1;
577
578     return aop;     
579 }
580
581 /*-----------------------------------------------------------------*/
582 /* aopForRemat - rematerialzes an object                           */
583 /*-----------------------------------------------------------------*/
584 static asmop *aopForRemat (operand *op) // x symbol *sym)
585 {
586   symbol *sym = OP_SYMBOL(op);
587   iCode *ic = NULL;
588   asmop *aop = newAsmop(AOP_PCODE);
589   int val = 0;
590   int offset = 0;
591
592   ic = sym->rematiCode;
593
594   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
595   if(IS_OP_POINTER(op)) {
596     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
597   }
598   for (;;) {
599     if (ic->op == '+') {
600       val += (int) operandLitValue(IC_RIGHT(ic));
601     } else if (ic->op == '-') {
602       val -= (int) operandLitValue(IC_RIGHT(ic));
603     } else
604       break;
605         
606     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
607   }
608
609   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
610   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
611   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
612   PCOI(aop->aopu.pcop)->index = val;
613
614   DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
615                       OP_SYMBOL(IC_LEFT(ic))->rname,
616                       val, IS_PTR_CONST(operandType(op)));
617
618   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
619
620   allocDirReg (IC_LEFT(ic));
621
622   return aop;        
623 }
624
625 int aopIdx (asmop *aop, int offset)
626 {
627   if(!aop)
628     return -1;
629
630   if(aop->type !=  AOP_REG)
631     return -2;
632         
633   return aop->aopu.aop_reg[offset]->rIdx;
634
635 }
636 /*-----------------------------------------------------------------*/
637 /* regsInCommon - two operands have some registers in common       */
638 /*-----------------------------------------------------------------*/
639 static bool regsInCommon (operand *op1, operand *op2)
640 {
641     symbol *sym1, *sym2;
642     int i;
643
644     /* if they have registers in common */
645     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
646         return FALSE ;
647
648     sym1 = OP_SYMBOL(op1);
649     sym2 = OP_SYMBOL(op2);
650
651     if (sym1->nRegs == 0 || sym2->nRegs == 0)
652         return FALSE ;
653
654     for (i = 0 ; i < sym1->nRegs ; i++) {
655         int j;
656         if (!sym1->regs[i])
657             continue ;
658
659         for (j = 0 ; j < sym2->nRegs ;j++ ) {
660             if (!sym2->regs[j])
661                 continue ;
662
663             if (sym2->regs[j] == sym1->regs[i])
664                 return TRUE ;
665         }
666     }
667
668     return FALSE ;
669 }
670
671 /*-----------------------------------------------------------------*/
672 /* operandsEqu - equivalent                                        */
673 /*-----------------------------------------------------------------*/
674 static bool operandsEqu ( operand *op1, operand *op2)
675 {
676     symbol *sym1, *sym2;
677
678     /* if they not symbols */
679     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
680         return FALSE;
681
682     sym1 = OP_SYMBOL(op1);
683     sym2 = OP_SYMBOL(op2);
684
685     /* if both are itemps & one is spilt
686        and the other is not then false */
687     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
688         sym1->isspilt != sym2->isspilt )
689         return FALSE ;
690
691     /* if they are the same */
692     if (sym1 == sym2)
693         return TRUE ;
694
695     if (strcmp(sym1->rname,sym2->rname) == 0)
696         return TRUE;
697
698
699     /* if left is a tmp & right is not */
700     if (IS_ITEMP(op1)  && 
701         !IS_ITEMP(op2) &&
702         sym1->isspilt  &&
703         (sym1->usl.spillLoc == sym2))
704         return TRUE;
705
706     if (IS_ITEMP(op2)  && 
707         !IS_ITEMP(op1) &&
708         sym2->isspilt  &&
709         sym1->level > 0 &&
710         (sym2->usl.spillLoc == sym1))
711         return TRUE ;
712
713     return FALSE ;
714 }
715
716 /*-----------------------------------------------------------------*/
717 /* pic14_sameRegs - two asmops have the same registers                   */
718 /*-----------------------------------------------------------------*/
719 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
720 {
721     int i;
722
723     if (aop1 == aop2)
724         return TRUE ;
725
726     if (aop1->type != AOP_REG ||
727         aop2->type != AOP_REG )
728         return FALSE ;
729
730     if (aop1->size != aop2->size )
731         return FALSE ;
732
733     for (i = 0 ; i < aop1->size ; i++ )
734         if (aop1->aopu.aop_reg[i] !=
735             aop2->aopu.aop_reg[i] )
736             return FALSE ;
737
738     return TRUE ;
739 }
740
741 /*-----------------------------------------------------------------*/
742 /* aopOp - allocates an asmop for an operand  :                    */
743 /*-----------------------------------------------------------------*/
744 void aopOp (operand *op, iCode *ic, bool result)
745 {
746     asmop *aop;
747     symbol *sym;
748     int i;
749
750     if (!op)
751         return ;
752
753     //    DEBUGpic14_emitcode(";","%d",__LINE__);
754     /* if this a literal */
755     if (IS_OP_LITERAL(op)) {
756         op->aop = aop = newAsmop(AOP_LIT);
757         aop->aopu.aop_lit = op->operand.valOperand;
758         aop->size = getSize(operandType(op));
759         return;
760     }
761
762     {
763       sym_link *type = operandType(op);
764       if(IS_PTR_CONST(type))
765         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
766     }
767
768     /* if already has a asmop then continue */
769     if (op->aop)
770         return ;
771
772     /* if the underlying symbol has a aop */
773     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
774       DEBUGpic14_emitcode(";","%d",__LINE__);
775         op->aop = OP_SYMBOL(op)->aop;
776         return;
777     }
778
779     /* if this is a true symbol */
780     if (IS_TRUE_SYMOP(op)) {    
781       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
782       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
783       return ;
784     }
785
786     /* this is a temporary : this has
787     only four choices :
788     a) register
789     b) spillocation
790     c) rematerialize 
791     d) conditional   
792     e) can be a return use only */
793
794     sym = OP_SYMBOL(op);
795
796
797     /* if the type is a conditional */
798     if (sym->regType == REG_CND) {
799         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
800         aop->size = 0;
801         return;
802     }
803
804     /* if it is spilt then two situations
805     a) is rematerialize 
806     b) has a spill location */
807     if (sym->isspilt || sym->nRegs == 0) {
808
809       DEBUGpic14_emitcode(";","%d",__LINE__);
810         /* rematerialize it NOW */
811         if (sym->remat) {
812
813             sym->aop = op->aop = aop =
814                                       aopForRemat (op);
815             aop->size = getSize(sym->type);
816             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
817             return;
818         }
819
820         if (sym->accuse) {
821             int i;
822             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
823             aop->size = getSize(sym->type);
824             for ( i = 0 ; i < 2 ; i++ )
825                 aop->aopu.aop_str[i] = accUse[i];
826             DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
827             return;  
828         }
829
830         if (sym->ruonly ) {
831           /*
832           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
833           aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
834           //allocDirReg (IC_LEFT(ic));
835           aop->size = getSize(sym->type);
836           */
837
838           unsigned i;
839
840           aop = op->aop = sym->aop = newAsmop(AOP_STR);
841           aop->size = getSize(sym->type);
842           for ( i = 0 ; i < fReturnSizePic ; i++ )
843             aop->aopu.aop_str[i] = fReturn[i];
844
845           DEBUGpic14_emitcode(";","%d",__LINE__);
846           return;
847         }
848
849         /* else spill location  */
850         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
851             /* force a new aop if sizes differ */
852             sym->usl.spillLoc->aop = NULL;
853         }
854         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
855                             __FUNCTION__,__LINE__,
856                             sym->usl.spillLoc->rname,
857                             sym->rname, sym->usl.spillLoc->offset);
858
859         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
860         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
861         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
862                                           getSize(sym->type), 
863                                           sym->usl.spillLoc->offset);
864         aop->size = getSize(sym->type);
865
866         return;
867     }
868
869     {
870       sym_link *type = operandType(op);
871       if(IS_PTR_CONST(type)) 
872         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
873     }
874
875     /* must be in a register */
876     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
877     sym->aop = op->aop = aop = newAsmop(AOP_REG);
878     aop->size = sym->nRegs;
879     for ( i = 0 ; i < sym->nRegs ;i++)
880         aop->aopu.aop_reg[i] = sym->regs[i];
881 }
882
883 /*-----------------------------------------------------------------*/
884 /* freeAsmop - free up the asmop given to an operand               */
885 /*----------------------------------------------------------------*/
886 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
887 {   
888     asmop *aop ;
889
890     if (!op)
891         aop = aaop;
892     else 
893         aop = op->aop;
894
895     if (!aop)
896         return ;
897
898     if (aop->freed)
899         goto dealloc; 
900
901     aop->freed = 1;
902
903     /* depending on the asmop type only three cases need work AOP_RO
904        , AOP_R1 && AOP_STK */
905 #if 0
906     switch (aop->type) {
907         case AOP_R0 :
908             if (_G.r0Pushed ) {
909                 if (pop) {
910                     pic14_emitcode ("pop","ar0");     
911                     _G.r0Pushed--;
912                 }
913             }
914             bitVectUnSetBit(ic->rUsed,R0_IDX);
915             break;
916
917         case AOP_R1 :
918             if (_G.r1Pushed ) {
919                 if (pop) {
920                     pic14_emitcode ("pop","ar1");
921                     _G.r1Pushed--;
922                 }
923             }
924             bitVectUnSetBit(ic->rUsed,R1_IDX);          
925             break;
926
927         case AOP_STK :
928         {
929             int sz = aop->size;    
930             int stk = aop->aopu.aop_stk + aop->size;
931             bitVectUnSetBit(ic->rUsed,R0_IDX);
932             bitVectUnSetBit(ic->rUsed,R1_IDX);          
933
934             getFreePtr(ic,&aop,FALSE);
935             
936             if (options.stack10bit)
937             {
938                 /* I'm not sure what to do here yet... */
939                 /* #STUB */
940                 fprintf(stderr, 
941                         "*** Warning: probably generating bad code for "
942                         "10 bit stack mode.\n");
943             }
944             
945             if (stk) {
946                 pic14_emitcode ("mov","a,_bp");
947                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
948                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
949             } else {
950                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
951             }
952
953             while (sz--) {
954                 pic14_emitcode("pop","acc");
955                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
956                 if (!sz) break;
957                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
958             }
959             op->aop = aop;
960             freeAsmop(op,NULL,ic,TRUE);
961             if (_G.r0Pushed) {
962                 pic14_emitcode("pop","ar0");
963                 _G.r0Pushed--;
964             }
965
966             if (_G.r1Pushed) {
967                 pic14_emitcode("pop","ar1");
968                 _G.r1Pushed--;
969             }       
970         }
971     }
972 #endif
973
974 dealloc:
975     /* all other cases just dealloc */
976     if (op ) {
977         op->aop = NULL;
978         if (IS_SYMOP(op)) {
979             OP_SYMBOL(op)->aop = NULL;    
980             /* if the symbol has a spill */
981             if (SPIL_LOC(op))
982                 SPIL_LOC(op)->aop = NULL;
983         }
984     }
985 }
986
987 /*-----------------------------------------------------------------*/
988 /* aopGet - for fetching value of the aop                          */
989 /*-----------------------------------------------------------------*/
990 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
991 {
992     char *s = buffer ;
993     char *rs;
994
995     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
996     /* offset is greater than
997     size then zero */
998     if (offset > (aop->size - 1) &&
999         aop->type != AOP_LIT)
1000         return zero;
1001
1002     /* depending on type */
1003     switch (aop->type) {
1004         
1005     case AOP_R0:
1006     case AOP_R1:
1007         DEBUGpic14_emitcode(";","%d",__LINE__);
1008         /* if we need to increment it */       
1009         while (offset > aop->coff) {        
1010             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1011             aop->coff++;
1012         }
1013         
1014         while (offset < aop->coff) {
1015             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1016             aop->coff--;
1017         }
1018         
1019         aop->coff = offset ;
1020         if (aop->paged) {
1021             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1022             return (dname ? "acc" : "a");
1023         }       
1024         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1025         rs = Safe_calloc(1,strlen(s)+1);
1026         strcpy(rs,s);   
1027         return rs;
1028         
1029     case AOP_DPTR:
1030     case AOP_DPTR2:
1031         DEBUGpic14_emitcode(";","%d",__LINE__);
1032     if (aop->type == AOP_DPTR2)
1033     {
1034         genSetDPTR(1);
1035     }
1036     
1037         while (offset > aop->coff) {
1038             pic14_emitcode ("inc","dptr");
1039             aop->coff++;
1040         }
1041         
1042         while (offset < aop->coff) {        
1043             pic14_emitcode("lcall","__decdptr");
1044             aop->coff--;
1045         }
1046         
1047         aop->coff = offset;
1048         if (aop->code) {
1049             pic14_emitcode("clr","a");
1050             pic14_emitcode("movc","a,@a+dptr");
1051         }
1052     else {
1053             pic14_emitcode("movx","a,@dptr");
1054     }
1055             
1056     if (aop->type == AOP_DPTR2)
1057     {
1058         genSetDPTR(0);
1059     }
1060             
1061     return (dname ? "acc" : "a");
1062         
1063         
1064     case AOP_IMMD:
1065         if (bit16) 
1066             sprintf (s,"%s",aop->aopu.aop_immd);
1067         else
1068             if (offset) 
1069                 sprintf(s,"(%s >> %d)",
1070                         aop->aopu.aop_immd,
1071                         offset*8);
1072             else
1073                 sprintf(s,"%s",
1074                         aop->aopu.aop_immd);
1075         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1076         rs = Safe_calloc(1,strlen(s)+1);
1077         strcpy(rs,s);   
1078         return rs;
1079         
1080     case AOP_DIR:
1081       if (offset) {
1082         sprintf(s,"(%s + %d)",
1083                 aop->aopu.aop_dir,
1084                 offset);
1085         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1086       } else
1087             sprintf(s,"%s",aop->aopu.aop_dir);
1088         rs = Safe_calloc(1,strlen(s)+1);
1089         strcpy(rs,s);   
1090         return rs;
1091         
1092     case AOP_REG:
1093       //if (dname) 
1094       //    return aop->aopu.aop_reg[offset]->dname;
1095       //else
1096             return aop->aopu.aop_reg[offset]->name;
1097         
1098     case AOP_CRY:
1099       //pic14_emitcode(";","%d",__LINE__);
1100       return aop->aopu.aop_dir;
1101         
1102     case AOP_ACC:
1103         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1104         return "AOP_accumulator_bug";
1105
1106     case AOP_LIT:
1107         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1108         rs = Safe_calloc(1,strlen(s)+1);
1109         strcpy(rs,s);   
1110         return rs;
1111         
1112     case AOP_STR:
1113         DEBUGpic14_emitcode(";","%d",__LINE__);
1114         aop->coff = offset ;
1115         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1116             dname)
1117             return "acc";
1118         
1119         return aop->aopu.aop_str[offset];
1120         
1121     case AOP_PCODE:
1122       {
1123         pCodeOp *pcop = aop->aopu.pcop;
1124         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1125         if(pcop->name) {
1126           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1127           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1128           sprintf(s,"%s", pcop->name);
1129         } else
1130           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1131
1132       }
1133       rs = Safe_calloc(1,strlen(s)+1);
1134       strcpy(rs,s);   
1135       return rs;
1136
1137     }
1138
1139     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1140            "aopget got unsupported aop->type");
1141     exit(0);
1142 }
1143
1144
1145 /*-----------------------------------------------------------------*/
1146 /* popGetTempReg - create a new temporary pCodeOp                  */
1147 /*-----------------------------------------------------------------*/
1148 pCodeOp *popGetTempReg(void)
1149 {
1150
1151   pCodeOp *pcop;
1152
1153   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1154   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1155     PCOR(pcop)->r->wasUsed=1;
1156     PCOR(pcop)->r->isFree=0;
1157   }
1158
1159   return pcop;
1160 }
1161
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp                  */
1164 /*-----------------------------------------------------------------*/
1165 void popReleaseTempReg(pCodeOp *pcop)
1166 {
1167
1168   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1169     PCOR(pcop)->r->isFree = 1;
1170
1171 }
1172 /*-----------------------------------------------------------------*/
1173 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1174 /*-----------------------------------------------------------------*/
1175 pCodeOp *popGetLabel(unsigned int key)
1176 {
1177
1178   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1179
1180   if(key>max_key)
1181     max_key = key;
1182
1183   return newpCodeOpLabel(NULL,key+100+labelOffset);
1184 }
1185
1186 /*-----------------------------------------------------------------*/
1187 /* popCopyReg - copy a pcode operator                              */
1188 /*-----------------------------------------------------------------*/
1189 pCodeOp *popCopyReg(pCodeOpReg *pc)
1190 {
1191   pCodeOpReg *pcor;
1192
1193   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1194   pcor->pcop.type = pc->pcop.type;
1195   if(pc->pcop.name) {
1196     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1197       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1198   } else
1199     pcor->pcop.name = NULL;
1200
1201   pcor->r = pc->r;
1202   pcor->rIdx = pc->rIdx;
1203   pcor->r->wasUsed=1;
1204
1205   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1206
1207   return PCOP(pcor);
1208 }
1209 /*-----------------------------------------------------------------*/
1210 /* popGet - asm operator to pcode operator conversion              */
1211 /*-----------------------------------------------------------------*/
1212 pCodeOp *popGetLit(unsigned int lit)
1213 {
1214
1215   return newpCodeOpLit(lit);
1216 }
1217
1218
1219 /*-----------------------------------------------------------------*/
1220 /* popGetImmd - asm operator to pcode immediate conversion         */
1221 /*-----------------------------------------------------------------*/
1222 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1223 {
1224
1225   return newpCodeOpImmd(name, offset,index, 0);
1226 }
1227
1228
1229 /*-----------------------------------------------------------------*/
1230 /* popGet - asm operator to pcode operator conversion              */
1231 /*-----------------------------------------------------------------*/
1232 pCodeOp *popGetWithString(char *str)
1233 {
1234   pCodeOp *pcop;
1235
1236
1237   if(!str) {
1238     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1239     exit (1);
1240   }
1241
1242   pcop = newpCodeOp(str,PO_STR);
1243
1244   return pcop;
1245 }
1246
1247 /*-----------------------------------------------------------------*/
1248 /* popRegFromString -                                              */
1249 /*-----------------------------------------------------------------*/
1250 pCodeOp *popRegFromString(char *str, int size, int offset)
1251 {
1252
1253   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1254   pcop->type = PO_DIR;
1255
1256   DEBUGpic14_emitcode(";","%d",__LINE__);
1257
1258   if(!str)
1259     str = "BAD_STRING";
1260
1261   pcop->name = Safe_calloc(1,strlen(str)+1);
1262   strcpy(pcop->name,str);
1263
1264   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1265
1266   PCOR(pcop)->r = dirregWithName(pcop->name);
1267   if(PCOR(pcop)->r == NULL) {
1268     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1269     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1270     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1271   } else {
1272     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1273   }
1274   PCOR(pcop)->instance = offset;
1275
1276   return pcop;
1277 }
1278
1279 pCodeOp *popRegFromIdx(int rIdx)
1280 {
1281   pCodeOp *pcop;
1282
1283   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1284                        __FUNCTION__,__LINE__,rIdx);
1285
1286   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1287
1288   PCOR(pcop)->rIdx = rIdx;
1289   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1290   PCOR(pcop)->r->isFree = 0;
1291   PCOR(pcop)->r->wasUsed = 1;
1292
1293   pcop->type = PCOR(pcop)->r->pc_type;
1294
1295
1296   return pcop;
1297 }
1298 /*-----------------------------------------------------------------*/
1299 /* popGet - asm operator to pcode operator conversion              */
1300 /*-----------------------------------------------------------------*/
1301 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1302 {
1303   //char *s = buffer ;
1304     //char *rs;
1305
1306     pCodeOp *pcop;
1307
1308     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1309     /* offset is greater than
1310     size then zero */
1311
1312     if (offset > (aop->size - 1) &&
1313         aop->type != AOP_LIT)
1314       return NULL;  //zero;
1315
1316     /* depending on type */
1317     switch (aop->type) {
1318         
1319     case AOP_R0:
1320     case AOP_R1:
1321     case AOP_DPTR:
1322     case AOP_DPTR2:
1323     case AOP_ACC:
1324         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1325         return NULL;
1326         
1327     case AOP_IMMD:
1328       DEBUGpic14_emitcode(";","%d",__LINE__);
1329       return popGetImmd(aop->aopu.aop_immd,offset,0);
1330
1331     case AOP_DIR:
1332       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1333 #if 0
1334         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1335         pcop->type = PO_DIR;
1336
1337         /*
1338         if (offset)
1339             sprintf(s,"(%s + %d)",
1340                     aop->aopu.aop_dir,
1341                     offset);
1342         else
1343             sprintf(s,"%s",aop->aopu.aop_dir);
1344         pcop->name = Safe_calloc(1,strlen(s)+1);
1345         strcpy(pcop->name,s);   
1346         */
1347         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1348         strcpy(pcop->name,aop->aopu.aop_dir);   
1349         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1350         if(PCOR(pcop)->r == NULL) {
1351           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1352           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1353           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1354         } else {
1355           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1356         }
1357         PCOR(pcop)->instance = offset;
1358
1359         return pcop;
1360 #endif
1361         
1362     case AOP_REG:
1363       {
1364         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1365
1366         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1367         PCOR(pcop)->rIdx = rIdx;
1368         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1369         PCOR(pcop)->r->wasUsed=1;
1370         PCOR(pcop)->r->isFree=0;
1371
1372         PCOR(pcop)->instance = offset;
1373         pcop->type = PCOR(pcop)->r->pc_type;
1374         //rs = aop->aopu.aop_reg[offset]->name;
1375         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1376         return pcop;
1377       }
1378
1379     case AOP_CRY:
1380       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1381       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1382       //if(PCOR(pcop)->r == NULL)
1383       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1384       return pcop;
1385         
1386     case AOP_LIT:
1387       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1388
1389     case AOP_STR:
1390       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1391       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1392       /*
1393       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1394       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1395       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1396       pcop->type = PCOR(pcop)->r->pc_type;
1397       pcop->name = PCOR(pcop)->r->name;
1398
1399       return pcop;
1400       */
1401
1402     case AOP_PCODE:
1403       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1404                           __LINE__, 
1405                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1406       pcop = pCodeOpCopy(aop->aopu.pcop);
1407       PCOI(pcop)->offset = offset;
1408       return pcop;
1409     }
1410
1411     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1412            "popGet got unsupported aop->type");
1413     exit(0);
1414 }
1415 /*-----------------------------------------------------------------*/
1416 /* aopPut - puts a string for a aop                                */
1417 /*-----------------------------------------------------------------*/
1418 void aopPut (asmop *aop, char *s, int offset)
1419 {
1420     char *d = buffer ;
1421     symbol *lbl ;
1422
1423     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1424
1425     if (aop->size && offset > ( aop->size - 1)) {
1426         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1427                "aopPut got offset > aop->size");
1428         exit(0);
1429     }
1430
1431     /* will assign value to value */
1432     /* depending on where it is ofcourse */
1433     switch (aop->type) {
1434     case AOP_DIR:
1435       if (offset) {
1436         sprintf(d,"(%s + %d)",
1437                 aop->aopu.aop_dir,offset);
1438         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1439
1440       } else
1441             sprintf(d,"%s",aop->aopu.aop_dir);
1442         
1443         if (strcmp(d,s)) {
1444           DEBUGpic14_emitcode(";","%d",__LINE__);
1445           if(strcmp(s,"W"))
1446             pic14_emitcode("movf","%s,w",s);
1447           pic14_emitcode("movwf","%s",d);
1448
1449           if(strcmp(s,"W")) {
1450             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1451             if(offset >= aop->size) {
1452               emitpcode(POC_CLRF,popGet(aop,offset));
1453               break;
1454             } else
1455               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1456           }
1457
1458           emitpcode(POC_MOVWF,popGet(aop,offset));
1459
1460
1461         }
1462         break;
1463         
1464     case AOP_REG:
1465       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1466         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1467           /*
1468             if (*s == '@'           ||
1469                 strcmp(s,"r0") == 0 ||
1470                 strcmp(s,"r1") == 0 ||
1471                 strcmp(s,"r2") == 0 ||
1472                 strcmp(s,"r3") == 0 ||
1473                 strcmp(s,"r4") == 0 ||
1474                 strcmp(s,"r5") == 0 ||
1475                 strcmp(s,"r6") == 0 || 
1476                 strcmp(s,"r7") == 0 )
1477                 pic14_emitcode("mov","%s,%s  ; %d",
1478                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1479             else
1480           */
1481
1482           if(strcmp(s,"W")==0 )
1483             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1484
1485           pic14_emitcode("movwf","%s",
1486                    aop->aopu.aop_reg[offset]->name);
1487
1488           if(strcmp(s,zero)==0) {
1489             emitpcode(POC_CLRF,popGet(aop,offset));
1490
1491           } else if(strcmp(s,"W")==0) {
1492             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1493             pcop->type = PO_GPR_REGISTER;
1494
1495             PCOR(pcop)->rIdx = -1;
1496             PCOR(pcop)->r = NULL;
1497
1498             DEBUGpic14_emitcode(";","%d",__LINE__);
1499             pcop->name = Safe_strdup(s);
1500             emitpcode(POC_MOVFW,pcop);
1501             emitpcode(POC_MOVWF,popGet(aop,offset));
1502           } else if(strcmp(s,one)==0) {
1503             emitpcode(POC_CLRF,popGet(aop,offset));
1504             emitpcode(POC_INCF,popGet(aop,offset));
1505           } else {
1506             emitpcode(POC_MOVWF,popGet(aop,offset));
1507           }
1508         }
1509         break;
1510         
1511     case AOP_DPTR:
1512     case AOP_DPTR2:
1513     
1514     if (aop->type == AOP_DPTR2)
1515     {
1516         genSetDPTR(1);
1517     }
1518     
1519         if (aop->code) {
1520             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1521                    "aopPut writting to code space");
1522             exit(0);
1523         }
1524         
1525         while (offset > aop->coff) {
1526             aop->coff++;
1527             pic14_emitcode ("inc","dptr");
1528         }
1529         
1530         while (offset < aop->coff) {
1531             aop->coff-- ;
1532             pic14_emitcode("lcall","__decdptr");
1533         }
1534         
1535         aop->coff = offset;
1536         
1537         /* if not in accumulater */
1538         MOVA(s);        
1539         
1540         pic14_emitcode ("movx","@dptr,a");
1541         
1542     if (aop->type == AOP_DPTR2)
1543     {
1544         genSetDPTR(0);
1545     }
1546         break;
1547         
1548     case AOP_R0:
1549     case AOP_R1:
1550         while (offset > aop->coff) {
1551             aop->coff++;
1552             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1553         }
1554         while (offset < aop->coff) {
1555             aop->coff-- ;
1556             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1557         }
1558         aop->coff = offset;
1559         
1560         if (aop->paged) {
1561             MOVA(s);           
1562             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1563             
1564         } else
1565             if (*s == '@') {
1566                 MOVA(s);
1567                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1568             } else
1569                 if (strcmp(s,"r0") == 0 ||
1570                     strcmp(s,"r1") == 0 ||
1571                     strcmp(s,"r2") == 0 ||
1572                     strcmp(s,"r3") == 0 ||
1573                     strcmp(s,"r4") == 0 ||
1574                     strcmp(s,"r5") == 0 ||
1575                     strcmp(s,"r6") == 0 || 
1576                     strcmp(s,"r7") == 0 ) {
1577                     char buffer[10];
1578                     sprintf(buffer,"a%s",s);
1579                     pic14_emitcode("mov","@%s,%s",
1580                              aop->aopu.aop_ptr->name,buffer);
1581                 } else
1582                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1583         
1584         break;
1585         
1586     case AOP_STK:
1587         if (strcmp(s,"a") == 0)
1588             pic14_emitcode("push","acc");
1589         else
1590             pic14_emitcode("push","%s",s);
1591         
1592         break;
1593         
1594     case AOP_CRY:
1595         /* if bit variable */
1596         if (!aop->aopu.aop_dir) {
1597             pic14_emitcode("clr","a");
1598             pic14_emitcode("rlc","a");
1599         } else {
1600             if (s == zero) 
1601                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1602             else
1603                 if (s == one)
1604                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1605                 else
1606                     if (!strcmp(s,"c"))
1607                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1608                     else {
1609                         lbl = newiTempLabel(NULL);
1610                         
1611                         if (strcmp(s,"a")) {
1612                             MOVA(s);
1613                         }
1614                         pic14_emitcode("clr","c");
1615                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1616                         pic14_emitcode("cpl","c");
1617                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1618                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1619                     }
1620         }
1621         break;
1622         
1623     case AOP_STR:
1624         aop->coff = offset;
1625         if (strcmp(aop->aopu.aop_str[offset],s))
1626             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1627         break;
1628         
1629     case AOP_ACC:
1630         aop->coff = offset;
1631         if (!offset && (strcmp(s,"acc") == 0))
1632             break;
1633         
1634         if (strcmp(aop->aopu.aop_str[offset],s))
1635             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1636         break;
1637
1638     default :
1639         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1640                "aopPut got unsupported aop->type");
1641         exit(0);    
1642     }    
1643
1644 }
1645
1646 /*-----------------------------------------------------------------*/
1647 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1648 /*-----------------------------------------------------------------*/
1649 void mov2w (asmop *aop, int offset)
1650 {
1651
1652   if(!aop)
1653     return;
1654
1655   if ( aop->type == AOP_PCODE ||
1656        aop->type == AOP_LIT )
1657     emitpcode(POC_MOVLW,popGet(aop,offset));
1658   else
1659     emitpcode(POC_MOVFW,popGet(aop,offset));
1660
1661 }
1662
1663 /*-----------------------------------------------------------------*/
1664 /* reAdjustPreg - points a register back to where it should        */
1665 /*-----------------------------------------------------------------*/
1666 static void reAdjustPreg (asmop *aop)
1667 {
1668     int size ;
1669
1670     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1671     aop->coff = 0;
1672     if ((size = aop->size) <= 1)
1673         return ;
1674     size-- ;
1675     switch (aop->type) {
1676         case AOP_R0 :
1677         case AOP_R1 :
1678             while (size--)
1679                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1680             break;          
1681         case AOP_DPTR :
1682         case AOP_DPTR2:
1683             if (aop->type == AOP_DPTR2)
1684             {
1685                 genSetDPTR(1);
1686             } 
1687             while (size--)
1688             {
1689                 pic14_emitcode("lcall","__decdptr");
1690             }
1691                 
1692             if (aop->type == AOP_DPTR2)
1693             {
1694                 genSetDPTR(0);
1695             }                
1696             break;  
1697
1698     }   
1699
1700 }
1701
1702 /*-----------------------------------------------------------------*/
1703 /* genNotFloat - generates not for float operations              */
1704 /*-----------------------------------------------------------------*/
1705 static void genNotFloat (operand *op, operand *res)
1706 {
1707     int size, offset;
1708     char *l;
1709     symbol *tlbl ;
1710
1711     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1712     /* we will put 127 in the first byte of 
1713     the result */
1714     aopPut(AOP(res),"#127",0);
1715     size = AOP_SIZE(op) - 1;
1716     offset = 1;
1717
1718     l = aopGet(op->aop,offset++,FALSE,FALSE);
1719     MOVA(l);    
1720
1721     while(size--) {
1722         pic14_emitcode("orl","a,%s",
1723                  aopGet(op->aop,
1724                         offset++,FALSE,FALSE));
1725     }
1726     tlbl = newiTempLabel(NULL);
1727
1728     tlbl = newiTempLabel(NULL);
1729     aopPut(res->aop,one,1);
1730     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1731     aopPut(res->aop,zero,1);
1732     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1733
1734     size = res->aop->size - 2;
1735     offset = 2;    
1736     /* put zeros in the rest */
1737     while (size--) 
1738         aopPut(res->aop,zero,offset++);
1739 }
1740
1741 #if 0
1742 /*-----------------------------------------------------------------*/
1743 /* opIsGptr: returns non-zero if the passed operand is             */   
1744 /* a generic pointer type.                                         */
1745 /*-----------------------------------------------------------------*/ 
1746 static int opIsGptr(operand *op)
1747 {
1748     sym_link *type = operandType(op);
1749     
1750     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1751     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1752     {
1753         return 1;
1754     }
1755     return 0;        
1756 }
1757 #endif
1758
1759 /*-----------------------------------------------------------------*/
1760 /* pic14_getDataSize - get the operand data size                         */
1761 /*-----------------------------------------------------------------*/
1762 int pic14_getDataSize(operand *op)
1763 {
1764     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1765
1766
1767     return AOP_SIZE(op);
1768
1769     // tsd- in the pic port, the genptr size is 1, so this code here
1770     // fails. ( in the 8051 port, the size was 4).
1771 #if 0
1772     int size;
1773     size = AOP_SIZE(op);
1774     if (size == GPTRSIZE)
1775     {
1776         sym_link *type = operandType(op);
1777         if (IS_GENPTR(type))
1778         {
1779             /* generic pointer; arithmetic operations
1780              * should ignore the high byte (pointer type).
1781              */
1782             size--;
1783     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1784         }
1785     }
1786     return size;
1787 #endif
1788 }
1789
1790 /*-----------------------------------------------------------------*/
1791 /* pic14_outAcc - output Acc                                             */
1792 /*-----------------------------------------------------------------*/
1793 void pic14_outAcc(operand *result)
1794 {
1795   int size,offset;
1796   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1797   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1798
1799
1800   size = pic14_getDataSize(result);
1801   if(size){
1802     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1803     size--;
1804     offset = 1;
1805     /* unsigned or positive */
1806     while(size--)
1807       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1808   }
1809
1810 }
1811
1812 /*-----------------------------------------------------------------*/
1813 /* pic14_outBitC - output a bit C                                        */
1814 /*-----------------------------------------------------------------*/
1815 void pic14_outBitC(operand *result)
1816 {
1817
1818     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1819     /* if the result is bit */
1820     if (AOP_TYPE(result) == AOP_CRY) 
1821         aopPut(AOP(result),"c",0);
1822     else {
1823         pic14_emitcode("clr","a  ; %d", __LINE__);
1824         pic14_emitcode("rlc","a");
1825         pic14_outAcc(result);
1826     }
1827 }
1828
1829 /*-----------------------------------------------------------------*/
1830 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1831 /*-----------------------------------------------------------------*/
1832 void pic14_toBoolean(operand *oper)
1833 {
1834     int size = AOP_SIZE(oper) - 1;
1835     int offset = 1;
1836
1837     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1838
1839     if ( AOP_TYPE(oper) != AOP_ACC) {
1840       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1841     }
1842     while (size--) {
1843       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1844     }
1845 }
1846
1847
1848 /*-----------------------------------------------------------------*/
1849 /* genNot - generate code for ! operation                          */
1850 /*-----------------------------------------------------------------*/
1851 static void genNot (iCode *ic)
1852 {
1853   symbol *tlbl;
1854   sym_link *optype = operandType(IC_LEFT(ic));
1855   int size;
1856
1857   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1858   /* assign asmOps to operand & result */
1859   aopOp (IC_LEFT(ic),ic,FALSE);
1860   aopOp (IC_RESULT(ic),ic,TRUE);
1861
1862   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1863   /* if in bit space then a special case */
1864   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1865     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1866       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1867       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1868     } else {
1869       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1870       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1871       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1872     }
1873     goto release;
1874   }
1875
1876   /* if type float then do float */
1877   if (IS_FLOAT(optype)) {
1878     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1879     goto release;
1880   }
1881
1882   size = AOP_SIZE(IC_RESULT(ic));
1883   if(size == 1) {
1884     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1885     emitpcode(POC_ANDLW,popGetLit(1));
1886     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1887     goto release;
1888   }
1889   pic14_toBoolean(IC_LEFT(ic));
1890
1891   tlbl = newiTempLabel(NULL);
1892   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1893   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1894   pic14_outBitC(IC_RESULT(ic));
1895
1896  release:    
1897   /* release the aops */
1898   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1900 }
1901
1902
1903 /*-----------------------------------------------------------------*/
1904 /* genCpl - generate code for complement                           */
1905 /*-----------------------------------------------------------------*/
1906 static void genCpl (iCode *ic)
1907 {
1908     int offset = 0;
1909     int size ;
1910
1911
1912     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1913     /* assign asmOps to operand & result */
1914     aopOp (IC_LEFT(ic),ic,FALSE);
1915     aopOp (IC_RESULT(ic),ic,TRUE);
1916
1917     /* if both are in bit space then 
1918     a special case */
1919     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1920         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1921
1922         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1923         pic14_emitcode("cpl","c"); 
1924         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1925         goto release; 
1926     } 
1927
1928     size = AOP_SIZE(IC_RESULT(ic));
1929     while (size--) {
1930         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1931         MOVA(l);       
1932         pic14_emitcode("cpl","a");
1933         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1934     }
1935
1936
1937 release:
1938     /* release the aops */
1939     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1940     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1941 }
1942
1943 /*-----------------------------------------------------------------*/
1944 /* genUminusFloat - unary minus for floating points                */
1945 /*-----------------------------------------------------------------*/
1946 static void genUminusFloat(operand *op,operand *result)
1947 {
1948     int size ,offset =0 ;
1949     char *l;
1950
1951     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1952     /* for this we just need to flip the 
1953     first it then copy the rest in place */
1954     size = AOP_SIZE(op) - 1;
1955     l = aopGet(AOP(op),3,FALSE,FALSE);
1956
1957     MOVA(l);    
1958
1959     pic14_emitcode("cpl","acc.7");
1960     aopPut(AOP(result),"a",3);    
1961
1962     while(size--) {
1963         aopPut(AOP(result),
1964                aopGet(AOP(op),offset,FALSE,FALSE),
1965                offset);
1966         offset++;
1967     }          
1968 }
1969
1970 /*-----------------------------------------------------------------*/
1971 /* genUminus - unary minus code generation                         */
1972 /*-----------------------------------------------------------------*/
1973 static void genUminus (iCode *ic)
1974 {
1975   int size, i;
1976   sym_link *optype, *rtype;
1977
1978
1979   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1980   /* assign asmops */
1981   aopOp(IC_LEFT(ic),ic,FALSE);
1982   aopOp(IC_RESULT(ic),ic,TRUE);
1983
1984   /* if both in bit space then special
1985      case */
1986   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1987       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1988
1989     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1990     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1991     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1992
1993     goto release; 
1994   } 
1995
1996   optype = operandType(IC_LEFT(ic));
1997   rtype = operandType(IC_RESULT(ic));
1998
1999   /* if float then do float stuff */
2000   if (IS_FLOAT(optype)) {
2001     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2002     goto release;
2003   }
2004
2005   /* otherwise subtract from zero by taking the 2's complement */
2006   size = AOP_SIZE(IC_LEFT(ic));
2007
2008   for(i=0; i<size; i++) {
2009     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2010       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2011     else {
2012       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2013       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2014     }
2015   }
2016
2017   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2018   for(i=1; i<size; i++) {
2019     emitSKPNZ;
2020     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2021   }
2022
2023  release:
2024   /* release the aops */
2025   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2026   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2027 }
2028
2029 /*-----------------------------------------------------------------*/
2030 /* saveRegisters - will look for a call and save the registers     */
2031 /*-----------------------------------------------------------------*/
2032 static void saveRegisters(iCode *lic) 
2033 {
2034     int i;
2035     iCode *ic;
2036     bitVect *rsave;
2037     sym_link *dtype;
2038
2039     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2040     /* look for call */
2041     for (ic = lic ; ic ; ic = ic->next) 
2042         if (ic->op == CALL || ic->op == PCALL)
2043             break;
2044
2045     if (!ic) {
2046         fprintf(stderr,"found parameter push with no function call\n");
2047         return ;
2048     }
2049
2050     /* if the registers have been saved already then
2051     do nothing */
2052     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2053         return ;
2054
2055     /* find the registers in use at this time 
2056     and push them away to safety */
2057     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2058                           ic->rUsed);
2059
2060     ic->regsSaved = 1;
2061     if (options.useXstack) {
2062         if (bitVectBitValue(rsave,R0_IDX))
2063             pic14_emitcode("mov","b,r0");
2064         pic14_emitcode("mov","r0,%s",spname);
2065         for (i = 0 ; i < pic14_nRegs ; i++) {
2066             if (bitVectBitValue(rsave,i)) {
2067                 if (i == R0_IDX)
2068                     pic14_emitcode("mov","a,b");
2069                 else
2070                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2071                 pic14_emitcode("movx","@r0,a");
2072                 pic14_emitcode("inc","r0");
2073             }
2074         }
2075         pic14_emitcode("mov","%s,r0",spname);
2076         if (bitVectBitValue(rsave,R0_IDX))
2077             pic14_emitcode("mov","r0,b");           
2078     }// else
2079     //for (i = 0 ; i < pic14_nRegs ; i++) {
2080     //    if (bitVectBitValue(rsave,i))
2081     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2082     //}
2083
2084     dtype = operandType(IC_LEFT(ic));
2085     if (currFunc && dtype && 
2086         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2087         IFFUNC_ISISR(currFunc->type) &&
2088         !ic->bankSaved) 
2089
2090         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2091
2092 }
2093 /*-----------------------------------------------------------------*/
2094 /* unsaveRegisters - pop the pushed registers                      */
2095 /*-----------------------------------------------------------------*/
2096 static void unsaveRegisters (iCode *ic)
2097 {
2098     int i;
2099     bitVect *rsave;
2100
2101     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2102     /* find the registers in use at this time 
2103     and push them away to safety */
2104     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2105                           ic->rUsed);
2106     
2107     if (options.useXstack) {
2108         pic14_emitcode("mov","r0,%s",spname);   
2109         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2110             if (bitVectBitValue(rsave,i)) {
2111                 pic14_emitcode("dec","r0");
2112                 pic14_emitcode("movx","a,@r0");
2113                 if (i == R0_IDX)
2114                     pic14_emitcode("mov","b,a");
2115                 else
2116                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2117             }       
2118
2119         }
2120         pic14_emitcode("mov","%s,r0",spname);
2121         if (bitVectBitValue(rsave,R0_IDX))
2122             pic14_emitcode("mov","r0,b");
2123     } //else
2124     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2125     //    if (bitVectBitValue(rsave,i))
2126     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2127     //}
2128
2129 }  
2130
2131
2132 /*-----------------------------------------------------------------*/
2133 /* pushSide -                                                      */
2134 /*-----------------------------------------------------------------*/
2135 static void pushSide(operand * oper, int size)
2136 {
2137 #if 0
2138         int offset = 0;
2139     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2140         while (size--) {
2141                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2142                 if (AOP_TYPE(oper) != AOP_REG &&
2143                     AOP_TYPE(oper) != AOP_DIR &&
2144                     strcmp(l,"a") ) {
2145                         pic14_emitcode("mov","a,%s",l);
2146                         pic14_emitcode("push","acc");
2147                 } else
2148                         pic14_emitcode("push","%s",l);
2149         }
2150 #endif
2151 }
2152
2153 /*-----------------------------------------------------------------*/
2154 /* assignResultValue -                                             */
2155 /*-----------------------------------------------------------------*/
2156 static void assignResultValue(operand * oper)
2157 {
2158   int size = AOP_SIZE(oper);
2159
2160   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2161
2162   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2163
2164   if(!GpsuedoStkPtr) {
2165     /* The last byte in the assignment is in W */
2166     size--;
2167     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2168     GpsuedoStkPtr++;
2169   }
2170
2171   while (size--) {
2172     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2173     GpsuedoStkPtr++;
2174     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2175   }
2176 }
2177
2178
2179 /*-----------------------------------------------------------------*/
2180 /* genIpush - genrate code for pushing this gets a little complex  */
2181 /*-----------------------------------------------------------------*/
2182 static void genIpush (iCode *ic)
2183 {
2184
2185   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2186 #if 0
2187     int size, offset = 0 ;
2188     char *l;
2189
2190
2191     /* if this is not a parm push : ie. it is spill push 
2192     and spill push is always done on the local stack */
2193     if (!ic->parmPush) {
2194
2195         /* and the item is spilt then do nothing */
2196         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2197             return ;
2198
2199         aopOp(IC_LEFT(ic),ic,FALSE);
2200         size = AOP_SIZE(IC_LEFT(ic));
2201         /* push it on the stack */
2202         while(size--) {
2203             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2204             if (*l == '#') {
2205                 MOVA(l);
2206                 l = "acc";
2207             }
2208             pic14_emitcode("push","%s",l);
2209         }
2210         return ;        
2211     }
2212
2213     /* this is a paramter push: in this case we call
2214     the routine to find the call and save those
2215     registers that need to be saved */   
2216     saveRegisters(ic);
2217
2218     /* then do the push */
2219     aopOp(IC_LEFT(ic),ic,FALSE);
2220
2221
2222         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2223     size = AOP_SIZE(IC_LEFT(ic));
2224
2225     while (size--) {
2226         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2227         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2228             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2229             strcmp(l,"a") ) {
2230             pic14_emitcode("mov","a,%s",l);
2231             pic14_emitcode("push","acc");
2232         } else
2233             pic14_emitcode("push","%s",l);
2234     }       
2235
2236     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2237 #endif
2238 }
2239
2240 /*-----------------------------------------------------------------*/
2241 /* genIpop - recover the registers: can happen only for spilling   */
2242 /*-----------------------------------------------------------------*/
2243 static void genIpop (iCode *ic)
2244 {
2245   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2246 #if 0
2247     int size,offset ;
2248
2249
2250     /* if the temp was not pushed then */
2251     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2252         return ;
2253
2254     aopOp(IC_LEFT(ic),ic,FALSE);
2255     size = AOP_SIZE(IC_LEFT(ic));
2256     offset = (size-1);
2257     while (size--) 
2258         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2259                                    FALSE,TRUE));
2260
2261     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2262 #endif
2263 }
2264
2265 /*-----------------------------------------------------------------*/
2266 /* unsaverbank - restores the resgister bank from stack            */
2267 /*-----------------------------------------------------------------*/
2268 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2269 {
2270   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2271 #if 0
2272     int i;
2273     asmop *aop ;
2274     regs *r = NULL;
2275
2276     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2277     if (popPsw) {
2278         if (options.useXstack) {
2279             aop = newAsmop(0);
2280             r = getFreePtr(ic,&aop,FALSE);
2281             
2282             
2283             pic14_emitcode("mov","%s,_spx",r->name);
2284             pic14_emitcode("movx","a,@%s",r->name);
2285             pic14_emitcode("mov","psw,a");
2286             pic14_emitcode("dec","%s",r->name);
2287             
2288         }else
2289             pic14_emitcode ("pop","psw");
2290     }
2291
2292     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2293         if (options.useXstack) {       
2294             pic14_emitcode("movx","a,@%s",r->name);
2295             //pic14_emitcode("mov","(%s+%d),a",
2296             //       regspic14[i].base,8*bank+regspic14[i].offset);
2297             pic14_emitcode("dec","%s",r->name);
2298
2299         } else 
2300           pic14_emitcode("pop",""); //"(%s+%d)",
2301         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2302     }
2303
2304     if (options.useXstack) {
2305
2306         pic14_emitcode("mov","_spx,%s",r->name);
2307         freeAsmop(NULL,aop,ic,TRUE);
2308
2309     }
2310 #endif 
2311 }
2312
2313 /*-----------------------------------------------------------------*/
2314 /* saverbank - saves an entire register bank on the stack          */
2315 /*-----------------------------------------------------------------*/
2316 static void saverbank (int bank, iCode *ic, bool pushPsw)
2317 {
2318   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2319 #if 0
2320     int i;
2321     asmop *aop ;
2322     regs *r = NULL;
2323
2324     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2325     if (options.useXstack) {
2326
2327         aop = newAsmop(0);
2328         r = getFreePtr(ic,&aop,FALSE);  
2329         pic14_emitcode("mov","%s,_spx",r->name);
2330
2331     }
2332
2333     for (i = 0 ; i < pic14_nRegs ;i++) {
2334         if (options.useXstack) {
2335             pic14_emitcode("inc","%s",r->name);
2336             //pic14_emitcode("mov","a,(%s+%d)",
2337             //         regspic14[i].base,8*bank+regspic14[i].offset);
2338             pic14_emitcode("movx","@%s,a",r->name);           
2339         } else 
2340           pic14_emitcode("push","");// "(%s+%d)",
2341                      //regspic14[i].base,8*bank+regspic14[i].offset);
2342     }
2343     
2344     if (pushPsw) {
2345         if (options.useXstack) {
2346             pic14_emitcode("mov","a,psw");
2347             pic14_emitcode("movx","@%s,a",r->name);     
2348             pic14_emitcode("inc","%s",r->name);
2349             pic14_emitcode("mov","_spx,%s",r->name);       
2350             freeAsmop (NULL,aop,ic,TRUE);
2351             
2352         } else
2353             pic14_emitcode("push","psw");
2354         
2355         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2356     }
2357     ic->bankSaved = 1;
2358 #endif
2359 }
2360
2361 /*-----------------------------------------------------------------*/
2362 /* genCall - generates a call statement                            */
2363 /*-----------------------------------------------------------------*/
2364 static void genCall (iCode *ic)
2365 {
2366   sym_link *dtype;   
2367
2368   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2369
2370   /* if caller saves & we have not saved then */
2371   if (!ic->regsSaved)
2372     saveRegisters(ic);
2373
2374   /* if we are calling a function that is not using
2375      the same register bank then we need to save the
2376      destination registers on the stack */
2377   dtype = operandType(IC_LEFT(ic));
2378   if (currFunc && dtype && 
2379       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2380       IFFUNC_ISISR(currFunc->type) &&
2381       !ic->bankSaved) 
2382
2383     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2384
2385   /* if send set is not empty the assign */
2386   if (_G.sendSet) {
2387     iCode *sic;
2388     /* For the Pic port, there is no data stack.
2389      * So parameters passed to functions are stored
2390      * in registers. (The pCode optimizer will get
2391      * rid of most of these :).
2392      */
2393     int psuedoStkPtr=-1; 
2394     int firstTimeThruLoop = 1;
2395
2396     _G.sendSet = reverseSet(_G.sendSet);
2397
2398     /* First figure how many parameters are getting passed */
2399     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2400          sic = setNextItem(_G.sendSet)) {
2401
2402       aopOp(IC_LEFT(sic),sic,FALSE);
2403       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2404       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2405     }
2406
2407     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2408          sic = setNextItem(_G.sendSet)) {
2409       int size, offset = 0;
2410
2411       aopOp(IC_LEFT(sic),sic,FALSE);
2412       size = AOP_SIZE(IC_LEFT(sic));
2413
2414       while (size--) {
2415         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2416                              AopType(AOP_TYPE(IC_LEFT(sic))));
2417
2418         if(!firstTimeThruLoop) {
2419           /* If this is not the first time we've been through the loop
2420            * then we need to save the parameter in a temporary
2421            * register. The last byte of the last parameter is
2422            * passed in W. */
2423           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2424
2425         }
2426         firstTimeThruLoop=0;
2427
2428         //if (strcmp(l,fReturn[offset])) {
2429         mov2w (AOP(IC_LEFT(sic)),  offset);
2430 /*
2431         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2432              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2433           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2434         else
2435           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2436 */
2437         //}
2438         offset++;
2439       }
2440       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2441     }
2442     _G.sendSet = NULL;
2443   }
2444   /* make the call */
2445   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2446                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2447                                       OP_SYMBOL(IC_LEFT(ic))->name));
2448
2449   GpsuedoStkPtr=0;
2450   /* if we need assign a result value */
2451   if ((IS_ITEMP(IC_RESULT(ic)) && 
2452        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2453         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2454       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2455
2456     _G.accInUse++;
2457     aopOp(IC_RESULT(ic),ic,FALSE);
2458     _G.accInUse--;
2459
2460     assignResultValue(IC_RESULT(ic));
2461
2462     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2463                          AopType(AOP_TYPE(IC_RESULT(ic))));
2464                 
2465     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2466   }
2467
2468   /* adjust the stack for parameters if 
2469      required */
2470   if (ic->parmBytes) {
2471     int i;
2472     if (ic->parmBytes > 3) {
2473       pic14_emitcode("mov","a,%s",spname);
2474       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2475       pic14_emitcode("mov","%s,a",spname);
2476     } else 
2477       for ( i = 0 ; i <  ic->parmBytes ;i++)
2478         pic14_emitcode("dec","%s",spname);
2479
2480   }
2481
2482   /* if register bank was saved then pop them */
2483   if (ic->bankSaved)
2484     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2485
2486   /* if we hade saved some registers then unsave them */
2487   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2488     unsaveRegisters (ic);
2489
2490
2491 }
2492
2493 /*-----------------------------------------------------------------*/
2494 /* genPcall - generates a call by pointer statement                */
2495 /*-----------------------------------------------------------------*/
2496 static void genPcall (iCode *ic)
2497 {
2498     sym_link *dtype;
2499     symbol *rlbl = newiTempLabel(NULL);
2500
2501
2502     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2503     /* if caller saves & we have not saved then */
2504     if (!ic->regsSaved)
2505         saveRegisters(ic);
2506
2507     /* if we are calling a function that is not using
2508     the same register bank then we need to save the
2509     destination registers on the stack */
2510     dtype = operandType(IC_LEFT(ic));
2511     if (currFunc && dtype && 
2512         IFFUNC_ISISR(currFunc->type) &&
2513         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2514         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2515
2516
2517     /* push the return address on to the stack */
2518     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2519     pic14_emitcode("push","acc");    
2520     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2521     pic14_emitcode("push","acc");
2522     
2523     if (options.model == MODEL_FLAT24)
2524     {
2525         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2526         pic14_emitcode("push","acc");    
2527     }
2528
2529     /* now push the calling address */
2530     aopOp(IC_LEFT(ic),ic,FALSE);
2531
2532     pushSide(IC_LEFT(ic), FPTRSIZE);
2533
2534     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2535
2536     /* if send set is not empty the assign */
2537     if (_G.sendSet) {
2538         iCode *sic ;
2539
2540         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2541              sic = setNextItem(_G.sendSet)) {
2542             int size, offset = 0;
2543             aopOp(IC_LEFT(sic),sic,FALSE);
2544             size = AOP_SIZE(IC_LEFT(sic));
2545             while (size--) {
2546                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2547                                 FALSE,FALSE);
2548                 if (strcmp(l,fReturn[offset]))
2549                     pic14_emitcode("mov","%s,%s",
2550                              fReturn[offset],
2551                              l);
2552                 offset++;
2553             }
2554             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2555         }
2556         _G.sendSet = NULL;
2557     }
2558
2559     pic14_emitcode("ret","");
2560     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2561
2562
2563     /* if we need assign a result value */
2564     if ((IS_ITEMP(IC_RESULT(ic)) &&
2565          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2566           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2567         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2568
2569         _G.accInUse++;
2570         aopOp(IC_RESULT(ic),ic,FALSE);
2571         _G.accInUse--;
2572         
2573         assignResultValue(IC_RESULT(ic));
2574
2575         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2576     }
2577
2578     /* adjust the stack for parameters if 
2579     required */
2580     if (ic->parmBytes) {
2581         int i;
2582         if (ic->parmBytes > 3) {
2583             pic14_emitcode("mov","a,%s",spname);
2584             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2585             pic14_emitcode("mov","%s,a",spname);
2586         } else 
2587             for ( i = 0 ; i <  ic->parmBytes ;i++)
2588                 pic14_emitcode("dec","%s",spname);
2589
2590     }
2591
2592     /* if register bank was saved then unsave them */
2593     if (currFunc && dtype && 
2594         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2595         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2596
2597     /* if we hade saved some registers then
2598     unsave them */
2599     if (ic->regsSaved)
2600         unsaveRegisters (ic);
2601
2602 }
2603
2604 /*-----------------------------------------------------------------*/
2605 /* resultRemat - result  is rematerializable                       */
2606 /*-----------------------------------------------------------------*/
2607 static int resultRemat (iCode *ic)
2608 {
2609   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2610   if (SKIP_IC(ic) || ic->op == IFX)
2611     return 0;
2612
2613   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2614     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2615     if (sym->remat && !POINTER_SET(ic)) 
2616       return 1;
2617   }
2618
2619   return 0;
2620 }
2621
2622 #if defined(__BORLANDC__) || defined(_MSC_VER)
2623 #define STRCASECMP stricmp
2624 #else
2625 #define STRCASECMP strcasecmp
2626 #endif
2627
2628 #if 0
2629 /*-----------------------------------------------------------------*/
2630 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2631 /*-----------------------------------------------------------------*/
2632 static bool inExcludeList(char *s)
2633 {
2634   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2635     int i =0;
2636     
2637     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2638     if (options.excludeRegs[i] &&
2639     STRCASECMP(options.excludeRegs[i],"none") == 0)
2640         return FALSE ;
2641
2642     for ( i = 0 ; options.excludeRegs[i]; i++) {
2643         if (options.excludeRegs[i] &&
2644         STRCASECMP(s,options.excludeRegs[i]) == 0)
2645             return TRUE;
2646     }
2647     return FALSE ;
2648 }
2649 #endif
2650
2651 /*-----------------------------------------------------------------*/
2652 /* genFunction - generated code for function entry                 */
2653 /*-----------------------------------------------------------------*/
2654 static void genFunction (iCode *ic)
2655 {
2656     symbol *sym;
2657     sym_link *ftype;
2658
2659     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2660
2661     labelOffset += (max_key+4);
2662     max_key=0;
2663     GpsuedoStkPtr=0;
2664     _G.nRegsSaved = 0;
2665     /* create the function header */
2666     pic14_emitcode(";","-----------------------------------------");
2667     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2668     pic14_emitcode(";","-----------------------------------------");
2669
2670     pic14_emitcode("","%s:",sym->rname);
2671     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2672
2673     ftype = operandType(IC_LEFT(ic));
2674
2675     /* if critical function then turn interrupts off */
2676     if (IFFUNC_ISCRITICAL(ftype))
2677         pic14_emitcode("clr","ea");
2678
2679     /* here we need to generate the equates for the
2680        register bank if required */
2681 #if 0
2682     if (FUNC_REGBANK(ftype) != rbank) {
2683         int i ;
2684
2685         rbank = FUNC_REGBANK(ftype);
2686         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2687             if (strcmp(regspic14[i].base,"0") == 0)
2688                 pic14_emitcode("","%s = 0x%02x",
2689                          regspic14[i].dname,
2690                          8*rbank+regspic14[i].offset);
2691             else
2692                 pic14_emitcode ("","%s = %s + 0x%02x",
2693                           regspic14[i].dname,
2694                           regspic14[i].base,
2695                           8*rbank+regspic14[i].offset);
2696         }
2697     }
2698 #endif
2699
2700     /* if this is an interrupt service routine then
2701     save acc, b, dpl, dph  */
2702     if (IFFUNC_ISISR(sym->type)) {
2703       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2704       emitpcodeNULLop(POC_NOP);
2705       emitpcodeNULLop(POC_NOP);
2706       emitpcodeNULLop(POC_NOP);
2707       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2708       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2709       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2710       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2711
2712       pBlockConvert2ISR(pb);
2713 #if 0  
2714         if (!inExcludeList("acc"))          
2715             pic14_emitcode ("push","acc");      
2716         if (!inExcludeList("b"))
2717             pic14_emitcode ("push","b");
2718         if (!inExcludeList("dpl"))
2719             pic14_emitcode ("push","dpl");
2720         if (!inExcludeList("dph"))
2721             pic14_emitcode ("push","dph");
2722         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2723         {
2724             pic14_emitcode ("push", "dpx");
2725             /* Make sure we're using standard DPTR */
2726             pic14_emitcode ("push", "dps");
2727             pic14_emitcode ("mov", "dps, #0x00");
2728             if (options.stack10bit)
2729             {   
2730                 /* This ISR could conceivably use DPTR2. Better save it. */
2731                 pic14_emitcode ("push", "dpl1");
2732                 pic14_emitcode ("push", "dph1");
2733                 pic14_emitcode ("push", "dpx1");
2734             }
2735         }
2736         /* if this isr has no bank i.e. is going to
2737            run with bank 0 , then we need to save more
2738            registers :-) */
2739         if (!FUNC_REGBANK(sym->type)) {
2740
2741             /* if this function does not call any other
2742                function then we can be economical and
2743                save only those registers that are used */
2744             if (! IFFUNC_HASFCALL(sym->type)) {
2745                 int i;
2746
2747                 /* if any registers used */
2748                 if (sym->regsUsed) {
2749                     /* save the registers used */
2750                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2751                         if (bitVectBitValue(sym->regsUsed,i) ||
2752                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2753                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2754                     }
2755                 }
2756                 
2757             } else {
2758                 /* this function has  a function call cannot
2759                    determines register usage so we will have the
2760                    entire bank */
2761                 saverbank(0,ic,FALSE);
2762             }       
2763         }
2764 #endif
2765     } else {
2766         /* if callee-save to be used for this function
2767            then save the registers being used in this function */
2768         if (IFFUNC_CALLEESAVES(sym->type)) {
2769             int i;
2770             
2771             /* if any registers used */
2772             if (sym->regsUsed) {
2773                 /* save the registers used */
2774                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2775                     if (bitVectBitValue(sym->regsUsed,i) ||
2776                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2777                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2778                         _G.nRegsSaved++;
2779                     }
2780                 }
2781             }
2782         }
2783     }
2784
2785     /* set the register bank to the desired value */
2786     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2787         pic14_emitcode("push","psw");
2788         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2789     }
2790
2791     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2792
2793         if (options.useXstack) {
2794             pic14_emitcode("mov","r0,%s",spname);
2795             pic14_emitcode("mov","a,_bp");
2796             pic14_emitcode("movx","@r0,a");
2797             pic14_emitcode("inc","%s",spname);
2798         }
2799         else
2800         {
2801             /* set up the stack */
2802             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2803         }
2804         pic14_emitcode ("mov","_bp,%s",spname);
2805     }
2806
2807     /* adjust the stack for the function */
2808     if (sym->stack) {
2809
2810         int i = sym->stack;
2811         if (i > 256 ) 
2812             werror(W_STACK_OVERFLOW,sym->name);
2813
2814         if (i > 3 && sym->recvSize < 4) {              
2815
2816             pic14_emitcode ("mov","a,sp");
2817             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2818             pic14_emitcode ("mov","sp,a");
2819            
2820         }
2821         else
2822             while(i--)
2823                 pic14_emitcode("inc","sp");
2824     }
2825
2826      if (sym->xstack) {
2827
2828         pic14_emitcode ("mov","a,_spx");
2829         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2830         pic14_emitcode ("mov","_spx,a");
2831     }    
2832
2833 }
2834
2835 /*-----------------------------------------------------------------*/
2836 /* genEndFunction - generates epilogue for functions               */
2837 /*-----------------------------------------------------------------*/
2838 static void genEndFunction (iCode *ic)
2839 {
2840     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2841
2842     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2843
2844     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2845     {
2846         pic14_emitcode ("mov","%s,_bp",spname);
2847     }
2848
2849     /* if use external stack but some variables were
2850     added to the local stack then decrement the
2851     local stack */
2852     if (options.useXstack && sym->stack) {      
2853         pic14_emitcode("mov","a,sp");
2854         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2855         pic14_emitcode("mov","sp,a");
2856     }
2857
2858
2859     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2860         if (options.useXstack) {
2861             pic14_emitcode("mov","r0,%s",spname);
2862             pic14_emitcode("movx","a,@r0");
2863             pic14_emitcode("mov","_bp,a");
2864             pic14_emitcode("dec","%s",spname);
2865         }
2866         else
2867         {
2868             pic14_emitcode ("pop","_bp");
2869         }
2870     }
2871
2872     /* restore the register bank  */    
2873     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2874         pic14_emitcode ("pop","psw");
2875
2876     if (IFFUNC_ISISR(sym->type)) {
2877
2878         /* now we need to restore the registers */
2879         /* if this isr has no bank i.e. is going to
2880            run with bank 0 , then we need to save more
2881            registers :-) */
2882         if (!FUNC_REGBANK(sym->type)) {
2883             
2884             /* if this function does not call any other
2885                function then we can be economical and
2886                save only those registers that are used */
2887             if (! IFFUNC_HASFCALL(sym->type)) {
2888                 int i;
2889                 
2890                 /* if any registers used */
2891                 if (sym->regsUsed) {
2892                     /* save the registers used */
2893                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2894                         if (bitVectBitValue(sym->regsUsed,i) ||
2895                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2896                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2897                     }
2898                 }
2899                 
2900             } else {
2901                 /* this function has  a function call cannot
2902                    determines register usage so we will have the
2903                    entire bank */
2904                 unsaverbank(0,ic,FALSE);
2905             }       
2906         }
2907 #if 0
2908         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2909         {
2910             if (options.stack10bit)
2911             {
2912                 pic14_emitcode ("pop", "dpx1");
2913                 pic14_emitcode ("pop", "dph1");
2914                 pic14_emitcode ("pop", "dpl1");
2915             }   
2916             pic14_emitcode ("pop", "dps");
2917             pic14_emitcode ("pop", "dpx");
2918         }
2919         if (!inExcludeList("dph"))
2920             pic14_emitcode ("pop","dph");
2921         if (!inExcludeList("dpl"))
2922             pic14_emitcode ("pop","dpl");
2923         if (!inExcludeList("b"))
2924             pic14_emitcode ("pop","b");
2925         if (!inExcludeList("acc"))
2926             pic14_emitcode ("pop","acc");
2927
2928         if (IFFUNC_ISCRITICAL(sym->type))
2929             pic14_emitcode("setb","ea");
2930 #endif
2931
2932         /* if debug then send end of function */
2933 /*      if (options.debug && currFunc) { */
2934         if (currFunc) {
2935             _G.debugLine = 1;
2936             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2937                      FileBaseName(ic->filename),currFunc->lastLine,
2938                      ic->level,ic->block); 
2939             if (IS_STATIC(currFunc->etype))         
2940                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2941             else
2942                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2943             _G.debugLine = 0;
2944         }
2945         
2946         pic14_emitcode ("reti","");
2947
2948         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2949         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2950         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2951         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2952         emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
2953         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2954
2955         emitpcodeNULLop(POC_RETFIE);
2956
2957     }
2958     else {
2959         if (IFFUNC_ISCRITICAL(sym->type))
2960             pic14_emitcode("setb","ea");
2961         
2962         if (IFFUNC_CALLEESAVES(sym->type)) {
2963             int i;
2964             
2965             /* if any registers used */
2966             if (sym->regsUsed) {
2967                 /* save the registers used */
2968                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2969                     if (bitVectBitValue(sym->regsUsed,i) ||
2970                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2971                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2972                 }
2973             }
2974             
2975         }
2976
2977         /* if debug then send end of function */
2978         if (currFunc) {
2979             _G.debugLine = 1;
2980             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2981                      FileBaseName(ic->filename),currFunc->lastLine,
2982                      ic->level,ic->block); 
2983             if (IS_STATIC(currFunc->etype))         
2984                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2985             else
2986                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2987             _G.debugLine = 0;
2988         }
2989
2990         pic14_emitcode ("return","");
2991         emitpcodeNULLop(POC_RETURN);
2992
2993         /* Mark the end of a function */
2994         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2995     }
2996
2997 }
2998
2999 /*-----------------------------------------------------------------*/
3000 /* genRet - generate code for return statement                     */
3001 /*-----------------------------------------------------------------*/
3002 static void genRet (iCode *ic)
3003 {
3004   int size,offset = 0 , pushed = 0;
3005     
3006   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3007   /* if we have no return value then
3008      just generate the "ret" */
3009   if (!IC_LEFT(ic)) 
3010     goto jumpret;       
3011     
3012   /* we have something to return then
3013      move the return value into place */
3014   aopOp(IC_LEFT(ic),ic,FALSE);
3015   size = AOP_SIZE(IC_LEFT(ic));
3016     
3017   while (size--) {
3018     char *l ;
3019     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3020       /* #NOCHANGE */
3021       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3022                  FALSE,TRUE);
3023       pic14_emitcode("push","%s",l);
3024       pushed++;
3025     } else {
3026       l = aopGet(AOP(IC_LEFT(ic)),offset,
3027                  FALSE,FALSE);
3028       if (strcmp(fReturn[offset],l)) {
3029         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3030             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3031           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3032         }else {
3033           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3034         }
3035         if(size) {
3036           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3037         }
3038         offset++;
3039       }
3040     }
3041   }    
3042
3043   if (pushed) {
3044     while(pushed) {
3045       pushed--;
3046       if (strcmp(fReturn[pushed],"a"))
3047         pic14_emitcode("pop",fReturn[pushed]);
3048       else
3049         pic14_emitcode("pop","acc");
3050     }
3051   }
3052   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3053     
3054  jumpret:
3055   /* generate a jump to the return label
3056      if the next is not the return statement */
3057   if (!(ic->next && ic->next->op == LABEL &&
3058         IC_LABEL(ic->next) == returnLabel)) {
3059         
3060     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3061     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3062   }
3063     
3064 }
3065
3066 /*-----------------------------------------------------------------*/
3067 /* genLabel - generates a label                                    */
3068 /*-----------------------------------------------------------------*/
3069 static void genLabel (iCode *ic)
3070 {
3071     /* special case never generate */
3072     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3073     if (IC_LABEL(ic) == entryLabel)
3074         return ;
3075
3076     emitpLabel(IC_LABEL(ic)->key);
3077     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3078 }
3079
3080 /*-----------------------------------------------------------------*/
3081 /* genGoto - generates a goto                                      */
3082 /*-----------------------------------------------------------------*/
3083 //tsd
3084 static void genGoto (iCode *ic)
3085 {
3086   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3087   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3088 }
3089
3090
3091 /*-----------------------------------------------------------------*/
3092 /* genMultbits :- multiplication of bits                           */
3093 /*-----------------------------------------------------------------*/
3094 static void genMultbits (operand *left, 
3095                          operand *right, 
3096                          operand *result)
3097 {
3098   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3099
3100   if(!pic14_sameRegs(AOP(result),AOP(right)))
3101     emitpcode(POC_BSF,  popGet(AOP(result),0));
3102
3103   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3104   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3105   emitpcode(POC_BCF,  popGet(AOP(result),0));
3106
3107 }
3108
3109
3110 /*-----------------------------------------------------------------*/
3111 /* genMultOneByte : 8 bit multiplication & division                */
3112 /*-----------------------------------------------------------------*/
3113 static void genMultOneByte (operand *left,
3114                             operand *right,
3115                             operand *result)
3116 {
3117   sym_link *opetype = operandType(result);
3118
3119   // symbol *lbl ;
3120   int size,offset;
3121
3122   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3123   DEBUGpic14_AopType(__LINE__,left,right,result);
3124   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3125
3126   /* (if two literals, the value is computed before) */
3127   /* if one literal, literal on the right */
3128   if (AOP_TYPE(left) == AOP_LIT){
3129     operand *t = right;
3130     right = left;
3131     left = t;
3132   }
3133
3134   size = AOP_SIZE(result);
3135   if(size == 1) {
3136
3137     if (AOP_TYPE(right) == AOP_LIT){
3138       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3139                      aopGet(AOP(right),0,FALSE,FALSE), 
3140                      aopGet(AOP(left),0,FALSE,FALSE), 
3141                      aopGet(AOP(result),0,FALSE,FALSE));
3142       pic14_emitcode("call","genMultLit");
3143     } else {
3144       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3145                      aopGet(AOP(right),0,FALSE,FALSE), 
3146                      aopGet(AOP(left),0,FALSE,FALSE), 
3147                      aopGet(AOP(result),0,FALSE,FALSE));
3148       pic14_emitcode("call","genMult8X8_8");
3149
3150     }
3151     genMult8X8_8 (left, right,result);
3152
3153
3154     /* signed or unsigned */
3155     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3156     //l = aopGet(AOP(left),0,FALSE,FALSE);
3157     //MOVA(l);       
3158     //pic14_emitcode("mul","ab");
3159     /* if result size = 1, mul signed = mul unsigned */
3160     //aopPut(AOP(result),"a",0);
3161
3162   } else {  // (size > 1)
3163
3164     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3165                    aopGet(AOP(right),0,FALSE,FALSE), 
3166                    aopGet(AOP(left),0,FALSE,FALSE), 
3167                    aopGet(AOP(result),0,FALSE,FALSE));
3168
3169     if (SPEC_USIGN(opetype)){
3170       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3171       genUMult8X8_16 (left, right, result, NULL);
3172
3173       if (size > 2) {
3174         /* for filling the MSBs */
3175         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3176         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3177       }
3178     }
3179     else{
3180       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3181
3182       pic14_emitcode("mov","a,b");
3183
3184       /* adjust the MSB if left or right neg */
3185
3186       /* if one literal */
3187       if (AOP_TYPE(right) == AOP_LIT){
3188         pic14_emitcode("multiply ","right is a lit");
3189         /* AND literal negative */
3190         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3191           /* adjust MSB (c==0 after mul) */
3192           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3193         }
3194       }
3195       else{
3196         genSMult8X8_16 (left, right, result, NULL);
3197       }
3198
3199       if(size > 2){
3200         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3201         /* get the sign */
3202         pic14_emitcode("rlc","a");
3203         pic14_emitcode("subb","a,acc");
3204       }
3205     }
3206
3207     size -= 2;   
3208     offset = 2;
3209     if (size > 0)
3210       while (size--)
3211         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3212     //aopPut(AOP(result),"a",offset++);
3213   }
3214 }
3215
3216 /*-----------------------------------------------------------------*/
3217 /* genMult - generates code for multiplication                     */
3218 /*-----------------------------------------------------------------*/
3219 static void genMult (iCode *ic)
3220 {
3221     operand *left = IC_LEFT(ic);
3222     operand *right = IC_RIGHT(ic);
3223     operand *result= IC_RESULT(ic);   
3224
3225     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3226     /* assign the amsops */
3227     aopOp (left,ic,FALSE);
3228     aopOp (right,ic,FALSE);
3229     aopOp (result,ic,TRUE);
3230
3231   DEBUGpic14_AopType(__LINE__,left,right,result);
3232
3233     /* special cases first */
3234     /* both are bits */
3235     if (AOP_TYPE(left) == AOP_CRY &&
3236         AOP_TYPE(right)== AOP_CRY) {
3237         genMultbits(left,right,result);
3238         goto release ;
3239     }
3240
3241     /* if both are of size == 1 */
3242     if (AOP_SIZE(left) == 1 &&
3243         AOP_SIZE(right) == 1 ) {
3244         genMultOneByte(left,right,result);
3245         goto release ;
3246     }
3247
3248     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3249
3250     /* should have been converted to function call */
3251     //assert(0) ;
3252
3253 release :
3254     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3255     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3256     freeAsmop(result,NULL,ic,TRUE); 
3257 }
3258
3259 /*-----------------------------------------------------------------*/
3260 /* genDivbits :- division of bits                                  */
3261 /*-----------------------------------------------------------------*/
3262 static void genDivbits (operand *left, 
3263                         operand *right, 
3264                         operand *result)
3265 {
3266
3267     char *l;
3268
3269     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3270     /* the result must be bit */    
3271     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3272     l = aopGet(AOP(left),0,FALSE,FALSE);
3273
3274     MOVA(l);    
3275
3276     pic14_emitcode("div","ab");
3277     pic14_emitcode("rrc","a");
3278     aopPut(AOP(result),"c",0);
3279 }
3280
3281 /*-----------------------------------------------------------------*/
3282 /* genDivOneByte : 8 bit division                                  */
3283 /*-----------------------------------------------------------------*/
3284 static void genDivOneByte (operand *left,
3285                            operand *right,
3286                            operand *result)
3287 {
3288     sym_link *opetype = operandType(result);
3289     char *l ;
3290     symbol *lbl ;
3291     int size,offset;
3292
3293     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3294     size = AOP_SIZE(result) - 1;
3295     offset = 1;
3296     /* signed or unsigned */
3297     if (SPEC_USIGN(opetype)) {
3298         /* unsigned is easy */
3299         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3300         l = aopGet(AOP(left),0,FALSE,FALSE);
3301         MOVA(l);        
3302         pic14_emitcode("div","ab");
3303         aopPut(AOP(result),"a",0);
3304         while (size--)
3305             aopPut(AOP(result),zero,offset++);
3306         return ;
3307     }
3308
3309     /* signed is a little bit more difficult */
3310
3311     /* save the signs of the operands */
3312     l = aopGet(AOP(left),0,FALSE,FALSE);    
3313     MOVA(l);    
3314     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3315     pic14_emitcode("push","acc"); /* save it on the stack */
3316
3317     /* now sign adjust for both left & right */
3318     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3319     MOVA(l);       
3320     lbl = newiTempLabel(NULL);
3321     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3322     pic14_emitcode("cpl","a");   
3323     pic14_emitcode("inc","a");
3324     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3325     pic14_emitcode("mov","b,a");
3326
3327     /* sign adjust left side */
3328     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3329     MOVA(l);
3330
3331     lbl = newiTempLabel(NULL);
3332     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3333     pic14_emitcode("cpl","a");
3334     pic14_emitcode("inc","a");
3335     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3336
3337     /* now the division */
3338     pic14_emitcode("div","ab");
3339     /* we are interested in the lower order
3340     only */
3341     pic14_emitcode("mov","b,a");
3342     lbl = newiTempLabel(NULL);
3343     pic14_emitcode("pop","acc");   
3344     /* if there was an over flow we don't 
3345     adjust the sign of the result */
3346     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3347     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3348     CLRC;
3349     pic14_emitcode("clr","a");
3350     pic14_emitcode("subb","a,b");
3351     pic14_emitcode("mov","b,a");
3352     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3353
3354     /* now we are done */
3355     aopPut(AOP(result),"b",0);
3356     if(size > 0){
3357         pic14_emitcode("mov","c,b.7");
3358         pic14_emitcode("subb","a,acc");   
3359     }
3360     while (size--)
3361         aopPut(AOP(result),"a",offset++);
3362
3363 }
3364
3365 /*-----------------------------------------------------------------*/
3366 /* genDiv - generates code for division                            */
3367 /*-----------------------------------------------------------------*/
3368 static void genDiv (iCode *ic)
3369 {
3370     operand *left = IC_LEFT(ic);
3371     operand *right = IC_RIGHT(ic);
3372     operand *result= IC_RESULT(ic);   
3373
3374     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3375     /* assign the amsops */
3376     aopOp (left,ic,FALSE);
3377     aopOp (right,ic,FALSE);
3378     aopOp (result,ic,TRUE);
3379
3380     /* special cases first */
3381     /* both are bits */
3382     if (AOP_TYPE(left) == AOP_CRY &&
3383         AOP_TYPE(right)== AOP_CRY) {
3384         genDivbits(left,right,result);
3385         goto release ;
3386     }
3387
3388     /* if both are of size == 1 */
3389     if (AOP_SIZE(left) == 1 &&
3390         AOP_SIZE(right) == 1 ) {
3391         genDivOneByte(left,right,result);
3392         goto release ;
3393     }
3394
3395     /* should have been converted to function call */
3396     assert(0);
3397 release :
3398     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3399     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3400     freeAsmop(result,NULL,ic,TRUE); 
3401 }
3402
3403 /*-----------------------------------------------------------------*/
3404 /* genModbits :- modulus of bits                                   */
3405 /*-----------------------------------------------------------------*/
3406 static void genModbits (operand *left, 
3407                         operand *right, 
3408                         operand *result)
3409 {
3410
3411     char *l;
3412
3413     /* the result must be bit */    
3414     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3415     l = aopGet(AOP(left),0,FALSE,FALSE);
3416
3417     MOVA(l);       
3418
3419     pic14_emitcode("div","ab");
3420     pic14_emitcode("mov","a,b");
3421     pic14_emitcode("rrc","a");
3422     aopPut(AOP(result),"c",0);
3423 }
3424
3425 /*-----------------------------------------------------------------*/
3426 /* genModOneByte : 8 bit modulus                                   */
3427 /*-----------------------------------------------------------------*/
3428 static void genModOneByte (operand *left,
3429                            operand *right,
3430                            operand *result)
3431 {
3432     sym_link *opetype = operandType(result);
3433     char *l ;
3434     symbol *lbl ;
3435
3436     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3437     /* signed or unsigned */
3438     if (SPEC_USIGN(opetype)) {
3439         /* unsigned is easy */
3440         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3441         l = aopGet(AOP(left),0,FALSE,FALSE);
3442         MOVA(l);    
3443         pic14_emitcode("div","ab");
3444         aopPut(AOP(result),"b",0);
3445         return ;
3446     }
3447
3448     /* signed is a little bit more difficult */
3449
3450     /* save the signs of the operands */
3451     l = aopGet(AOP(left),0,FALSE,FALSE);    
3452     MOVA(l);
3453
3454     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3455     pic14_emitcode("push","acc"); /* save it on the stack */
3456
3457     /* now sign adjust for both left & right */
3458     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3459     MOVA(l);
3460
3461     lbl = newiTempLabel(NULL);
3462     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3463     pic14_emitcode("cpl","a");   
3464     pic14_emitcode("inc","a");
3465     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3466     pic14_emitcode("mov","b,a"); 
3467
3468     /* sign adjust left side */
3469     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3470     MOVA(l);
3471
3472     lbl = newiTempLabel(NULL);
3473     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3474     pic14_emitcode("cpl","a");   
3475     pic14_emitcode("inc","a");
3476     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3477
3478     /* now the multiplication */
3479     pic14_emitcode("div","ab");
3480     /* we are interested in the lower order
3481     only */
3482     lbl = newiTempLabel(NULL);
3483     pic14_emitcode("pop","acc");   
3484     /* if there was an over flow we don't 
3485     adjust the sign of the result */
3486     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3487     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3488     CLRC ;
3489     pic14_emitcode("clr","a");
3490     pic14_emitcode("subb","a,b");
3491     pic14_emitcode("mov","b,a");
3492     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3493
3494     /* now we are done */
3495     aopPut(AOP(result),"b",0);
3496
3497 }
3498
3499 /*-----------------------------------------------------------------*/
3500 /* genMod - generates code for division                            */
3501 /*-----------------------------------------------------------------*/
3502 static void genMod (iCode *ic)
3503 {
3504     operand *left = IC_LEFT(ic);
3505     operand *right = IC_RIGHT(ic);
3506     operand *result= IC_RESULT(ic);  
3507
3508     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3509     /* assign the amsops */
3510     aopOp (left,ic,FALSE);
3511     aopOp (right,ic,FALSE);
3512     aopOp (result,ic,TRUE);
3513
3514     /* special cases first */
3515     /* both are bits */
3516     if (AOP_TYPE(left) == AOP_CRY &&
3517         AOP_TYPE(right)== AOP_CRY) {
3518         genModbits(left,right,result);
3519         goto release ;
3520     }
3521
3522     /* if both are of size == 1 */
3523     if (AOP_SIZE(left) == 1 &&
3524         AOP_SIZE(right) == 1 ) {
3525         genModOneByte(left,right,result);
3526         goto release ;
3527     }
3528
3529     /* should have been converted to function call */
3530     assert(0);
3531
3532 release :
3533     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3534     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3535     freeAsmop(result,NULL,ic,TRUE); 
3536 }
3537
3538 /*-----------------------------------------------------------------*/
3539 /* genIfxJump :- will create a jump depending on the ifx           */
3540 /*-----------------------------------------------------------------*/
3541 /*
3542   note: May need to add parameter to indicate when a variable is in bit space.
3543 */
3544 static void genIfxJump (iCode *ic, char *jval)
3545 {
3546
3547     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3548     /* if true label then we jump if condition
3549     supplied is true */
3550     if ( IC_TRUE(ic) ) {
3551
3552         if(strcmp(jval,"a") == 0)
3553           emitSKPZ;
3554         else if (strcmp(jval,"c") == 0)
3555           emitSKPC;
3556         else {
3557           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3558           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3559         }
3560
3561         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3562         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3563
3564     }
3565     else {
3566         /* false label is present */
3567         if(strcmp(jval,"a") == 0)
3568           emitSKPNZ;
3569         else if (strcmp(jval,"c") == 0)
3570           emitSKPNC;
3571         else {
3572           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3573           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3574         }
3575
3576         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3577         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3578
3579     }
3580
3581
3582     /* mark the icode as generated */
3583     ic->generated = 1;
3584 }
3585
3586 /*-----------------------------------------------------------------*/
3587 /* genSkip                                                         */
3588 /*-----------------------------------------------------------------*/
3589 static void genSkip(iCode *ifx,int status_bit)
3590 {
3591   if(!ifx)
3592     return;
3593
3594   if ( IC_TRUE(ifx) ) {
3595     switch(status_bit) {
3596     case 'z':
3597       emitSKPNZ;
3598       break;
3599
3600     case 'c':
3601       emitSKPNC;
3602       break;
3603
3604     case 'd':
3605       emitSKPDC;
3606       break;
3607
3608     }
3609
3610     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3611     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3612
3613   } else {
3614
3615     switch(status_bit) {
3616
3617     case 'z':
3618       emitSKPZ;
3619       break;
3620
3621     case 'c':
3622       emitSKPC;
3623       break;
3624
3625     case 'd':
3626       emitSKPDC;
3627       break;
3628     }
3629     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3630     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3631
3632   }
3633
3634 }
3635
3636 /*-----------------------------------------------------------------*/
3637 /* genSkipc                                                        */
3638 /*-----------------------------------------------------------------*/
3639 static void genSkipc(resolvedIfx *rifx)
3640 {
3641   if(!rifx)
3642     return;
3643
3644   if(rifx->condition)
3645     emitSKPC;
3646   else
3647     emitSKPNC;
3648
3649   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3650   rifx->generated = 1;
3651 }
3652
3653 /*-----------------------------------------------------------------*/
3654 /* genSkipz2                                                       */
3655 /*-----------------------------------------------------------------*/
3656 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3657 {
3658   if(!rifx)
3659     return;
3660
3661   if( (rifx->condition ^ invert_condition) & 1)
3662     emitSKPZ;
3663   else
3664     emitSKPNZ;
3665
3666   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3667   rifx->generated = 1;
3668 }
3669
3670 /*-----------------------------------------------------------------*/
3671 /* genSkipz                                                        */
3672 /*-----------------------------------------------------------------*/
3673 static void genSkipz(iCode *ifx, int condition)
3674 {
3675   if(!ifx)
3676     return;
3677
3678   if(condition)
3679     emitSKPNZ;
3680   else
3681     emitSKPZ;
3682
3683   if ( IC_TRUE(ifx) )
3684     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3685   else
3686     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3687
3688   if ( IC_TRUE(ifx) )
3689     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3690   else
3691     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3692
3693 }
3694 /*-----------------------------------------------------------------*/
3695 /* genSkipCond                                                     */
3696 /*-----------------------------------------------------------------*/
3697 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3698 {
3699   if(!rifx)
3700     return;
3701
3702   if(rifx->condition)
3703     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3704   else
3705     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3706
3707
3708   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3709   rifx->generated = 1;
3710 }
3711
3712 #if 0
3713 /*-----------------------------------------------------------------*/
3714 /* genChkZeroes :- greater or less than comparison                 */
3715 /*     For each byte in a literal that is zero, inclusive or the   */
3716 /*     the corresponding byte in the operand with W                */
3717 /*     returns true if any of the bytes are zero                   */
3718 /*-----------------------------------------------------------------*/
3719 static int genChkZeroes(operand *op, int lit,  int size)
3720 {
3721
3722   int i;
3723   int flag =1;
3724
3725   while(size--) {
3726     i = (lit >> (size*8)) & 0xff;
3727
3728     if(i==0) {
3729       if(flag) 
3730         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3731       else
3732         emitpcode(POC_IORFW, popGet(AOP(op),size));
3733       flag = 0;
3734     }
3735   }
3736
3737   return (flag==0);
3738 }
3739 #endif
3740
3741 /*-----------------------------------------------------------------*/
3742 /* genCmp :- greater or less than comparison                       */
3743 /*-----------------------------------------------------------------*/
3744 static void genCmp (operand *left,operand *right,
3745                     operand *result, iCode *ifx, int sign)
3746 {
3747   int size; //, offset = 0 ;
3748   unsigned long lit = 0L,i = 0;
3749   resolvedIfx rFalseIfx;
3750   //  resolvedIfx rTrueIfx;
3751   symbol *truelbl;
3752   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3753 /*
3754   if(ifx) {
3755     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3756     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3757   }
3758 */
3759
3760   resolveIfx(&rFalseIfx,ifx);
3761   truelbl  = newiTempLabel(NULL);
3762   size = max(AOP_SIZE(left),AOP_SIZE(right));
3763
3764 #define _swapp
3765
3766   /* if literal is on the right then swap with left */
3767   if ((AOP_TYPE(right) == AOP_LIT)) {
3768     operand *tmp = right ;
3769     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3770     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3771 #ifdef _swapp
3772
3773     lit = (lit - 1) & mask;
3774     right = left;
3775     left = tmp;
3776     rFalseIfx.condition ^= 1;
3777 #endif
3778
3779   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3780     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3781   }
3782
3783
3784   //if(IC_TRUE(ifx) == NULL)
3785   /* if left & right are bit variables */
3786   if (AOP_TYPE(left) == AOP_CRY &&
3787       AOP_TYPE(right) == AOP_CRY ) {
3788     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3789     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3790   } else {
3791     /* subtract right from left if at the
3792        end the carry flag is set then we know that
3793        left is greater than right */
3794
3795     //    {
3796
3797     symbol *lbl  = newiTempLabel(NULL);
3798
3799 #ifndef _swapp
3800     if(AOP_TYPE(right) == AOP_LIT) {
3801
3802       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3803
3804       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3805
3806       /* special cases */
3807
3808       if(lit == 0) {
3809
3810         if(sign != 0) 
3811           genSkipCond(&rFalseIfx,left,size-1,7);
3812         else 
3813           /* no need to compare to 0...*/
3814           /* NOTE: this is a de-generate compare that most certainly 
3815            *       creates some dead code. */
3816           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3817
3818         if(ifx) ifx->generated = 1;
3819         return;
3820
3821       }
3822       size--;
3823
3824       if(size == 0) {
3825         //i = (lit >> (size*8)) & 0xff;
3826         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3827         
3828         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3829
3830         i = ((0-lit) & 0xff);
3831         if(sign) {
3832           if( i == 0x81) { 
3833             /* lit is 0x7f, all signed chars are less than
3834              * this except for 0x7f itself */
3835             emitpcode(POC_XORLW, popGetLit(0x7f));
3836             genSkipz2(&rFalseIfx,0);
3837           } else {
3838             emitpcode(POC_ADDLW, popGetLit(0x80));
3839             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3840             genSkipc(&rFalseIfx);
3841           }
3842
3843         } else {
3844           if(lit == 1) {
3845             genSkipz2(&rFalseIfx,1);
3846           } else {
3847             emitpcode(POC_ADDLW, popGetLit(i));
3848             genSkipc(&rFalseIfx);
3849           }
3850         }
3851
3852         if(ifx) ifx->generated = 1;
3853         return;
3854       }
3855
3856       /* chars are out of the way. now do ints and longs */
3857
3858
3859       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3860         
3861       /* special cases */
3862
3863       if(sign) {
3864
3865         if(lit == 0) {
3866           genSkipCond(&rFalseIfx,left,size,7);
3867           if(ifx) ifx->generated = 1;
3868           return;
3869         }
3870
3871         if(lit <0x100) {
3872           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3873
3874           //rFalseIfx.condition ^= 1;
3875           //genSkipCond(&rFalseIfx,left,size,7);
3876           //rFalseIfx.condition ^= 1;
3877
3878           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3879           if(rFalseIfx.condition)
3880             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3881           else
3882             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3883
3884           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3885           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3886           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3887
3888           while(size > 1)
3889             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3890
3891           if(rFalseIfx.condition) {
3892             emitSKPZ;
3893             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3894
3895           } else {
3896             emitSKPNZ;
3897           }
3898
3899           genSkipc(&rFalseIfx);
3900           emitpLabel(truelbl->key);
3901           if(ifx) ifx->generated = 1;
3902           return;
3903
3904         }
3905
3906         if(size == 1) {
3907
3908           if( (lit & 0xff) == 0) {
3909             /* lower byte is zero */
3910             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3911             i = ((lit >> 8) & 0xff) ^0x80;
3912             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3913             emitpcode(POC_ADDLW, popGetLit( 0x80));
3914             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3915             genSkipc(&rFalseIfx);
3916
3917
3918             if(ifx) ifx->generated = 1;
3919             return;
3920
3921           }
3922         } else {
3923           /* Special cases for signed longs */
3924           if( (lit & 0xffffff) == 0) {
3925             /* lower byte is zero */
3926             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3927             i = ((lit >> 8*3) & 0xff) ^0x80;
3928             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3929             emitpcode(POC_ADDLW, popGetLit( 0x80));
3930             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3931             genSkipc(&rFalseIfx);
3932
3933
3934             if(ifx) ifx->generated = 1;
3935             return;
3936
3937           }
3938
3939         }
3940
3941
3942         if(lit & (0x80 << (size*8))) {
3943           /* lit is negative */
3944           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3945
3946           //genSkipCond(&rFalseIfx,left,size,7);
3947
3948           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3949
3950           if(rFalseIfx.condition)
3951             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3952           else
3953             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3954
3955
3956         } else {
3957           /* lit is positive */
3958           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3959           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3960           if(rFalseIfx.condition)
3961             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3962           else
3963             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3964
3965         }
3966
3967         /*
3968           This works, but is only good for ints.
3969           It also requires a "known zero" register.
3970           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3971           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3972           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3973           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3974           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3975           genSkipc(&rFalseIfx);
3976
3977           emitpLabel(truelbl->key);
3978           if(ifx) ifx->generated = 1;
3979           return;
3980         **/
3981           
3982         /* There are no more special cases, so perform a general compare */
3983   
3984         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3985         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3986
3987         while(size--) {
3988
3989           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3990           emitSKPNZ;
3991           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3992         }
3993         //rFalseIfx.condition ^= 1;
3994         genSkipc(&rFalseIfx);
3995
3996         emitpLabel(truelbl->key);
3997
3998         if(ifx) ifx->generated = 1;
3999         return;
4000
4001
4002       }
4003
4004
4005       /* sign is out of the way. So now do an unsigned compare */
4006       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4007
4008
4009       /* General case - compare to an unsigned literal on the right.*/
4010
4011       i = (lit >> (size*8)) & 0xff;
4012       emitpcode(POC_MOVLW, popGetLit(i));
4013       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4014       while(size--) {
4015         i = (lit >> (size*8)) & 0xff;
4016
4017         if(i) {
4018           emitpcode(POC_MOVLW, popGetLit(i));
4019           emitSKPNZ;
4020           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4021         } else {
4022           /* this byte of the lit is zero, 
4023            *if it's not the last then OR in the variable */
4024           if(size)
4025             emitpcode(POC_IORFW, popGet(AOP(left),size));
4026         }
4027       }
4028
4029
4030       emitpLabel(lbl->key);
4031       //if(emitFinalCheck)
4032       genSkipc(&rFalseIfx);
4033       if(sign)
4034         emitpLabel(truelbl->key);
4035
4036       if(ifx) ifx->generated = 1;
4037       return;
4038
4039
4040     }
4041 #endif
4042     if(AOP_TYPE(left) == AOP_LIT) {
4043       //symbol *lbl = newiTempLabel(NULL);
4044
4045       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4046
4047
4048       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4049
4050       /* Special cases */
4051       if((lit == 0) && (sign == 0)){
4052
4053         size--;
4054         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4055         while(size) 
4056           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4057
4058         genSkipz2(&rFalseIfx,0);
4059         if(ifx) ifx->generated = 1;
4060         return;
4061       }
4062
4063       if(size==1) {
4064         /* Special cases */
4065         lit &= 0xff;
4066         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4067           /* degenerate compare can never be true */
4068           if(rFalseIfx.condition == 0)
4069             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4070
4071           if(ifx) ifx->generated = 1;
4072           return;
4073         }
4074
4075         if(sign) {
4076           /* signed comparisons to a literal byte */
4077
4078           int lp1 = (lit+1) & 0xff;
4079
4080           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4081           switch (lp1) {
4082           case 0:
4083             rFalseIfx.condition ^= 1;
4084             genSkipCond(&rFalseIfx,right,0,7);
4085             break;
4086           case 0x7f:
4087             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4088             emitpcode(POC_XORLW, popGetLit(0x7f));
4089             genSkipz2(&rFalseIfx,1);
4090             break;
4091           default:
4092             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4093             emitpcode(POC_ADDLW, popGetLit(0x80));
4094             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4095             rFalseIfx.condition ^= 1;
4096             genSkipc(&rFalseIfx);
4097             break;
4098           }
4099         } else {
4100           /* unsigned comparisons to a literal byte */
4101
4102           switch(lit & 0xff ) {
4103           case 0:
4104             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4105             genSkipz2(&rFalseIfx,0);
4106             break;
4107           case 0x7f:
4108             rFalseIfx.condition ^= 1;
4109             genSkipCond(&rFalseIfx,right,0,7);
4110             break;
4111
4112           default:
4113             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4114             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4115             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4116             rFalseIfx.condition ^= 1;
4117             genSkipc(&rFalseIfx);
4118             break;
4119           }
4120         }
4121
4122         if(ifx) ifx->generated = 1;
4123         return;
4124
4125       } else {
4126
4127         /* Size is greater than 1 */
4128
4129         if(sign) {
4130           int lp1 = lit+1;
4131
4132           size--;
4133
4134           if(lp1 == 0) {
4135             /* this means lit = 0xffffffff, or -1 */
4136
4137
4138             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4139             rFalseIfx.condition ^= 1;
4140             genSkipCond(&rFalseIfx,right,size,7);
4141             if(ifx) ifx->generated = 1;
4142             return;
4143           }
4144
4145           if(lit == 0) {
4146             int s = size;
4147
4148             if(rFalseIfx.condition) {
4149               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4150               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4151             }
4152
4153             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4154             while(size--)
4155               emitpcode(POC_IORFW, popGet(AOP(right),size));
4156
4157
4158             emitSKPZ;
4159             if(rFalseIfx.condition) {
4160               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4161               emitpLabel(truelbl->key);
4162             }else {
4163               rFalseIfx.condition ^= 1;
4164               genSkipCond(&rFalseIfx,right,s,7);
4165             }
4166
4167             if(ifx) ifx->generated = 1;
4168             return;
4169           }
4170
4171           if((size == 1) &&  (0 == (lp1&0xff))) {
4172             /* lower byte of signed word is zero */
4173             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4174             i = ((lp1 >> 8) & 0xff) ^0x80;
4175             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4176             emitpcode(POC_ADDLW, popGetLit( 0x80));
4177             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4178             rFalseIfx.condition ^= 1;
4179             genSkipc(&rFalseIfx);
4180
4181
4182             if(ifx) ifx->generated = 1;
4183             return;
4184           }
4185
4186           if(lit & (0x80 << (size*8))) {
4187             /* Lit is less than zero */
4188             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4189             //rFalseIfx.condition ^= 1;
4190             //genSkipCond(&rFalseIfx,left,size,7);
4191             //rFalseIfx.condition ^= 1;
4192             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4193             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4194
4195             if(rFalseIfx.condition)
4196               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4197             else
4198               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4199
4200
4201           } else {
4202             /* Lit is greater than or equal to zero */
4203             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4204             //rFalseIfx.condition ^= 1;
4205             //genSkipCond(&rFalseIfx,right,size,7);
4206             //rFalseIfx.condition ^= 1;
4207
4208             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4209             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4210
4211             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4212             if(rFalseIfx.condition)
4213               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4214             else
4215               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4216
4217           }
4218
4219
4220           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4221           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4222
4223           while(size--) {
4224
4225             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4226             emitSKPNZ;
4227             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4228           }
4229           rFalseIfx.condition ^= 1;
4230           //rFalseIfx.condition = 1;
4231           genSkipc(&rFalseIfx);
4232
4233           emitpLabel(truelbl->key);
4234
4235           if(ifx) ifx->generated = 1;
4236           return;
4237           // end of if (sign)
4238         } else {
4239
4240           /* compare word or long to an unsigned literal on the right.*/
4241
4242
4243           size--;
4244           if(lit < 0xff) {
4245             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4246             switch (lit) {
4247             case 0:
4248               break; /* handled above */
4249 /*
4250             case 0xff:
4251               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4252               while(size--)
4253                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4254               genSkipz2(&rFalseIfx,0);
4255               break;
4256 */
4257             default:
4258               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4259               while(--size)
4260                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4261
4262               emitSKPZ;
4263               if(rFalseIfx.condition)
4264                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4265               else
4266                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4267
4268
4269               emitpcode(POC_MOVLW, popGetLit(lit+1));
4270               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4271
4272               rFalseIfx.condition ^= 1;
4273               genSkipc(&rFalseIfx);
4274             }
4275
4276             emitpLabel(truelbl->key);
4277
4278             if(ifx) ifx->generated = 1;
4279             return;
4280           }
4281
4282
4283           lit++;
4284           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4285           i = (lit >> (size*8)) & 0xff;
4286
4287           emitpcode(POC_MOVLW, popGetLit(i));
4288           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4289
4290           while(size--) {
4291             i = (lit >> (size*8)) & 0xff;
4292
4293             if(i) {
4294               emitpcode(POC_MOVLW, popGetLit(i));
4295               emitSKPNZ;
4296               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4297             } else {
4298               /* this byte of the lit is zero, 
4299                *if it's not the last then OR in the variable */
4300               if(size)
4301                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4302             }
4303           }
4304
4305
4306           emitpLabel(lbl->key);
4307
4308           rFalseIfx.condition ^= 1;
4309           genSkipc(&rFalseIfx);
4310         }
4311
4312         if(sign)
4313           emitpLabel(truelbl->key);
4314         if(ifx) ifx->generated = 1;
4315         return;
4316       }
4317     }
4318     /* Compare two variables */
4319
4320     DEBUGpic14_emitcode(";sign","%d",sign);
4321
4322     size--;
4323     if(sign) {
4324       /* Sigh. thus sucks... */
4325       if(size) {
4326         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4327         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4328         emitpcode(POC_MOVLW, popGetLit(0x80));
4329         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4330         emitpcode(POC_XORFW, popGet(AOP(right),size));
4331         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4332       } else {
4333         /* Signed char comparison */
4334         /* Special thanks to Nikolai Golovchenko for this snippet */
4335         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4336         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4337         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4338         emitpcode(POC_XORFW, popGet(AOP(left),0));
4339         emitpcode(POC_XORFW, popGet(AOP(right),0));
4340         emitpcode(POC_ADDLW, popGetLit(0x80));
4341
4342         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4343         genSkipc(&rFalseIfx);
4344           
4345         if(ifx) ifx->generated = 1;
4346         return;
4347       }
4348
4349     } else {
4350
4351       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4352       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4353     }
4354
4355
4356     /* The rest of the bytes of a multi-byte compare */
4357     while (size) {
4358
4359       emitSKPZ;
4360       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4361       size--;
4362
4363       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4364       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4365
4366
4367     }
4368
4369     emitpLabel(lbl->key);
4370
4371     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4372     genSkipc(&rFalseIfx);
4373     if(ifx) ifx->generated = 1;
4374     return;
4375
4376   }
4377
4378   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4379     pic14_outBitC(result);
4380   } else {
4381     /* if the result is used in the next
4382        ifx conditional branch then generate
4383        code a little differently */
4384     if (ifx )
4385       genIfxJump (ifx,"c");
4386     else
4387       pic14_outBitC(result);
4388     /* leave the result in acc */
4389   }
4390
4391 }
4392
4393 /*-----------------------------------------------------------------*/
4394 /* genCmpGt :- greater than comparison                             */
4395 /*-----------------------------------------------------------------*/
4396 static void genCmpGt (iCode *ic, iCode *ifx)
4397 {
4398     operand *left, *right, *result;
4399     sym_link *letype , *retype;
4400     int sign ;
4401
4402     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4403     left = IC_LEFT(ic);
4404     right= IC_RIGHT(ic);
4405     result = IC_RESULT(ic);
4406
4407     letype = getSpec(operandType(left));
4408     retype =getSpec(operandType(right));
4409     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4410     /* assign the amsops */
4411     aopOp (left,ic,FALSE);
4412     aopOp (right,ic,FALSE);
4413     aopOp (result,ic,TRUE);
4414
4415     genCmp(right, left, result, ifx, sign);
4416
4417     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4418     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4419     freeAsmop(result,NULL,ic,TRUE); 
4420 }
4421
4422 /*-----------------------------------------------------------------*/
4423 /* genCmpLt - less than comparisons                                */
4424 /*-----------------------------------------------------------------*/
4425 static void genCmpLt (iCode *ic, iCode *ifx)
4426 {
4427     operand *left, *right, *result;
4428     sym_link *letype , *retype;
4429     int sign ;
4430
4431     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4432     left = IC_LEFT(ic);
4433     right= IC_RIGHT(ic);
4434     result = IC_RESULT(ic);
4435
4436     letype = getSpec(operandType(left));
4437     retype =getSpec(operandType(right));
4438     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4439
4440     /* assign the amsops */
4441     aopOp (left,ic,FALSE);
4442     aopOp (right,ic,FALSE);
4443     aopOp (result,ic,TRUE);
4444
4445     genCmp(left, right, result, ifx, sign);
4446
4447     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4448     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4449     freeAsmop(result,NULL,ic,TRUE); 
4450 }
4451
4452 /*-----------------------------------------------------------------*/
4453 /* genc16bit2lit - compare a 16 bit value to a literal             */
4454 /*-----------------------------------------------------------------*/
4455 static void genc16bit2lit(operand *op, int lit, int offset)
4456 {
4457   int i;
4458
4459   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4460   if( (lit&0xff) == 0) 
4461     i=1;
4462   else
4463     i=0;
4464
4465   switch( BYTEofLONG(lit,i)) { 
4466   case 0:
4467     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4468     break;
4469   case 1:
4470     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4471     break;
4472   case 0xff:
4473     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4474     break;
4475   default:
4476     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4477     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4478   }
4479
4480   i ^= 1;
4481
4482   switch( BYTEofLONG(lit,i)) { 
4483   case 0:
4484     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4485     break;
4486   case 1:
4487     emitSKPNZ;
4488     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4489     break;
4490   case 0xff:
4491     emitSKPNZ;
4492     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4493     break;
4494   default:
4495     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4496     emitSKPNZ;
4497     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4498
4499   }
4500
4501 }
4502
4503 /*-----------------------------------------------------------------*/
4504 /* gencjneshort - compare and jump if not equal                    */
4505 /*-----------------------------------------------------------------*/
4506 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4507 {
4508   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4509   int offset = 0;
4510   resolvedIfx rIfx;
4511   symbol *lbl;
4512
4513   unsigned long lit = 0L;
4514   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4515   DEBUGpic14_AopType(__LINE__,left,right,NULL);
4516
4517   resolveIfx(&rIfx,ifx);
4518   lbl =  newiTempLabel(NULL);
4519
4520
4521   /* if the left side is a literal or 
4522      if the right is in a pointer register and left 
4523      is not */
4524   if ((AOP_TYPE(left) == AOP_LIT) || 
4525       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4526     operand *t = right;
4527     right = left;
4528     left = t;
4529   }
4530   if(AOP_TYPE(right) == AOP_LIT)
4531     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4532
4533   /* if the right side is a literal then anything goes */
4534   if (AOP_TYPE(right) == AOP_LIT &&
4535       AOP_TYPE(left) != AOP_DIR ) {
4536     switch(size) {
4537     case 2:
4538       genc16bit2lit(left, lit, 0);
4539       emitSKPNZ;
4540       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4541       break;
4542     default:
4543       while (size--) {
4544         if(lit & 0xff) {
4545           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4546           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4547         } else {
4548           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4549         }
4550
4551         emitSKPNZ;
4552         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4553         offset++;
4554         lit >>= 8;
4555       }
4556       break;
4557     }
4558   }
4559
4560   /* if the right side is in a register or in direct space or
4561      if the left is a pointer register & right is not */    
4562   else if (AOP_TYPE(right) == AOP_REG ||
4563            AOP_TYPE(right) == AOP_DIR || 
4564            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4565            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4566     switch(size) {
4567     case 2:
4568       genc16bit2lit(left, lit, 0);
4569       emitSKPNZ;
4570       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4571       break;
4572     default:
4573       while (size--) {
4574         int emit_skip=1;
4575         if((AOP_TYPE(left) == AOP_DIR) && 
4576            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4577
4578           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4579           emitpcode(POC_XORFW,popGet(AOP(right),offset));
4580
4581         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4582             
4583           switch (lit & 0xff) {
4584           case 0:
4585             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4586             break;
4587           case 1:
4588             emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4589             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4590             emit_skip=0;
4591             break;
4592           case 0xff:
4593             emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4594             emitpcode(POC_GOTO,popGetLabel(lbl->key));
4595             emit_skip=0;
4596             break;
4597           default:
4598             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4599             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4600           }
4601           lit >>= 8;
4602
4603         } else {
4604           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4605         }
4606         if(emit_skip) {
4607           if(AOP_TYPE(result) == AOP_CRY) {
4608             pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4609             if(rIfx.condition)
4610               emitSKPNZ;
4611             else
4612               emitSKPZ;
4613             emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4614           } else {
4615             /* fix me. probably need to check result size too */
4616             emitpcode(POC_CLRF,popGet(AOP(result),0));
4617             if(rIfx.condition)
4618               emitSKPNZ;
4619             else
4620               emitSKPZ;
4621             emitpcode(POC_INCF,popGet(AOP(result),0));
4622           }
4623           if(ifx)
4624             ifx->generated=1;
4625         }
4626         emit_skip++;
4627         offset++;
4628       }
4629       break;
4630     }
4631   } else if(AOP_TYPE(right) == AOP_REG &&
4632             AOP_TYPE(left) != AOP_DIR){
4633
4634     while(size--) {
4635       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4636       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4637       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4638       if(rIfx.condition)
4639         emitSKPNZ;
4640       else
4641         emitSKPZ;
4642       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4643       offset++;
4644     }
4645       
4646   }else{
4647     /* right is a pointer reg need both a & b */
4648     while(size--) {
4649       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4650       if(strcmp(l,"b"))
4651         pic14_emitcode("mov","b,%s",l);
4652       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4653       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4654       offset++;
4655     }
4656   }
4657   emitpLabel(lbl->key);
4658
4659   if(ifx)
4660     ifx->generated = 1;
4661 }
4662
4663 #if 0
4664 /*-----------------------------------------------------------------*/
4665 /* gencjne - compare and jump if not equal                         */
4666 /*-----------------------------------------------------------------*/
4667 static void gencjne(operand *left, operand *right, iCode *ifx)
4668 {
4669     symbol *tlbl  = newiTempLabel(NULL);
4670
4671     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4672     gencjneshort(left, right, lbl);
4673
4674     pic14_emitcode("mov","a,%s",one);
4675     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4676     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4677     pic14_emitcode("clr","a");
4678     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4679
4680     emitpLabel(lbl->key);
4681     emitpLabel(tlbl->key);
4682
4683 }
4684 #endif
4685
4686 /*-----------------------------------------------------------------*/
4687 /* genCmpEq - generates code for equal to                          */
4688 /*-----------------------------------------------------------------*/
4689 static void genCmpEq (iCode *ic, iCode *ifx)
4690 {
4691     operand *left, *right, *result;
4692     unsigned long lit = 0L;
4693     int size,offset=0;
4694
4695     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4696
4697     if(ifx)
4698       DEBUGpic14_emitcode ("; ifx is non-null","");
4699     else
4700       DEBUGpic14_emitcode ("; ifx is null","");
4701
4702     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4703     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4704     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4705
4706     size = max(AOP_SIZE(left),AOP_SIZE(right));
4707
4708     DEBUGpic14_AopType(__LINE__,left,right,result);
4709
4710     /* if literal, literal on the right or 
4711     if the right is in a pointer register and left 
4712     is not */
4713     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4714         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4715       operand *tmp = right ;
4716       right = left;
4717       left = tmp;
4718     }
4719
4720
4721     if(ifx && !AOP_SIZE(result)){
4722         symbol *tlbl;
4723         /* if they are both bit variables */
4724         if (AOP_TYPE(left) == AOP_CRY &&
4725             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4726             if(AOP_TYPE(right) == AOP_LIT){
4727                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4728                 if(lit == 0L){
4729                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4730                     pic14_emitcode("cpl","c");
4731                 } else if(lit == 1L) {
4732                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4733                 } else {
4734                     pic14_emitcode("clr","c");
4735                 }
4736                 /* AOP_TYPE(right) == AOP_CRY */
4737             } else {
4738                 symbol *lbl = newiTempLabel(NULL);
4739                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4740                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4741                 pic14_emitcode("cpl","c");
4742                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4743             }
4744             /* if true label then we jump if condition
4745             supplied is true */
4746             tlbl = newiTempLabel(NULL);
4747             if ( IC_TRUE(ifx) ) {
4748                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4749                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4750             } else {
4751                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4752                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4753             }
4754             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4755
4756             {
4757               /* left and right are both bit variables, result is carry */
4758               resolvedIfx rIfx;
4759               
4760               resolveIfx(&rIfx,ifx);
4761
4762               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4763               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4764               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4765               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4766               genSkipz2(&rIfx,0);
4767             }
4768         } else {
4769
4770           /* They're not both bit variables. Is the right a literal? */
4771           if(AOP_TYPE(right) == AOP_LIT) {
4772             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4773             
4774             switch(size) {
4775
4776             case 1:
4777               switch(lit & 0xff) {
4778               case 1:
4779                 if ( IC_TRUE(ifx) ) {
4780                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4781                   emitSKPNZ;
4782                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4783                 } else {
4784                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4785                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4786                 }
4787                 break;
4788               case 0xff:
4789                 if ( IC_TRUE(ifx) ) {
4790                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4791                   emitSKPNZ;
4792                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4793                 } else {
4794                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4795                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4796                 }
4797                 break;
4798               default:
4799                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4800                 if(lit)
4801                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4802                 genSkip(ifx,'z');
4803               }
4804
4805
4806               /* end of size == 1 */
4807               break;
4808               
4809             case 2:
4810               genc16bit2lit(left,lit,offset);
4811               genSkip(ifx,'z');
4812               break;
4813               /* end of size == 2 */
4814
4815             default:
4816               /* size is 4 */
4817               if(lit==0) {
4818                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4819                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4820                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4821                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4822
4823               } else {
4824
4825                 /* search for patterns that can be optimized */
4826
4827                 genc16bit2lit(left,lit,0);
4828                 lit >>= 16;
4829                 if(lit) {
4830                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4831                   //genSkip(ifx,'z');
4832                   genc16bit2lit(left,lit,2);
4833                 } else {
4834                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4835                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4836
4837                 }
4838                 
4839               }
4840
4841               genSkip(ifx,'z');
4842             }
4843           
4844             ifx->generated = 1;
4845             goto release ;
4846             
4847
4848           } else if(AOP_TYPE(right) == AOP_CRY ) {
4849             /* we know the left is not a bit, but that the right is */
4850             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4851             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4852                       popGet(AOP(right),offset));
4853             emitpcode(POC_XORLW,popGetLit(1));
4854
4855             /* if the two are equal, then W will be 0 and the Z bit is set
4856              * we could test Z now, or go ahead and check the high order bytes if
4857              * the variable we're comparing is larger than a byte. */
4858
4859             while(--size)
4860               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4861
4862             if ( IC_TRUE(ifx) ) {
4863               emitSKPNZ;
4864               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4865               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4866             } else {
4867               emitSKPZ;
4868               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4869               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4870             }
4871
4872           } else {
4873             /* They're both variables that are larger than bits */
4874             int s = size;
4875
4876             tlbl = newiTempLabel(NULL);
4877
4878             while(size--) {
4879               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4880               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4881
4882               if ( IC_TRUE(ifx) ) {
4883                 if(size) {
4884                   emitSKPZ;
4885                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4886                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4887                 } else {
4888                   emitSKPNZ;
4889                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4890                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4891                 }
4892               } else {
4893                 emitSKPZ;
4894                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4895                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4896               }
4897               offset++;
4898             }
4899             if(s>1 && IC_TRUE(ifx)) {
4900               emitpLabel(tlbl->key);
4901               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4902             }
4903           }
4904         }
4905         /* mark the icode as generated */
4906         ifx->generated = 1;
4907         goto release ;
4908     }
4909
4910     /* if they are both bit variables */
4911     if (AOP_TYPE(left) == AOP_CRY &&
4912         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4913         if(AOP_TYPE(right) == AOP_LIT){
4914             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4915             if(lit == 0L){
4916                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4917                 pic14_emitcode("cpl","c");
4918             } else if(lit == 1L) {
4919                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4920             } else {
4921                 pic14_emitcode("clr","c");
4922             }
4923             /* AOP_TYPE(right) == AOP_CRY */
4924         } else {
4925             symbol *lbl = newiTempLabel(NULL);
4926             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4927             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4928             pic14_emitcode("cpl","c");
4929             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4930         }
4931         /* c = 1 if egal */
4932         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4933             pic14_outBitC(result);
4934             goto release ;
4935         }
4936         if (ifx) {
4937             genIfxJump (ifx,"c");
4938             goto release ;
4939         }
4940         /* if the result is used in an arithmetic operation
4941         then put the result in place */
4942         pic14_outBitC(result);
4943     } else {
4944       
4945       gencjne(left,right,result,ifx);
4946 /*
4947       if(ifx) 
4948         gencjne(left,right,newiTempLabel(NULL));
4949       else {
4950         if(IC_TRUE(ifx)->key)
4951           gencjne(left,right,IC_TRUE(ifx)->key);
4952         else
4953           gencjne(left,right,IC_FALSE(ifx)->key);
4954         ifx->generated = 1;
4955         goto release ;
4956       }
4957       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4958         aopPut(AOP(result),"a",0);
4959         goto release ;
4960       }
4961
4962       if (ifx) {
4963         genIfxJump (ifx,"a");
4964         goto release ;
4965       }
4966 */
4967       /* if the result is used in an arithmetic operation
4968          then put the result in place */
4969 /*
4970       if (AOP_TYPE(result) != AOP_CRY) 
4971         pic14_outAcc(result);
4972 */
4973       /* leave the result in acc */
4974     }
4975
4976 release:
4977     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4978     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4979     freeAsmop(result,NULL,ic,TRUE);
4980 }
4981
4982 /*-----------------------------------------------------------------*/
4983 /* ifxForOp - returns the icode containing the ifx for operand     */
4984 /*-----------------------------------------------------------------*/
4985 static iCode *ifxForOp ( operand *op, iCode *ic )
4986 {
4987     /* if true symbol then needs to be assigned */
4988     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4989     if (IS_TRUE_SYMOP(op))
4990         return NULL ;
4991
4992     /* if this has register type condition and
4993     the next instruction is ifx with the same operand
4994     and live to of the operand is upto the ifx only then */
4995     if (ic->next &&
4996         ic->next->op == IFX &&
4997         IC_COND(ic->next)->key == op->key &&
4998         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4999         return ic->next;
5000
5001     if (ic->next &&
5002         ic->next->op == IFX &&
5003         IC_COND(ic->next)->key == op->key) {
5004       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5005       return ic->next;
5006     }
5007
5008     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5009     if (ic->next &&
5010         ic->next->op == IFX)
5011       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5012
5013     if (ic->next &&
5014         ic->next->op == IFX &&
5015         IC_COND(ic->next)->key == op->key) {
5016       DEBUGpic14_emitcode ("; "," key is okay");
5017       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5018                            OP_SYMBOL(op)->liveTo,
5019                            ic->next->seq);
5020     }
5021
5022
5023     return NULL;
5024 }
5025 /*-----------------------------------------------------------------*/
5026 /* genAndOp - for && operation                                     */
5027 /*-----------------------------------------------------------------*/
5028 static void genAndOp (iCode *ic)
5029 {
5030     operand *left,*right, *result;
5031     symbol *tlbl;
5032
5033     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5034     /* note here that && operations that are in an
5035     if statement are taken away by backPatchLabels
5036     only those used in arthmetic operations remain */
5037     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5038     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5039     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5040
5041     /* if both are bit variables */
5042     if (AOP_TYPE(left) == AOP_CRY &&
5043         AOP_TYPE(right) == AOP_CRY ) {
5044         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5045         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5046         pic14_outBitC(result);
5047     } else {
5048         tlbl = newiTempLabel(NULL);
5049         pic14_toBoolean(left);    
5050         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5051         pic14_toBoolean(right);
5052         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5053         pic14_outBitAcc(result);
5054     }
5055
5056     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5057     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5058     freeAsmop(result,NULL,ic,TRUE);
5059 }
5060
5061
5062 /*-----------------------------------------------------------------*/
5063 /* genOrOp - for || operation                                      */
5064 /*-----------------------------------------------------------------*/
5065 /*
5066   tsd pic port -
5067   modified this code, but it doesn't appear to ever get called
5068 */
5069
5070 static void genOrOp (iCode *ic)
5071 {
5072     operand *left,*right, *result;
5073     symbol *tlbl;
5074
5075     /* note here that || operations that are in an
5076     if statement are taken away by backPatchLabels
5077     only those used in arthmetic operations remain */
5078     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5079     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5080     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5081     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5082
5083     DEBUGpic14_AopType(__LINE__,left,right,result);
5084
5085     /* if both are bit variables */
5086     if (AOP_TYPE(left) == AOP_CRY &&
5087         AOP_TYPE(right) == AOP_CRY ) {
5088       pic14_emitcode("clrc","");
5089       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5090                AOP(left)->aopu.aop_dir,
5091                AOP(left)->aopu.aop_dir);
5092       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5093                AOP(right)->aopu.aop_dir,
5094                AOP(right)->aopu.aop_dir);
5095       pic14_emitcode("setc","");
5096
5097     } else {
5098         tlbl = newiTempLabel(NULL);
5099         pic14_toBoolean(left);
5100         emitSKPZ;
5101         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5102         pic14_toBoolean(right);
5103         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5104
5105         pic14_outBitAcc(result);
5106     }
5107
5108     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5109     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110     freeAsmop(result,NULL,ic,TRUE);            
5111 }
5112
5113 /*-----------------------------------------------------------------*/
5114 /* isLiteralBit - test if lit == 2^n                               */
5115 /*-----------------------------------------------------------------*/
5116 static int isLiteralBit(unsigned long lit)
5117 {
5118     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5119     0x100L,0x200L,0x400L,0x800L,
5120     0x1000L,0x2000L,0x4000L,0x8000L,
5121     0x10000L,0x20000L,0x40000L,0x80000L,
5122     0x100000L,0x200000L,0x400000L,0x800000L,
5123     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5124     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5125     int idx;
5126     
5127     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5128     for(idx = 0; idx < 32; idx++)
5129         if(lit == pw[idx])
5130             return idx+1;
5131     return 0;
5132 }
5133
5134 /*-----------------------------------------------------------------*/
5135 /* continueIfTrue -                                                */
5136 /*-----------------------------------------------------------------*/
5137 static void continueIfTrue (iCode *ic)
5138 {
5139     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5140     if(IC_TRUE(ic))
5141         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5142     ic->generated = 1;
5143 }
5144
5145 /*-----------------------------------------------------------------*/
5146 /* jmpIfTrue -                                                     */
5147 /*-----------------------------------------------------------------*/
5148 static void jumpIfTrue (iCode *ic)
5149 {
5150     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5151     if(!IC_TRUE(ic))
5152         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5153     ic->generated = 1;
5154 }
5155
5156 /*-----------------------------------------------------------------*/
5157 /* jmpTrueOrFalse -                                                */
5158 /*-----------------------------------------------------------------*/
5159 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5160 {
5161     // ugly but optimized by peephole
5162     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5163     if(IC_TRUE(ic)){
5164         symbol *nlbl = newiTempLabel(NULL);
5165         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5166         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5167         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5168         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5169     }
5170     else{
5171         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5172         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5173     }
5174     ic->generated = 1;
5175 }
5176
5177 /*-----------------------------------------------------------------*/
5178 /* genAnd  - code for and                                          */
5179 /*-----------------------------------------------------------------*/
5180 static void genAnd (iCode *ic, iCode *ifx)
5181 {
5182   operand *left, *right, *result;
5183   int size, offset=0;  
5184   unsigned long lit = 0L;
5185   int bytelit = 0;
5186   resolvedIfx rIfx;
5187
5188
5189   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5190   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5191   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5192   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5193
5194   resolveIfx(&rIfx,ifx);
5195
5196   /* if left is a literal & right is not then exchange them */
5197   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5198       AOP_NEEDSACC(left)) {
5199     operand *tmp = right ;
5200     right = left;
5201     left = tmp;
5202   }
5203
5204   /* if result = right then exchange them */
5205   if(pic14_sameRegs(AOP(result),AOP(right))){
5206     operand *tmp = right ;
5207     right = left;
5208     left = tmp;
5209   }
5210
5211   /* if right is bit then exchange them */
5212   if (AOP_TYPE(right) == AOP_CRY &&
5213       AOP_TYPE(left) != AOP_CRY){
5214     operand *tmp = right ;
5215     right = left;
5216     left = tmp;
5217   }
5218   if(AOP_TYPE(right) == AOP_LIT)
5219     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5220
5221   size = AOP_SIZE(result);
5222
5223   DEBUGpic14_AopType(__LINE__,left,right,result);
5224
5225   // if(bit & yy)
5226   // result = bit & yy;
5227   if (AOP_TYPE(left) == AOP_CRY){
5228     // c = bit & literal;
5229     if(AOP_TYPE(right) == AOP_LIT){
5230       if(lit & 1) {
5231         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5232           // no change
5233           goto release;
5234         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5235       } else {
5236         // bit(result) = 0;
5237         if(size && (AOP_TYPE(result) == AOP_CRY)){
5238           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5239           goto release;
5240         }
5241         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5242           jumpIfTrue(ifx);
5243           goto release;
5244         }
5245         pic14_emitcode("clr","c");
5246       }
5247     } else {
5248       if (AOP_TYPE(right) == AOP_CRY){
5249         // c = bit & bit;
5250         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5251         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5252       } else {
5253         // c = bit & val;
5254         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5255         // c = lsb
5256         pic14_emitcode("rrc","a");
5257         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5258       }
5259     }
5260     // bit = c
5261     // val = c
5262     if(size)
5263       pic14_outBitC(result);
5264     // if(bit & ...)
5265     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5266       genIfxJump(ifx, "c");           
5267     goto release ;
5268   }
5269
5270   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5271   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5272   if((AOP_TYPE(right) == AOP_LIT) &&
5273      (AOP_TYPE(result) == AOP_CRY) &&
5274      (AOP_TYPE(left) != AOP_CRY)){
5275     int posbit = isLiteralBit(lit);
5276     /* left &  2^n */
5277     if(posbit){
5278       posbit--;
5279       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5280       // bit = left & 2^n
5281       if(size)
5282         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5283       // if(left &  2^n)
5284       else{
5285         if(ifx){
5286 /*
5287           if(IC_TRUE(ifx)) {
5288             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5289             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5290           } else {
5291             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5292             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5293           }
5294 */
5295           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5296                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5297           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5298           
5299           ifx->generated = 1;
5300         }
5301         goto release;
5302       }
5303     } else {
5304       symbol *tlbl = newiTempLabel(NULL);
5305       int sizel = AOP_SIZE(left);
5306       if(size)
5307         pic14_emitcode("setb","c");
5308       while(sizel--){
5309         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5310           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5311           // byte ==  2^n ?
5312           if((posbit = isLiteralBit(bytelit)) != 0)
5313             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5314           else{
5315             if(bytelit != 0x0FFL)
5316               pic14_emitcode("anl","a,%s",
5317                              aopGet(AOP(right),offset,FALSE,TRUE));
5318             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5319           }
5320         }
5321         offset++;
5322       }
5323       // bit = left & literal
5324       if(size){
5325         pic14_emitcode("clr","c");
5326         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5327       }
5328       // if(left & literal)
5329       else{
5330         if(ifx)
5331           jmpTrueOrFalse(ifx, tlbl);
5332         goto release ;
5333       }
5334     }
5335     pic14_outBitC(result);
5336     goto release ;
5337   }
5338
5339   /* if left is same as result */
5340   if(pic14_sameRegs(AOP(result),AOP(left))){
5341     int know_W = -1;
5342     for(;size--; offset++,lit>>=8) {
5343       if(AOP_TYPE(right) == AOP_LIT){
5344         switch(lit & 0xff) {
5345         case 0x00:
5346           /*  and'ing with 0 has clears the result */
5347           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5348           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5349           break;
5350         case 0xff:
5351           /* and'ing with 0xff is a nop when the result and left are the same */
5352           break;
5353
5354         default:
5355           {
5356             int p = my_powof2( (~lit) & 0xff );
5357             if(p>=0) {
5358               /* only one bit is set in the literal, so use a bcf instruction */
5359               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5360               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5361
5362             } else {
5363               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5364               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5365               if(know_W != (lit&0xff))
5366                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5367               know_W = lit &0xff;
5368               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5369             }
5370           }    
5371         }
5372       } else {
5373         if (AOP_TYPE(left) == AOP_ACC) {
5374           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5375         } else {                    
5376           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5377           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5378
5379         }
5380       }
5381     }
5382
5383   } else {
5384     // left & result in different registers
5385     if(AOP_TYPE(result) == AOP_CRY){
5386       // result = bit
5387       // if(size), result in bit
5388       // if(!size && ifx), conditional oper: if(left & right)
5389       symbol *tlbl = newiTempLabel(NULL);
5390       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5391       if(size)
5392         pic14_emitcode("setb","c");
5393       while(sizer--){
5394         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5395         pic14_emitcode("anl","a,%s",
5396                        aopGet(AOP(left),offset,FALSE,FALSE));
5397         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5398         offset++;
5399       }
5400       if(size){
5401         CLRC;
5402         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5403         pic14_outBitC(result);
5404       } else if(ifx)
5405         jmpTrueOrFalse(ifx, tlbl);
5406     } else {
5407       for(;(size--);offset++) {
5408         // normal case
5409         // result = left & right
5410         if(AOP_TYPE(right) == AOP_LIT){
5411           int t = (lit >> (offset*8)) & 0x0FFL;
5412           switch(t) { 
5413           case 0x00:
5414             pic14_emitcode("clrf","%s",
5415                            aopGet(AOP(result),offset,FALSE,FALSE));
5416             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5417             break;
5418           case 0xff:
5419             pic14_emitcode("movf","%s,w",
5420                            aopGet(AOP(left),offset,FALSE,FALSE));
5421             pic14_emitcode("movwf","%s",
5422                            aopGet(AOP(result),offset,FALSE,FALSE));
5423             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5424             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5425             break;
5426           default:
5427             pic14_emitcode("movlw","0x%x",t);
5428             pic14_emitcode("andwf","%s,w",
5429                            aopGet(AOP(left),offset,FALSE,FALSE));
5430             pic14_emitcode("movwf","%s",
5431                            aopGet(AOP(result),offset,FALSE,FALSE));
5432               
5433             emitpcode(POC_MOVLW, popGetLit(t));
5434             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5435             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5436           }
5437           continue;
5438         }
5439
5440         if (AOP_TYPE(left) == AOP_ACC) {
5441           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5442           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5443         } else {
5444           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5445           pic14_emitcode("andwf","%s,w",
5446                          aopGet(AOP(left),offset,FALSE,FALSE));
5447           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5448           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5449         }
5450         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5451         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5452       }
5453     }
5454   }
5455
5456   release :
5457     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5458   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5459   freeAsmop(result,NULL,ic,TRUE);     
5460 }
5461
5462 /*-----------------------------------------------------------------*/
5463 /* genOr  - code for or                                            */
5464 /*-----------------------------------------------------------------*/
5465 static void genOr (iCode *ic, iCode *ifx)
5466 {
5467     operand *left, *right, *result;
5468     int size, offset=0;
5469     unsigned long lit = 0L;
5470
5471     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5472
5473     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5474     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5475     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5476
5477     DEBUGpic14_AopType(__LINE__,left,right,result);
5478
5479     /* if left is a literal & right is not then exchange them */
5480     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5481         AOP_NEEDSACC(left)) {
5482         operand *tmp = right ;
5483         right = left;
5484         left = tmp;
5485     }
5486
5487     /* if result = right then exchange them */
5488     if(pic14_sameRegs(AOP(result),AOP(right))){
5489         operand *tmp = right ;
5490         right = left;
5491         left = tmp;
5492     }
5493
5494     /* if right is bit then exchange them */
5495     if (AOP_TYPE(right) == AOP_CRY &&
5496         AOP_TYPE(left) != AOP_CRY){
5497         operand *tmp = right ;
5498         right = left;
5499         left = tmp;
5500     }
5501
5502     DEBUGpic14_AopType(__LINE__,left,right,result);
5503
5504     if(AOP_TYPE(right) == AOP_LIT)
5505         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5506
5507     size = AOP_SIZE(result);
5508
5509     // if(bit | yy)
5510     // xx = bit | yy;
5511     if (AOP_TYPE(left) == AOP_CRY){
5512         if(AOP_TYPE(right) == AOP_LIT){
5513             // c = bit & literal;
5514             if(lit){
5515                 // lit != 0 => result = 1
5516                 if(AOP_TYPE(result) == AOP_CRY){
5517                   if(size)
5518                     emitpcode(POC_BSF, popGet(AOP(result),0));
5519                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5520                   //     AOP(result)->aopu.aop_dir,
5521                   //     AOP(result)->aopu.aop_dir);
5522                     else if(ifx)
5523                         continueIfTrue(ifx);
5524                     goto release;
5525                 }
5526             } else {
5527                 // lit == 0 => result = left
5528                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5529                     goto release;
5530                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5531             }
5532         } else {
5533             if (AOP_TYPE(right) == AOP_CRY){
5534               if(pic14_sameRegs(AOP(result),AOP(left))){
5535                 // c = bit | bit;
5536                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5537                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5538                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5539
5540                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5541                          AOP(result)->aopu.aop_dir,
5542                          AOP(result)->aopu.aop_dir);
5543                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5544                          AOP(right)->aopu.aop_dir,
5545                          AOP(right)->aopu.aop_dir);
5546                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5547                          AOP(result)->aopu.aop_dir,
5548                          AOP(result)->aopu.aop_dir);
5549               } else {
5550                 if( AOP_TYPE(result) == AOP_ACC) {
5551                   emitpcode(POC_MOVLW, popGetLit(0));
5552                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5553                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5554                   emitpcode(POC_MOVLW, popGetLit(1));
5555
5556                 } else {
5557
5558                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5559                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5560                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5561                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5562
5563                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5564                                  AOP(result)->aopu.aop_dir,
5565                                  AOP(result)->aopu.aop_dir);
5566                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5567                                  AOP(right)->aopu.aop_dir,
5568                                  AOP(right)->aopu.aop_dir);
5569                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5570                                  AOP(left)->aopu.aop_dir,
5571                                  AOP(left)->aopu.aop_dir);
5572                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5573                                  AOP(result)->aopu.aop_dir,
5574                                  AOP(result)->aopu.aop_dir);
5575                 }
5576               }
5577             } else {
5578                 // c = bit | val;
5579                 symbol *tlbl = newiTempLabel(NULL);
5580                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5581
5582
5583                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5584                 if( AOP_TYPE(right) == AOP_ACC) {
5585                   emitpcode(POC_IORLW, popGetLit(0));
5586                   emitSKPNZ;
5587                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5588                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5589                 }
5590
5591
5592
5593                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5594                     pic14_emitcode(";XXX setb","c");
5595                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5596                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5597                 pic14_toBoolean(right);
5598                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5599                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5600                     jmpTrueOrFalse(ifx, tlbl);
5601                     goto release;
5602                 } else {
5603                     CLRC;
5604                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5605                 }
5606             }
5607         }
5608         // bit = c
5609         // val = c
5610         if(size)
5611             pic14_outBitC(result);
5612         // if(bit | ...)
5613         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5614             genIfxJump(ifx, "c");           
5615         goto release ;
5616     }
5617
5618     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5619     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5620     if((AOP_TYPE(right) == AOP_LIT) &&
5621        (AOP_TYPE(result) == AOP_CRY) &&
5622        (AOP_TYPE(left) != AOP_CRY)){
5623         if(lit){
5624           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5625             // result = 1
5626             if(size)
5627                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5628             else 
5629                 continueIfTrue(ifx);
5630             goto release;
5631         } else {
5632           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5633             // lit = 0, result = boolean(left)
5634             if(size)
5635                 pic14_emitcode(";XXX setb","c");
5636             pic14_toBoolean(right);
5637             if(size){
5638                 symbol *tlbl = newiTempLabel(NULL);
5639                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5640                 CLRC;
5641                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5642             } else {
5643                 genIfxJump (ifx,"a");
5644                 goto release;
5645             }
5646         }
5647         pic14_outBitC(result);
5648         goto release ;
5649     }
5650
5651     /* if left is same as result */
5652     if(pic14_sameRegs(AOP(result),AOP(left))){
5653       int know_W = -1;
5654       for(;size--; offset++,lit>>=8) {
5655         if(AOP_TYPE(right) == AOP_LIT){
5656           if((lit & 0xff) == 0)
5657             /*  or'ing with 0 has no effect */
5658             continue;
5659           else {
5660             int p = my_powof2(lit & 0xff);
5661             if(p>=0) {
5662               /* only one bit is set in the literal, so use a bsf instruction */
5663               emitpcode(POC_BSF,
5664                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5665             } else {
5666               if(know_W != (lit & 0xff))
5667                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5668               know_W = lit & 0xff;
5669               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5670             }
5671                     
5672           }
5673         } else {
5674           if (AOP_TYPE(left) == AOP_ACC) {
5675             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5676             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5677           } else {                  
5678             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5679             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5680
5681             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5682             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5683
5684           }
5685         }
5686       }
5687     } else {
5688         // left & result in different registers
5689         if(AOP_TYPE(result) == AOP_CRY){
5690             // result = bit
5691             // if(size), result in bit
5692             // if(!size && ifx), conditional oper: if(left | right)
5693             symbol *tlbl = newiTempLabel(NULL);
5694             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5695             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5696
5697
5698             if(size)
5699                 pic14_emitcode(";XXX setb","c");
5700             while(sizer--){
5701                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5702                 pic14_emitcode(";XXX orl","a,%s",
5703                          aopGet(AOP(left),offset,FALSE,FALSE));
5704                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5705                 offset++;
5706             }
5707             if(size){
5708                 CLRC;
5709                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5710                 pic14_outBitC(result);
5711             } else if(ifx)
5712                 jmpTrueOrFalse(ifx, tlbl);
5713         } else for(;(size--);offset++){
5714           // normal case
5715           // result = left & right
5716           if(AOP_TYPE(right) == AOP_LIT){
5717             int t = (lit >> (offset*8)) & 0x0FFL;
5718             switch(t) { 
5719             case 0x00:
5720               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5721               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5722
5723               pic14_emitcode("movf","%s,w",
5724                        aopGet(AOP(left),offset,FALSE,FALSE));
5725               pic14_emitcode("movwf","%s",
5726                        aopGet(AOP(result),offset,FALSE,FALSE));
5727               break;
5728             default:
5729               emitpcode(POC_MOVLW,  popGetLit(t));
5730               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5731               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5732
5733               pic14_emitcode("movlw","0x%x",t);
5734               pic14_emitcode("iorwf","%s,w",
5735                        aopGet(AOP(left),offset,FALSE,FALSE));
5736               pic14_emitcode("movwf","%s",
5737                        aopGet(AOP(result),offset,FALSE,FALSE));
5738               
5739             }
5740             continue;
5741           }
5742
5743           // faster than result <- left, anl result,right
5744           // and better if result is SFR
5745           if (AOP_TYPE(left) == AOP_ACC) {
5746             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5747             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5748           } else {
5749             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5750             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5751
5752             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5753             pic14_emitcode("iorwf","%s,w",
5754                      aopGet(AOP(left),offset,FALSE,FALSE));
5755           }
5756           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5757           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5758         }
5759     }
5760
5761 release :
5762     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5763     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5764     freeAsmop(result,NULL,ic,TRUE);     
5765 }
5766
5767 /*-----------------------------------------------------------------*/
5768 /* genXor - code for xclusive or                                   */
5769 /*-----------------------------------------------------------------*/
5770 static void genXor (iCode *ic, iCode *ifx)
5771 {
5772   operand *left, *right, *result;
5773   int size, offset=0;
5774   unsigned long lit = 0L;
5775
5776   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5777
5778   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5779   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5780   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5781
5782   /* if left is a literal & right is not ||
5783      if left needs acc & right does not */
5784   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5785       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5786     operand *tmp = right ;
5787     right = left;
5788     left = tmp;
5789   }
5790
5791   /* if result = right then exchange them */
5792   if(pic14_sameRegs(AOP(result),AOP(right))){
5793     operand *tmp = right ;
5794     right = left;
5795     left = tmp;
5796   }
5797
5798   /* if right is bit then exchange them */
5799   if (AOP_TYPE(right) == AOP_CRY &&
5800       AOP_TYPE(left) != AOP_CRY){
5801     operand *tmp = right ;
5802     right = left;
5803     left = tmp;
5804   }
5805   if(AOP_TYPE(right) == AOP_LIT)
5806     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5807
5808   size = AOP_SIZE(result);
5809
5810   // if(bit ^ yy)
5811   // xx = bit ^ yy;
5812   if (AOP_TYPE(left) == AOP_CRY){
5813     if(AOP_TYPE(right) == AOP_LIT){
5814       // c = bit & literal;
5815       if(lit>>1){
5816         // lit>>1  != 0 => result = 1
5817         if(AOP_TYPE(result) == AOP_CRY){
5818           if(size)
5819             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5820             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5821           else if(ifx)
5822             continueIfTrue(ifx);
5823           goto release;
5824         }
5825         pic14_emitcode("setb","c");
5826       } else{
5827         // lit == (0 or 1)
5828         if(lit == 0){
5829           // lit == 0, result = left
5830           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5831             goto release;
5832           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5833         } else{
5834           // lit == 1, result = not(left)
5835           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5836             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5837             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5838             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5839             goto release;
5840           } else {
5841             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5842             pic14_emitcode("cpl","c");
5843           }
5844         }
5845       }
5846
5847     } else {
5848       // right != literal
5849       symbol *tlbl = newiTempLabel(NULL);
5850       if (AOP_TYPE(right) == AOP_CRY){
5851         // c = bit ^ bit;
5852         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5853       }
5854       else{
5855         int sizer = AOP_SIZE(right);
5856         // c = bit ^ val
5857         // if val>>1 != 0, result = 1
5858         pic14_emitcode("setb","c");
5859         while(sizer){
5860           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5861           if(sizer == 1)
5862             // test the msb of the lsb
5863             pic14_emitcode("anl","a,#0xfe");
5864           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5865           sizer--;
5866         }
5867         // val = (0,1)
5868         pic14_emitcode("rrc","a");
5869       }
5870       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5871       pic14_emitcode("cpl","c");
5872       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5873     }
5874     // bit = c
5875     // val = c
5876     if(size)
5877       pic14_outBitC(result);
5878     // if(bit | ...)
5879     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5880       genIfxJump(ifx, "c");           
5881     goto release ;
5882   }
5883
5884   if(pic14_sameRegs(AOP(result),AOP(left))){
5885     /* if left is same as result */
5886     for(;size--; offset++) {
5887       if(AOP_TYPE(right) == AOP_LIT){
5888         int t  = (lit >> (offset*8)) & 0x0FFL;
5889         if(t == 0x00L)
5890           continue;
5891         else
5892           if (IS_AOP_PREG(left)) {
5893             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5894             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5895             aopPut(AOP(result),"a",offset);
5896           } else {
5897             emitpcode(POC_MOVLW, popGetLit(t));
5898             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5899             pic14_emitcode("xrl","%s,%s",
5900                            aopGet(AOP(left),offset,FALSE,TRUE),
5901                            aopGet(AOP(right),offset,FALSE,FALSE));
5902           }
5903       } else {
5904         if (AOP_TYPE(left) == AOP_ACC)
5905           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5906         else {
5907           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5908           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5909 /*
5910           if (IS_AOP_PREG(left)) {
5911             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5912             aopPut(AOP(result),"a",offset);
5913           } else
5914             pic14_emitcode("xrl","%s,a",
5915                            aopGet(AOP(left),offset,FALSE,TRUE));
5916 */
5917         }
5918       }
5919     }
5920   } else {
5921     // left & result in different registers
5922     if(AOP_TYPE(result) == AOP_CRY){
5923       // result = bit
5924       // if(size), result in bit
5925       // if(!size && ifx), conditional oper: if(left ^ right)
5926       symbol *tlbl = newiTempLabel(NULL);
5927       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5928       if(size)
5929         pic14_emitcode("setb","c");
5930       while(sizer--){
5931         if((AOP_TYPE(right) == AOP_LIT) &&
5932            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5933           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5934         } else {
5935           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5936           pic14_emitcode("xrl","a,%s",
5937                          aopGet(AOP(left),offset,FALSE,FALSE));
5938         }
5939         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5940         offset++;
5941       }
5942       if(size){
5943         CLRC;
5944         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5945         pic14_outBitC(result);
5946       } else if(ifx)
5947         jmpTrueOrFalse(ifx, tlbl);
5948     } else for(;(size--);offset++){
5949       // normal case
5950       // result = left & right
5951       if(AOP_TYPE(right) == AOP_LIT){
5952         int t = (lit >> (offset*8)) & 0x0FFL;
5953         switch(t) { 
5954         case 0x00:
5955           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5956           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5957           pic14_emitcode("movf","%s,w",
5958                          aopGet(AOP(left),offset,FALSE,FALSE));
5959           pic14_emitcode("movwf","%s",
5960                          aopGet(AOP(result),offset,FALSE,FALSE));
5961           break;
5962         case 0xff:
5963           emitpcode(POC_COMFW,popGet(AOP(left),offset));
5964           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5965           pic14_emitcode("comf","%s,w",
5966                          aopGet(AOP(left),offset,FALSE,FALSE));
5967           pic14_emitcode("movwf","%s",
5968                          aopGet(AOP(result),offset,FALSE,FALSE));
5969           break;
5970         default:
5971           emitpcode(POC_MOVLW, popGetLit(t));
5972           emitpcode(POC_XORFW,popGet(AOP(left),offset));
5973           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5974           pic14_emitcode("movlw","0x%x",t);
5975           pic14_emitcode("xorwf","%s,w",
5976                          aopGet(AOP(left),offset,FALSE,FALSE));
5977           pic14_emitcode("movwf","%s",
5978                          aopGet(AOP(result),offset,FALSE,FALSE));
5979
5980         }
5981         continue;
5982       }
5983
5984       // faster than result <- left, anl result,right
5985       // and better if result is SFR
5986       if (AOP_TYPE(left) == AOP_ACC) {
5987         emitpcode(POC_XORFW,popGet(AOP(right),offset));
5988         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5989       } else {
5990         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5991         emitpcode(POC_XORFW,popGet(AOP(left),offset));
5992         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5993         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5994       }
5995       if ( AOP_TYPE(result) != AOP_ACC){
5996         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5997         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5998       }
5999     }
6000   }
6001
6002   release :
6003     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6004   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6005   freeAsmop(result,NULL,ic,TRUE);     
6006 }
6007
6008 /*-----------------------------------------------------------------*/
6009 /* genInline - write the inline code out                           */
6010 /*-----------------------------------------------------------------*/
6011 static void genInline (iCode *ic)
6012 {
6013     char *buffer, *bp, *bp1;
6014     
6015     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6016
6017     _G.inLine += (!options.asmpeep);
6018
6019     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6020     strcpy(buffer,IC_INLINE(ic));
6021
6022     /* emit each line as a code */
6023     while (*bp) {
6024         if (*bp == '\n') {
6025             *bp++ = '\0';
6026             pic14_emitcode(bp1,"");
6027             addpCode2pBlock(pb,newpCodeInlineP(bp1));
6028             bp1 = bp;
6029         } else {
6030             if (*bp == ':') {
6031                 bp++;
6032                 *bp = '\0';
6033                 bp++;
6034                 pic14_emitcode(bp1,"");
6035                 bp1 = bp;
6036             } else
6037                 bp++;
6038         }
6039     }
6040     if (bp1 != bp) {
6041         pic14_emitcode(bp1,"");
6042         addpCode2pBlock(pb,newpCodeInlineP(bp1));
6043     }
6044     /*     pic14_emitcode("",buffer); */
6045     _G.inLine -= (!options.asmpeep);
6046 }
6047
6048 /*-----------------------------------------------------------------*/
6049 /* genRRC - rotate right with carry                                */
6050 /*-----------------------------------------------------------------*/
6051 static void genRRC (iCode *ic)
6052 {
6053   operand *left , *result ;
6054   int size, offset = 0, same;
6055
6056   /* rotate right with carry */
6057   left = IC_LEFT(ic);
6058   result=IC_RESULT(ic);
6059   aopOp (left,ic,FALSE);
6060   aopOp (result,ic,FALSE);
6061
6062   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6063
6064   same = pic14_sameRegs(AOP(result),AOP(left));
6065
6066   size = AOP_SIZE(result);    
6067
6068   /* get the lsb and put it into the carry */
6069   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6070
6071   offset = 0 ;
6072
6073   while(size--) {
6074
6075     if(same) {
6076       emitpcode(POC_RRF, popGet(AOP(left),offset));
6077     } else {
6078       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6079       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6080     }
6081
6082     offset++;
6083   }
6084
6085   freeAsmop(left,NULL,ic,TRUE);
6086   freeAsmop(result,NULL,ic,TRUE);
6087 }
6088
6089 /*-----------------------------------------------------------------*/
6090 /* genRLC - generate code for rotate left with carry               */
6091 /*-----------------------------------------------------------------*/
6092 static void genRLC (iCode *ic)
6093 {    
6094   operand *left , *result ;
6095   int size, offset = 0;
6096   int same;
6097
6098   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6099   /* rotate right with carry */
6100   left = IC_LEFT(ic);
6101   result=IC_RESULT(ic);
6102   aopOp (left,ic,FALSE);
6103   aopOp (result,ic,FALSE);
6104
6105   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6106
6107   same = pic14_sameRegs(AOP(result),AOP(left));
6108
6109   /* move it to the result */
6110   size = AOP_SIZE(result);    
6111
6112   /* get the msb and put it into the carry */
6113   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6114
6115   offset = 0 ;
6116
6117   while(size--) {
6118
6119     if(same) {
6120       emitpcode(POC_RLF, popGet(AOP(left),offset));
6121     } else {
6122       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6123       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6124     }
6125
6126     offset++;
6127   }
6128
6129
6130   freeAsmop(left,NULL,ic,TRUE);
6131   freeAsmop(result,NULL,ic,TRUE);
6132 }
6133
6134 /*-----------------------------------------------------------------*/
6135 /* genGetHbit - generates code get highest order bit               */
6136 /*-----------------------------------------------------------------*/
6137 static void genGetHbit (iCode *ic)
6138 {
6139     operand *left, *result;
6140     left = IC_LEFT(ic);
6141     result=IC_RESULT(ic);
6142     aopOp (left,ic,FALSE);
6143     aopOp (result,ic,FALSE);
6144
6145     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6146     /* get the highest order byte into a */
6147     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6148     if(AOP_TYPE(result) == AOP_CRY){
6149         pic14_emitcode("rlc","a");
6150         pic14_outBitC(result);
6151     }
6152     else{
6153         pic14_emitcode("rl","a");
6154         pic14_emitcode("anl","a,#0x01");
6155         pic14_outAcc(result);
6156     }
6157
6158
6159     freeAsmop(left,NULL,ic,TRUE);
6160     freeAsmop(result,NULL,ic,TRUE);
6161 }
6162
6163 /*-----------------------------------------------------------------*/
6164 /* AccRol - rotate left accumulator by known count                 */
6165 /*-----------------------------------------------------------------*/
6166 static void AccRol (int shCount)
6167 {
6168     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6169     shCount &= 0x0007;              // shCount : 0..7
6170     switch(shCount){
6171         case 0 :
6172             break;
6173         case 1 :
6174             pic14_emitcode("rl","a");
6175             break;
6176         case 2 :
6177             pic14_emitcode("rl","a");
6178             pic14_emitcode("rl","a");
6179             break;
6180         case 3 :
6181             pic14_emitcode("swap","a");
6182             pic14_emitcode("rr","a");
6183             break;
6184         case 4 :
6185             pic14_emitcode("swap","a");
6186             break;
6187         case 5 :
6188             pic14_emitcode("swap","a");
6189             pic14_emitcode("rl","a");
6190             break;
6191         case 6 :
6192             pic14_emitcode("rr","a");
6193             pic14_emitcode("rr","a");
6194             break;
6195         case 7 :
6196             pic14_emitcode("rr","a");
6197             break;
6198     }
6199 }
6200
6201 /*-----------------------------------------------------------------*/
6202 /* AccLsh - left shift accumulator by known count                  */
6203 /*-----------------------------------------------------------------*/
6204 static void AccLsh (int shCount)
6205 {
6206     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6207     if(shCount != 0){
6208         if(shCount == 1)
6209             pic14_emitcode("add","a,acc");
6210         else 
6211             if(shCount == 2) {
6212             pic14_emitcode("add","a,acc");
6213             pic14_emitcode("add","a,acc");
6214         } else {
6215             /* rotate left accumulator */
6216             AccRol(shCount);
6217             /* and kill the lower order bits */
6218             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6219         }
6220     }
6221 }
6222
6223 /*-----------------------------------------------------------------*/
6224 /* AccRsh - right shift accumulator by known count                 */
6225 /*-----------------------------------------------------------------*/
6226 static void AccRsh (int shCount)
6227 {
6228     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6229     if(shCount != 0){
6230         if(shCount == 1){
6231             CLRC;
6232             pic14_emitcode("rrc","a");
6233         } else {
6234             /* rotate right accumulator */
6235             AccRol(8 - shCount);
6236             /* and kill the higher order bits */
6237             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6238         }
6239     }
6240 }
6241
6242 #if 0
6243 /*-----------------------------------------------------------------*/
6244 /* AccSRsh - signed right shift accumulator by known count                 */
6245 /*-----------------------------------------------------------------*/
6246 static void AccSRsh (int shCount)
6247 {
6248     symbol *tlbl ;
6249     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6250     if(shCount != 0){
6251         if(shCount == 1){
6252             pic14_emitcode("mov","c,acc.7");
6253             pic14_emitcode("rrc","a");
6254         } else if(shCount == 2){
6255             pic14_emitcode("mov","c,acc.7");
6256             pic14_emitcode("rrc","a");
6257             pic14_emitcode("mov","c,acc.7");
6258             pic14_emitcode("rrc","a");
6259         } else {
6260             tlbl = newiTempLabel(NULL);
6261             /* rotate right accumulator */
6262             AccRol(8 - shCount);
6263             /* and kill the higher order bits */
6264             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6265             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6266             pic14_emitcode("orl","a,#0x%02x",
6267                      (unsigned char)~SRMask[shCount]);
6268             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6269         }
6270     }
6271 }
6272 #endif
6273 /*-----------------------------------------------------------------*/
6274 /* shiftR1Left2Result - shift right one byte from left to result   */
6275 /*-----------------------------------------------------------------*/
6276 static void shiftR1Left2ResultSigned (operand *left, int offl,
6277                                 operand *result, int offr,
6278                                 int shCount)
6279 {
6280   int same;
6281
6282   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6283
6284   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6285
6286   switch(shCount) {
6287   case 1:
6288     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6289     if(same) 
6290       emitpcode(POC_RRF, popGet(AOP(result),offr));
6291     else {
6292       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6293       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6294     }
6295
6296     break;
6297   case 2:
6298
6299     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6300     if(same) 
6301       emitpcode(POC_RRF, popGet(AOP(result),offr));
6302     else {
6303       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6304       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6305     }
6306     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6307     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6308
6309     break;
6310
6311   case 3:
6312     if(same)
6313       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6314     else {
6315       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6316       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6317     }
6318
6319     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6320     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6321     emitpcode(POC_ANDLW, popGetLit(0x1f));
6322
6323     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6324     emitpcode(POC_IORLW, popGetLit(0xe0));
6325
6326     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6327     break;
6328
6329   case 4:
6330     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6331     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6332     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6333     emitpcode(POC_IORLW,  popGetLit(0xf0));
6334     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6335     break;
6336   case 5:
6337     if(same) {
6338       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6339     } else {
6340       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6341       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6342     }
6343     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6344     emitpcode(POC_ANDLW,  popGetLit(0x07));
6345     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6346     emitpcode(POC_IORLW,  popGetLit(0xf8));
6347     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6348     break;
6349
6350   case 6:
6351     if(same) {
6352       emitpcode(POC_MOVLW, popGetLit(0x00));
6353       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6354       emitpcode(POC_MOVLW, popGetLit(0xfe));
6355       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6356       emitpcode(POC_IORLW, popGetLit(0x01));
6357       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6358     } else {
6359       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6360       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6361       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6362       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6363       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6364     }
6365     break;
6366
6367   case 7:
6368     if(same) {
6369       emitpcode(POC_MOVLW, popGetLit(0x00));
6370       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6371       emitpcode(POC_MOVLW, popGetLit(0xff));
6372       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6373     } else {
6374       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6375       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6376       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6377     }
6378
6379   default:
6380     break;
6381   }
6382 }
6383
6384 /*-----------------------------------------------------------------*/
6385 /* shiftR1Left2Result - shift right one byte from left to result   */
6386 /*-----------------------------------------------------------------*/
6387 static void shiftR1Left2Result (operand *left, int offl,
6388                                 operand *result, int offr,
6389                                 int shCount, int sign)
6390 {
6391   int same;
6392
6393   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6394
6395   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6396
6397   /* Copy the msb into the carry if signed. */
6398   if(sign) {
6399     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6400     return;
6401   }
6402
6403
6404
6405   switch(shCount) {
6406   case 1:
6407     emitCLRC;
6408     if(same) 
6409       emitpcode(POC_RRF, popGet(AOP(result),offr));
6410     else {
6411       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6412       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413     }
6414     break;
6415   case 2:
6416     emitCLRC;
6417     if(same) {
6418       emitpcode(POC_RRF, popGet(AOP(result),offr));
6419     } else {
6420       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6421       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422     }
6423     emitCLRC;
6424     emitpcode(POC_RRF, popGet(AOP(result),offr));
6425
6426     break;
6427   case 3:
6428     if(same)
6429       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6430     else {
6431       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6432       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6433     }
6434
6435     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6436     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6437     emitpcode(POC_ANDLW, popGetLit(0x1f));
6438     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6439     break;
6440       
6441   case 4:
6442     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6443     emitpcode(POC_ANDLW, popGetLit(0x0f));
6444     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445     break;
6446
6447   case 5:
6448     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6449     emitpcode(POC_ANDLW, popGetLit(0x0f));
6450     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6451     emitCLRC;
6452     emitpcode(POC_RRF, popGet(AOP(result),offr));
6453
6454     break;
6455   case 6:
6456
6457     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6458     emitpcode(POC_ANDLW, popGetLit(0x80));
6459     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6460     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6461     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6462     break;
6463
6464   case 7:
6465
6466     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6467     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6468     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6469
6470     break;
6471
6472   default:
6473     break;
6474   }
6475 }
6476
6477 /*-----------------------------------------------------------------*/
6478 /* shiftL1Left2Result - shift left one byte from left to result    */
6479 /*-----------------------------------------------------------------*/
6480 static void shiftL1Left2Result (operand *left, int offl,
6481                                 operand *result, int offr, int shCount)
6482 {
6483   int same;
6484
6485   //    char *l;
6486   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6487
6488   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6489   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6490     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6491     //    MOVA(l);
6492     /* shift left accumulator */
6493     //AccLsh(shCount); // don't comment out just yet...
6494   //    aopPut(AOP(result),"a",offr);
6495
6496   switch(shCount) {
6497   case 1:
6498     /* Shift left 1 bit position */
6499     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6500     if(same) {
6501       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6502     } else {
6503       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6504       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505     }
6506     break;
6507   case 2:
6508     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6509     emitpcode(POC_ANDLW,popGetLit(0x7e));
6510     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6511     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6512     break;
6513   case 3:
6514     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6515     emitpcode(POC_ANDLW,popGetLit(0x3e));
6516     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6517     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6518     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6519     break;
6520   case 4:
6521     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6522     emitpcode(POC_ANDLW, popGetLit(0xf0));
6523     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6524     break;
6525   case 5:
6526     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6527     emitpcode(POC_ANDLW, popGetLit(0xf0));
6528     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6529     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6530     break;
6531   case 6:
6532     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6533     emitpcode(POC_ANDLW, popGetLit(0x30));
6534     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6535     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6536     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6537     break;
6538   case 7:
6539     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6540     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6541     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6542     break;
6543
6544   default:
6545     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6546   }
6547
6548 }
6549
6550 /*-----------------------------------------------------------------*/
6551 /* movLeft2Result - move byte from left to result                  */
6552 /*-----------------------------------------------------------------*/
6553 static void movLeft2Result (operand *left, int offl,
6554                             operand *result, int offr)
6555 {
6556   char *l;
6557   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6558   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6559     l = aopGet(AOP(left),offl,FALSE,FALSE);
6560
6561     if (*l == '@' && (IS_AOP_PREG(result))) {
6562       pic14_emitcode("mov","a,%s",l);
6563       aopPut(AOP(result),"a",offr);
6564     } else {
6565       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6566       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6567     }
6568   }
6569 }
6570
6571 /*-----------------------------------------------------------------*/
6572 /* shiftL2Left2Result - shift left two bytes from left to result   */
6573 /*-----------------------------------------------------------------*/
6574 static void shiftL2Left2Result (operand *left, int offl,
6575                                 operand *result, int offr, int shCount)
6576 {
6577
6578
6579   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6580
6581   if(pic14_sameRegs(AOP(result), AOP(left))) {
6582     switch(shCount) {
6583     case 0:
6584       break;
6585     case 1:
6586     case 2:
6587     case 3:
6588
6589       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6590       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6591       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6592
6593       while(--shCount) {
6594         emitCLRC;
6595         emitpcode(POC_RLF, popGet(AOP(result),offr));
6596         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6597       }
6598
6599       break;
6600     case 4:
6601     case 5:
6602       emitpcode(POC_MOVLW, popGetLit(0x0f));
6603       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6604       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6605       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6606       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6607       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6608       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6609       if(shCount >=5) {
6610         emitpcode(POC_RLF, popGet(AOP(result),offr));
6611         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6612       }
6613       break;
6614     case 6:
6615       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6616       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6617       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6618       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6619       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6620       emitpcode(POC_ANDLW,popGetLit(0xc0));
6621       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6622       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6623       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6624       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6625       break;
6626     case 7:
6627       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6628       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6629       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6630       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6631       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6632     }
6633
6634   } else {
6635     switch(shCount) {
6636     case 0:
6637       break;
6638     case 1:
6639     case 2:
6640     case 3:
6641       /* note, use a mov/add for the shift since the mov has a
6642          chance of getting optimized out */
6643       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6644       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6645       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6646       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6647       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6648
6649       while(--shCount) {
6650         emitCLRC;
6651         emitpcode(POC_RLF, popGet(AOP(result),offr));
6652         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6653       }
6654       break;
6655
6656     case 4:
6657     case 5:
6658       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6659       emitpcode(POC_ANDLW, popGetLit(0xF0));
6660       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6661       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6662       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6663       emitpcode(POC_ANDLW, popGetLit(0xF0));
6664       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6665       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6666
6667
6668       if(shCount == 5) {
6669         emitpcode(POC_RLF, popGet(AOP(result),offr));
6670         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6671       }
6672       break;
6673     case 6:
6674       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6675       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6676       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6677       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6678
6679       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6680       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6681       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682       emitpcode(POC_ANDLW,popGetLit(0xc0));
6683       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6684       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6685       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6686       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6687       break;
6688     case 7:
6689       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6690       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6691       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6692       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6693       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6694     }
6695   }
6696
6697 }
6698 /*-----------------------------------------------------------------*/
6699 /* shiftR2Left2Result - shift right two bytes from left to result  */
6700 /*-----------------------------------------------------------------*/
6701 static void shiftR2Left2Result (operand *left, int offl,
6702                                 operand *result, int offr,
6703                                 int shCount, int sign)
6704 {
6705   int same=0;
6706
6707   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6708   same = pic14_sameRegs(AOP(result), AOP(left));
6709
6710   if(same && ((offl + MSB16) == offr)){
6711     same=1;
6712     /* don't crash result[offr] */
6713     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6714     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6715   } else {
6716     movLeft2Result(left,offl, result, offr);
6717     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6718   }
6719   /* a:x >> shCount (x = lsb(result))*/
6720 /*
6721   if(sign)
6722     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6723   else {
6724     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6725 */
6726   switch(shCount) {
6727   case 0:
6728     break;
6729   case 1:
6730   case 2:
6731   case 3:
6732     if(sign)
6733       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6734     else
6735       emitCLRC;
6736
6737     if(same) {
6738       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6739       emitpcode(POC_RRF,popGet(AOP(result),offr));
6740     } else {
6741       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6742       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6743       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6744       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6745     }
6746
6747     while(--shCount) {
6748       if(sign)
6749         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6750       else
6751         emitCLRC;
6752       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6753       emitpcode(POC_RRF,popGet(AOP(result),offr));
6754     }
6755     break;
6756   case 4:
6757   case 5:
6758     if(same) {
6759
6760       emitpcode(POC_MOVLW, popGetLit(0xf0));
6761       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6762       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6763
6764       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6765       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6766       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6767       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6768     } else {
6769       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6770       emitpcode(POC_ANDLW, popGetLit(0x0f));
6771       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6772
6773       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6774       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6775       emitpcode(POC_ANDLW, popGetLit(0xf0));
6776       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6777       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6778     }
6779
6780     if(shCount >=5) {
6781       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6782       emitpcode(POC_RRF, popGet(AOP(result),offr));
6783     }
6784
6785     if(sign) {
6786       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6787       emitpcode(POC_BTFSC, 
6788                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6789       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6790     }
6791
6792     break;
6793
6794   case 6:
6795     if(same) {
6796
6797       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6798       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6799
6800       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6801       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6802       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6803       emitpcode(POC_ANDLW,popGetLit(0x03));
6804       if(sign) {
6805         emitpcode(POC_BTFSC, 
6806                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6807         emitpcode(POC_IORLW,popGetLit(0xfc));
6808       }
6809       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6810       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6811       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6812       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6813     } else {
6814       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6815       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6816       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6817       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6818       emitpcode(POC_RLFW,  popGet(AOP(result),offr+MSB16));
6819       emitpcode(POC_ANDLW,popGetLit(0x03));
6820       if(sign) {
6821         emitpcode(POC_BTFSC, 
6822                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6823         emitpcode(POC_IORLW,popGetLit(0xfc));
6824       }
6825       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6826       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6827
6828         
6829     }
6830
6831     break;
6832   case 7:
6833     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6834     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6835     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6836     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6837     if(sign) {
6838       emitSKPNC;
6839       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6840     } else 
6841       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6842   }
6843 }
6844
6845
6846 /*-----------------------------------------------------------------*/
6847 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6848 /*-----------------------------------------------------------------*/
6849 static void shiftLLeftOrResult (operand *left, int offl,
6850                                 operand *result, int offr, int shCount)
6851 {
6852     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6853     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6854     /* shift left accumulator */
6855     AccLsh(shCount);
6856     /* or with result */
6857     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6858     /* back to result */
6859     aopPut(AOP(result),"a",offr);
6860 }
6861
6862 /*-----------------------------------------------------------------*/
6863 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6864 /*-----------------------------------------------------------------*/
6865 static void shiftRLeftOrResult (operand *left, int offl,
6866                                 operand *result, int offr, int shCount)
6867 {
6868     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6869     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6870     /* shift right accumulator */
6871     AccRsh(shCount);
6872     /* or with result */
6873     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6874     /* back to result */
6875     aopPut(AOP(result),"a",offr);
6876 }
6877
6878 /*-----------------------------------------------------------------*/
6879 /* genlshOne - left shift a one byte quantity by known count       */
6880 /*-----------------------------------------------------------------*/
6881 static void genlshOne (operand *result, operand *left, int shCount)
6882 {       
6883     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6884     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6885 }
6886
6887 /*-----------------------------------------------------------------*/
6888 /* genlshTwo - left shift two bytes by known amount != 0           */
6889 /*-----------------------------------------------------------------*/
6890 static void genlshTwo (operand *result,operand *left, int shCount)
6891 {
6892     int size;
6893     
6894     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6895     size = pic14_getDataSize(result);
6896
6897     /* if shCount >= 8 */
6898     if (shCount >= 8) {
6899         shCount -= 8 ;
6900
6901         if (size > 1){
6902             if (shCount)
6903                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6904             else 
6905                 movLeft2Result(left, LSB, result, MSB16);
6906         }
6907         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6908     }
6909
6910     /*  1 <= shCount <= 7 */
6911     else {  
6912         if(size == 1)
6913             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6914         else 
6915             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6916     }
6917 }
6918
6919 /*-----------------------------------------------------------------*/
6920 /* shiftLLong - shift left one long from left to result            */
6921 /* offl = LSB or MSB16                                             */
6922 /*-----------------------------------------------------------------*/
6923 static void shiftLLong (operand *left, operand *result, int offr )
6924 {
6925     char *l;
6926     int size = AOP_SIZE(result);
6927
6928     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6929     if(size >= LSB+offr){
6930         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6931         MOVA(l);
6932         pic14_emitcode("add","a,acc");
6933         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6934             size >= MSB16+offr && offr != LSB )
6935             pic14_emitcode("xch","a,%s",
6936                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6937         else        
6938             aopPut(AOP(result),"a",LSB+offr);
6939     }
6940
6941     if(size >= MSB16+offr){
6942         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6943             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6944             MOVA(l);
6945         }
6946         pic14_emitcode("rlc","a");
6947         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6948             size >= MSB24+offr && offr != LSB)
6949             pic14_emitcode("xch","a,%s",
6950                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6951         else        
6952             aopPut(AOP(result),"a",MSB16+offr);
6953     }
6954
6955     if(size >= MSB24+offr){
6956         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6957             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6958             MOVA(l);
6959         }
6960         pic14_emitcode("rlc","a");
6961         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6962             size >= MSB32+offr && offr != LSB )
6963             pic14_emitcode("xch","a,%s",
6964                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6965         else        
6966             aopPut(AOP(result),"a",MSB24+offr);
6967     }
6968
6969     if(size > MSB32+offr){
6970         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6971             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6972             MOVA(l);    
6973         }
6974         pic14_emitcode("rlc","a");
6975         aopPut(AOP(result),"a",MSB32+offr);
6976     }
6977     if(offr != LSB)
6978         aopPut(AOP(result),zero,LSB);       
6979 }
6980
6981 /*-----------------------------------------------------------------*/
6982 /* genlshFour - shift four byte by a known amount != 0             */
6983 /*-----------------------------------------------------------------*/
6984 static void genlshFour (operand *result, operand *left, int shCount)
6985 {
6986     int size;
6987
6988     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6989     size = AOP_SIZE(result);
6990
6991     /* if shifting more that 3 bytes */
6992     if (shCount >= 24 ) {
6993         shCount -= 24;
6994         if (shCount)
6995             /* lowest order of left goes to the highest
6996             order of the destination */
6997             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6998         else
6999             movLeft2Result(left, LSB, result, MSB32);
7000         aopPut(AOP(result),zero,LSB);
7001         aopPut(AOP(result),zero,MSB16);
7002         aopPut(AOP(result),zero,MSB32);
7003         return;
7004     }
7005
7006     /* more than two bytes */
7007     else if ( shCount >= 16 ) {
7008         /* lower order two bytes goes to higher order two bytes */
7009         shCount -= 16;
7010         /* if some more remaining */
7011         if (shCount)
7012             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7013         else {
7014             movLeft2Result(left, MSB16, result, MSB32);
7015             movLeft2Result(left, LSB, result, MSB24);
7016         }
7017         aopPut(AOP(result),zero,MSB16);
7018         aopPut(AOP(result),zero,LSB);
7019         return;
7020     }    
7021
7022     /* if more than 1 byte */
7023     else if ( shCount >= 8 ) {
7024         /* lower order three bytes goes to higher order  three bytes */
7025         shCount -= 8;
7026         if(size == 2){
7027             if(shCount)
7028                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7029             else
7030                 movLeft2Result(left, LSB, result, MSB16);
7031         }
7032         else{   /* size = 4 */
7033             if(shCount == 0){
7034                 movLeft2Result(left, MSB24, result, MSB32);
7035                 movLeft2Result(left, MSB16, result, MSB24);
7036                 movLeft2Result(left, LSB, result, MSB16);
7037                 aopPut(AOP(result),zero,LSB);
7038             }
7039             else if(shCount == 1)
7040                 shiftLLong(left, result, MSB16);
7041             else{
7042                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7043                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7044                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7045                 aopPut(AOP(result),zero,LSB);
7046             }
7047         }
7048     }
7049
7050     /* 1 <= shCount <= 7 */
7051     else if(shCount <= 2){
7052         shiftLLong(left, result, LSB);
7053         if(shCount == 2)
7054             shiftLLong(result, result, LSB);
7055     }
7056     /* 3 <= shCount <= 7, optimize */
7057     else{
7058         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7059         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7060         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7061     }
7062 }
7063
7064 /*-----------------------------------------------------------------*/
7065 /* genLeftShiftLiteral - left shifting by known count              */
7066 /*-----------------------------------------------------------------*/
7067 static void genLeftShiftLiteral (operand *left,
7068                                  operand *right,
7069                                  operand *result,
7070                                  iCode *ic)
7071 {    
7072     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7073     int size;
7074
7075     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7076     freeAsmop(right,NULL,ic,TRUE);
7077
7078     aopOp(left,ic,FALSE);
7079     aopOp(result,ic,FALSE);
7080
7081     size = getSize(operandType(result));
7082
7083 #if VIEW_SIZE
7084     pic14_emitcode("; shift left ","result %d, left %d",size,
7085              AOP_SIZE(left));
7086 #endif
7087
7088     /* I suppose that the left size >= result size */
7089     if(shCount == 0){
7090         while(size--){
7091             movLeft2Result(left, size, result, size);
7092         }
7093     }
7094
7095     else if(shCount >= (size * 8))
7096         while(size--)
7097             aopPut(AOP(result),zero,size);
7098     else{
7099         switch (size) {
7100             case 1:
7101                 genlshOne (result,left,shCount);
7102                 break;
7103
7104             case 2:
7105             case 3:
7106                 genlshTwo (result,left,shCount);
7107                 break;
7108
7109             case 4:
7110                 genlshFour (result,left,shCount);
7111                 break;
7112         }
7113     }
7114     freeAsmop(left,NULL,ic,TRUE);
7115     freeAsmop(result,NULL,ic,TRUE);
7116 }
7117
7118 /*-----------------------------------------------------------------*
7119  * genMultiAsm - repeat assembly instruction for size of register.
7120  * if endian == 1, then the high byte (i.e base address + size of 
7121  * register) is used first else the low byte is used first;
7122  *-----------------------------------------------------------------*/
7123 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7124 {
7125
7126   int offset = 0;
7127
7128   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7129
7130   if(!reg)
7131     return;
7132
7133   if(!endian) {
7134     endian = 1;
7135   } else {
7136     endian = -1;
7137     offset = size-1;
7138   }
7139
7140   while(size--) {
7141     emitpcode(poc,    popGet(AOP(reg),offset));
7142     offset += endian;
7143   }
7144
7145 }
7146 /*-----------------------------------------------------------------*/
7147 /* genLeftShift - generates code for left shifting                 */
7148 /*-----------------------------------------------------------------*/
7149 static void genLeftShift (iCode *ic)
7150 {
7151   operand *left,*right, *result;
7152   int size, offset;
7153   char *l;
7154   symbol *tlbl , *tlbl1;
7155   pCodeOp *pctemp;
7156
7157   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7158
7159   right = IC_RIGHT(ic);
7160   left  = IC_LEFT(ic);
7161   result = IC_RESULT(ic);
7162
7163   aopOp(right,ic,FALSE);
7164
7165   /* if the shift count is known then do it 
7166      as efficiently as possible */
7167   if (AOP_TYPE(right) == AOP_LIT) {
7168     genLeftShiftLiteral (left,right,result,ic);
7169     return ;
7170   }
7171
7172   /* shift count is unknown then we have to form 
7173      a loop get the loop count in B : Note: we take
7174      only the lower order byte since shifting
7175      more that 32 bits make no sense anyway, ( the
7176      largest size of an object can be only 32 bits ) */  
7177
7178     
7179   aopOp(left,ic,FALSE);
7180   aopOp(result,ic,FALSE);
7181
7182   /* now move the left to the result if they are not the
7183      same */
7184   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7185       AOP_SIZE(result) > 1) {
7186
7187     size = AOP_SIZE(result);
7188     offset=0;
7189     while (size--) {
7190       l = aopGet(AOP(left),offset,FALSE,TRUE);
7191       if (*l == '@' && (IS_AOP_PREG(result))) {
7192
7193         pic14_emitcode("mov","a,%s",l);
7194         aopPut(AOP(result),"a",offset);
7195       } else {
7196         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7197         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7198         //aopPut(AOP(result),l,offset);
7199       }
7200       offset++;
7201     }
7202   }
7203
7204   size = AOP_SIZE(result);
7205
7206   /* if it is only one byte then */
7207   if (size == 1) {
7208     if(optimized_for_speed) {
7209       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7210       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7211       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7212       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7213       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7214       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7215       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7216       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7217       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7218       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7219       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7220       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7221     } else {
7222
7223       tlbl = newiTempLabel(NULL);
7224       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7225         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7226         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7227       }
7228
7229       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7230       emitpcode(POC_RRF,    popGet(AOP(result),0));
7231       emitpLabel(tlbl->key);
7232       emitpcode(POC_RLF,    popGet(AOP(result),0));
7233       emitpcode(POC_ADDLW,  popGetLit(1));
7234       emitSKPC;
7235       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7236     }
7237     goto release ;
7238   }
7239     
7240   if (pic14_sameRegs(AOP(left),AOP(result))) {
7241
7242     tlbl = newiTempLabel(NULL);
7243     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7244     genMultiAsm(POC_RRF, result, size,1);
7245     emitpLabel(tlbl->key);
7246     genMultiAsm(POC_RLF, result, size,0);
7247     emitpcode(POC_ADDLW,  popGetLit(1));
7248     emitSKPC;
7249     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7250     goto release;
7251   }
7252
7253   //tlbl = newiTempLabel(NULL);
7254   //offset = 0 ;   
7255   //tlbl1 = newiTempLabel(NULL);
7256
7257   //reAdjustPreg(AOP(result));    
7258     
7259   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7260   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7261   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7262   //MOVA(l);
7263   //pic14_emitcode("add","a,acc");         
7264   //aopPut(AOP(result),"a",offset++);
7265   //while (--size) {
7266   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7267   //  MOVA(l);
7268   //  pic14_emitcode("rlc","a");         
7269   //  aopPut(AOP(result),"a",offset++);
7270   //}
7271   //reAdjustPreg(AOP(result));
7272
7273   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7274   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7275
7276
7277   tlbl = newiTempLabel(NULL);
7278   tlbl1= newiTempLabel(NULL);
7279
7280   size = AOP_SIZE(result);
7281   offset = 1;
7282
7283   pctemp = popGetTempReg();  /* grab a temporary working register. */
7284
7285   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7286
7287   /* offset should be 0, 1 or 3 */
7288   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7289   emitSKPNZ;
7290   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7291
7292   emitpcode(POC_MOVWF, pctemp);
7293
7294
7295   emitpLabel(tlbl->key);
7296
7297   emitCLRC;
7298   emitpcode(POC_RLF,  popGet(AOP(result),0));
7299   while(--size)
7300     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7301
7302   emitpcode(POC_DECFSZ,  pctemp);
7303   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7304   emitpLabel(tlbl1->key);
7305
7306   popReleaseTempReg(pctemp);
7307
7308
7309  release:
7310   freeAsmop (right,NULL,ic,TRUE);
7311   freeAsmop(left,NULL,ic,TRUE);
7312   freeAsmop(result,NULL,ic,TRUE);
7313 }
7314
7315 /*-----------------------------------------------------------------*/
7316 /* genrshOne - right shift a one byte quantity by known count      */
7317 /*-----------------------------------------------------------------*/
7318 static void genrshOne (operand *result, operand *left,
7319                        int shCount, int sign)
7320 {
7321     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7322     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7323 }
7324
7325 /*-----------------------------------------------------------------*/
7326 /* genrshTwo - right shift two bytes by known amount != 0          */
7327 /*-----------------------------------------------------------------*/
7328 static void genrshTwo (operand *result,operand *left,
7329                        int shCount, int sign)
7330 {
7331   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7332   /* if shCount >= 8 */
7333   if (shCount >= 8) {
7334     shCount -= 8 ;
7335     if (shCount)
7336       shiftR1Left2Result(left, MSB16, result, LSB,
7337                          shCount, sign);
7338     else
7339       movLeft2Result(left, MSB16, result, LSB);
7340
7341     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7342
7343     if(sign) {
7344       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7345       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7346     }
7347   }
7348
7349   /*  1 <= shCount <= 7 */
7350   else
7351     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7352 }
7353
7354 /*-----------------------------------------------------------------*/
7355 /* shiftRLong - shift right one long from left to result           */
7356 /* offl = LSB or MSB16                                             */
7357 /*-----------------------------------------------------------------*/
7358 static void shiftRLong (operand *left, int offl,
7359                         operand *result, int sign)
7360 {
7361     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7362     if(!sign)
7363         pic14_emitcode("clr","c");
7364     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7365     if(sign)
7366         pic14_emitcode("mov","c,acc.7");
7367     pic14_emitcode("rrc","a");
7368     aopPut(AOP(result),"a",MSB32-offl);
7369     if(offl == MSB16)
7370         /* add sign of "a" */
7371         addSign(result, MSB32, sign);
7372
7373     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7374     pic14_emitcode("rrc","a");
7375     aopPut(AOP(result),"a",MSB24-offl);
7376
7377     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7378     pic14_emitcode("rrc","a");
7379     aopPut(AOP(result),"a",MSB16-offl);
7380
7381     if(offl == LSB){
7382         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7383         pic14_emitcode("rrc","a");
7384         aopPut(AOP(result),"a",LSB);
7385     }
7386 }
7387
7388 /*-----------------------------------------------------------------*/
7389 /* genrshFour - shift four byte by a known amount != 0             */
7390 /*-----------------------------------------------------------------*/
7391 static void genrshFour (operand *result, operand *left,
7392                         int shCount, int sign)
7393 {
7394   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7395   /* if shifting more that 3 bytes */
7396   if(shCount >= 24 ) {
7397     shCount -= 24;
7398     if(shCount)
7399       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7400     else
7401       movLeft2Result(left, MSB32, result, LSB);
7402
7403     addSign(result, MSB16, sign);
7404   }
7405   else if(shCount >= 16){
7406     shCount -= 16;
7407     if(shCount)
7408       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7409     else{
7410       movLeft2Result(left, MSB24, result, LSB);
7411       movLeft2Result(left, MSB32, result, MSB16);
7412     }
7413     addSign(result, MSB24, sign);
7414   }
7415   else if(shCount >= 8){
7416     shCount -= 8;
7417     if(shCount == 1)
7418       shiftRLong(left, MSB16, result, sign);
7419     else if(shCount == 0){
7420       movLeft2Result(left, MSB16, result, LSB);
7421       movLeft2Result(left, MSB24, result, MSB16);
7422       movLeft2Result(left, MSB32, result, MSB24);
7423       addSign(result, MSB32, sign);
7424     }
7425     else{
7426       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7427       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7428       /* the last shift is signed */
7429       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7430       addSign(result, MSB32, sign);
7431     }
7432   }
7433   else{   /* 1 <= shCount <= 7 */
7434     if(shCount <= 2){
7435       shiftRLong(left, LSB, result, sign);
7436       if(shCount == 2)
7437         shiftRLong(result, LSB, result, sign);
7438     }
7439     else{
7440       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7441       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7442       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7443     }
7444   }
7445 }
7446
7447 /*-----------------------------------------------------------------*/
7448 /* genRightShiftLiteral - right shifting by known count            */
7449 /*-----------------------------------------------------------------*/
7450 static void genRightShiftLiteral (operand *left,
7451                                   operand *right,
7452                                   operand *result,
7453                                   iCode *ic,
7454                                   int sign)
7455 {    
7456   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7457   int lsize,res_size;
7458
7459   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7460   freeAsmop(right,NULL,ic,TRUE);
7461
7462   aopOp(left,ic,FALSE);
7463   aopOp(result,ic,FALSE);
7464
7465 #if VIEW_SIZE
7466   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7467                  AOP_SIZE(left));
7468 #endif
7469
7470   lsize = pic14_getDataSize(left);
7471   res_size = pic14_getDataSize(result);
7472   /* test the LEFT size !!! */
7473
7474   /* I suppose that the left size >= result size */
7475   if(shCount == 0){
7476     while(res_size--)
7477       movLeft2Result(left, lsize, result, res_size);
7478   }
7479
7480   else if(shCount >= (lsize * 8)){
7481
7482     if(res_size == 1) {
7483       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7484       if(sign) {
7485         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7486         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7487       }
7488     } else {
7489
7490       if(sign) {
7491         emitpcode(POC_MOVLW, popGetLit(0));
7492         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7493         emitpcode(POC_MOVLW, popGetLit(0xff));
7494         while(res_size--)
7495           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7496
7497       } else {
7498
7499         while(res_size--)
7500           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7501       }
7502     }
7503   } else {
7504
7505     switch (res_size) {
7506     case 1:
7507       genrshOne (result,left,shCount,sign);
7508       break;
7509
7510     case 2:
7511       genrshTwo (result,left,shCount,sign);
7512       break;
7513
7514     case 4:
7515       genrshFour (result,left,shCount,sign);
7516       break;
7517     default :
7518       break;
7519     }
7520
7521   }
7522
7523   freeAsmop(left,NULL,ic,TRUE);
7524   freeAsmop(result,NULL,ic,TRUE);
7525 }
7526
7527 /*-----------------------------------------------------------------*/
7528 /* genSignedRightShift - right shift of signed number              */
7529 /*-----------------------------------------------------------------*/
7530 static void genSignedRightShift (iCode *ic)
7531 {
7532   operand *right, *left, *result;
7533   int size, offset;
7534   //  char *l;
7535   symbol *tlbl, *tlbl1 ;
7536   pCodeOp *pctemp;
7537
7538   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7539
7540   /* we do it the hard way put the shift count in b
7541      and loop thru preserving the sign */
7542   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7543
7544   right = IC_RIGHT(ic);
7545   left  = IC_LEFT(ic);
7546   result = IC_RESULT(ic);
7547
7548   aopOp(right,ic,FALSE);  
7549   aopOp(left,ic,FALSE);
7550   aopOp(result,ic,FALSE);
7551
7552
7553   if ( AOP_TYPE(right) == AOP_LIT) {
7554     genRightShiftLiteral (left,right,result,ic,1);
7555     return ;
7556   }
7557   /* shift count is unknown then we have to form 
7558      a loop get the loop count in B : Note: we take
7559      only the lower order byte since shifting
7560      more that 32 bits make no sense anyway, ( the
7561      largest size of an object can be only 32 bits ) */  
7562
7563   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7564   //pic14_emitcode("inc","b");
7565   //freeAsmop (right,NULL,ic,TRUE);
7566   //aopOp(left,ic,FALSE);
7567   //aopOp(result,ic,FALSE);
7568
7569   /* now move the left to the result if they are not the
7570      same */
7571   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7572       AOP_SIZE(result) > 1) {
7573
7574     size = AOP_SIZE(result);
7575     offset=0;
7576     while (size--) { 
7577       /*
7578         l = aopGet(AOP(left),offset,FALSE,TRUE);
7579         if (*l == '@' && IS_AOP_PREG(result)) {
7580
7581         pic14_emitcode("mov","a,%s",l);
7582         aopPut(AOP(result),"a",offset);
7583         } else
7584         aopPut(AOP(result),l,offset);
7585       */
7586       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7587       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7588
7589       offset++;
7590     }
7591   }
7592
7593   /* mov the highest order bit to OVR */    
7594   tlbl = newiTempLabel(NULL);
7595   tlbl1= newiTempLabel(NULL);
7596
7597   size = AOP_SIZE(result);
7598   offset = size - 1;
7599
7600   pctemp = popGetTempReg();  /* grab a temporary working register. */
7601
7602   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7603
7604   /* offset should be 0, 1 or 3 */
7605   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7606   emitSKPNZ;
7607   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7608
7609   emitpcode(POC_MOVWF, pctemp);
7610
7611
7612   emitpLabel(tlbl->key);
7613
7614   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7615   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7616
7617   while(--size) {
7618     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7619   }
7620
7621   emitpcode(POC_DECFSZ,  pctemp);
7622   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7623   emitpLabel(tlbl1->key);
7624
7625   popReleaseTempReg(pctemp);
7626 #if 0
7627   size = AOP_SIZE(result);
7628   offset = size - 1;
7629   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7630   pic14_emitcode("rlc","a");
7631   pic14_emitcode("mov","ov,c");
7632   /* if it is only one byte then */
7633   if (size == 1) {
7634     l = aopGet(AOP(left),0,FALSE,FALSE);
7635     MOVA(l);
7636     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7637     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7638     pic14_emitcode("mov","c,ov");
7639     pic14_emitcode("rrc","a");
7640     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7641     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7642     aopPut(AOP(result),"a",0);
7643     goto release ;
7644   }
7645
7646   reAdjustPreg(AOP(result));
7647   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7648   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7649   pic14_emitcode("mov","c,ov");
7650   while (size--) {
7651     l = aopGet(AOP(result),offset,FALSE,FALSE);
7652     MOVA(l);
7653     pic14_emitcode("rrc","a");         
7654     aopPut(AOP(result),"a",offset--);
7655   }
7656   reAdjustPreg(AOP(result));
7657   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7658   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7659
7660  release:
7661 #endif
7662
7663   freeAsmop(left,NULL,ic,TRUE);
7664   freeAsmop(result,NULL,ic,TRUE);
7665   freeAsmop(right,NULL,ic,TRUE);
7666 }
7667
7668 /*-----------------------------------------------------------------*/
7669 /* genRightShift - generate code for right shifting                */
7670 /*-----------------------------------------------------------------*/
7671 static void genRightShift (iCode *ic)
7672 {
7673     operand *right, *left, *result;
7674     sym_link *retype ;
7675     int size, offset;
7676     char *l;
7677     symbol *tlbl, *tlbl1 ;
7678
7679     /* if signed then we do it the hard way preserve the
7680     sign bit moving it inwards */
7681     retype = getSpec(operandType(IC_RESULT(ic)));
7682     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7683
7684     if (!SPEC_USIGN(retype)) {
7685         genSignedRightShift (ic);
7686         return ;
7687     }
7688
7689     /* signed & unsigned types are treated the same : i.e. the
7690     signed is NOT propagated inwards : quoting from the
7691     ANSI - standard : "for E1 >> E2, is equivalent to division
7692     by 2**E2 if unsigned or if it has a non-negative value,
7693     otherwise the result is implementation defined ", MY definition
7694     is that the sign does not get propagated */
7695
7696     right = IC_RIGHT(ic);
7697     left  = IC_LEFT(ic);
7698     result = IC_RESULT(ic);
7699
7700     aopOp(right,ic,FALSE);
7701
7702     /* if the shift count is known then do it 
7703     as efficiently as possible */
7704     if (AOP_TYPE(right) == AOP_LIT) {
7705         genRightShiftLiteral (left,right,result,ic, 0);
7706         return ;
7707     }
7708
7709     /* shift count is unknown then we have to form 
7710     a loop get the loop count in B : Note: we take
7711     only the lower order byte since shifting
7712     more that 32 bits make no sense anyway, ( the
7713     largest size of an object can be only 32 bits ) */  
7714
7715     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7716     pic14_emitcode("inc","b");
7717     aopOp(left,ic,FALSE);
7718     aopOp(result,ic,FALSE);
7719
7720     /* now move the left to the result if they are not the
7721     same */
7722     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7723         AOP_SIZE(result) > 1) {
7724
7725         size = AOP_SIZE(result);
7726         offset=0;
7727         while (size--) {
7728             l = aopGet(AOP(left),offset,FALSE,TRUE);
7729             if (*l == '@' && IS_AOP_PREG(result)) {
7730
7731                 pic14_emitcode("mov","a,%s",l);
7732                 aopPut(AOP(result),"a",offset);
7733             } else
7734                 aopPut(AOP(result),l,offset);
7735             offset++;
7736         }
7737     }
7738
7739     tlbl = newiTempLabel(NULL);
7740     tlbl1= newiTempLabel(NULL);
7741     size = AOP_SIZE(result);
7742     offset = size - 1;
7743
7744     /* if it is only one byte then */
7745     if (size == 1) {
7746
7747       tlbl = newiTempLabel(NULL);
7748       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7749         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7750         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7751       }
7752
7753       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7754       emitpcode(POC_RLF,    popGet(AOP(result),0));
7755       emitpLabel(tlbl->key);
7756       emitpcode(POC_RRF,    popGet(AOP(result),0));
7757       emitpcode(POC_ADDLW,  popGetLit(1));
7758       emitSKPC;
7759       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7760
7761       goto release ;
7762     }
7763
7764     reAdjustPreg(AOP(result));
7765     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7766     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7767     CLRC;
7768     while (size--) {
7769         l = aopGet(AOP(result),offset,FALSE,FALSE);
7770         MOVA(l);
7771         pic14_emitcode("rrc","a");         
7772         aopPut(AOP(result),"a",offset--);
7773     }
7774     reAdjustPreg(AOP(result));
7775
7776     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7777     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7778
7779 release:
7780     freeAsmop(left,NULL,ic,TRUE);
7781     freeAsmop (right,NULL,ic,TRUE);
7782     freeAsmop(result,NULL,ic,TRUE);
7783 }
7784
7785 /*-----------------------------------------------------------------*/
7786 /* genUnpackBits - generates code for unpacking bits               */
7787 /*-----------------------------------------------------------------*/
7788 static void genUnpackBits (operand *result, char *rname, int ptype)
7789 {    
7790     int shCnt ;
7791     int rlen = 0 ;
7792     sym_link *etype;
7793     int offset = 0 ;
7794
7795     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7796     etype = getSpec(operandType(result));
7797
7798     /* read the first byte  */
7799     switch (ptype) {
7800
7801     case POINTER:
7802     case IPOINTER:
7803         pic14_emitcode("mov","a,@%s",rname);
7804         break;
7805         
7806     case PPOINTER:
7807         pic14_emitcode("movx","a,@%s",rname);
7808         break;
7809         
7810     case FPOINTER:
7811         pic14_emitcode("movx","a,@dptr");
7812         break;
7813
7814     case CPOINTER:
7815         pic14_emitcode("clr","a");
7816         pic14_emitcode("movc","a","@a+dptr");
7817         break;
7818
7819     case GPOINTER:
7820         pic14_emitcode("lcall","__gptrget");
7821         break;
7822     }
7823
7824     /* if we have bitdisplacement then it fits   */
7825     /* into this byte completely or if length is */
7826     /* less than a byte                          */
7827     if ((shCnt = SPEC_BSTR(etype)) || 
7828         (SPEC_BLEN(etype) <= 8))  {
7829
7830         /* shift right acc */
7831         AccRsh(shCnt);
7832
7833         pic14_emitcode("anl","a,#0x%02x",
7834                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7835         aopPut(AOP(result),"a",offset);
7836         return ;
7837     }
7838
7839     /* bit field did not fit in a byte  */
7840     rlen = SPEC_BLEN(etype) - 8;
7841     aopPut(AOP(result),"a",offset++);
7842
7843     while (1)  {
7844
7845         switch (ptype) {
7846         case POINTER:
7847         case IPOINTER:
7848             pic14_emitcode("inc","%s",rname);
7849             pic14_emitcode("mov","a,@%s",rname);
7850             break;
7851             
7852         case PPOINTER:
7853             pic14_emitcode("inc","%s",rname);
7854             pic14_emitcode("movx","a,@%s",rname);
7855             break;
7856
7857         case FPOINTER:
7858             pic14_emitcode("inc","dptr");
7859             pic14_emitcode("movx","a,@dptr");
7860             break;
7861             
7862         case CPOINTER:
7863             pic14_emitcode("clr","a");
7864             pic14_emitcode("inc","dptr");
7865             pic14_emitcode("movc","a","@a+dptr");
7866             break;
7867             
7868         case GPOINTER:
7869             pic14_emitcode("inc","dptr");
7870             pic14_emitcode("lcall","__gptrget");
7871             break;
7872         }
7873
7874         rlen -= 8;            
7875         /* if we are done */
7876         if ( rlen <= 0 )
7877             break ;
7878         
7879         aopPut(AOP(result),"a",offset++);
7880                               
7881     }
7882     
7883     if (rlen) {
7884         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7885         aopPut(AOP(result),"a",offset);        
7886     }
7887     
7888     return ;
7889 }
7890
7891 #if 0
7892 /*-----------------------------------------------------------------*/
7893 /* genDataPointerGet - generates code when ptr offset is known     */
7894 /*-----------------------------------------------------------------*/
7895 static void genDataPointerGet (operand *left, 
7896                                operand *result, 
7897                                iCode *ic)
7898 {
7899   int size , offset = 0;
7900
7901
7902   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7903
7904
7905   /* optimization - most of the time, left and result are the same
7906    * address, but different types. for the pic code, we could omit
7907    * the following
7908    */
7909
7910   aopOp(result,ic,TRUE);
7911
7912   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7913
7914   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7915
7916   size = AOP_SIZE(result);
7917
7918   while (size--) {
7919     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7920     offset++;
7921   }
7922
7923   freeAsmop(left,NULL,ic,TRUE);
7924   freeAsmop(result,NULL,ic,TRUE);
7925 }
7926 #endif
7927 /*-----------------------------------------------------------------*/
7928 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7929 /*-----------------------------------------------------------------*/
7930 static void genNearPointerGet (operand *left, 
7931                                operand *result, 
7932                                iCode *ic)
7933 {
7934     asmop *aop = NULL;
7935     //regs *preg = NULL ;
7936     char *rname ;
7937     sym_link *rtype, *retype;
7938     sym_link *ltype = operandType(left);    
7939     //char buffer[80];
7940
7941     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7942
7943     rtype = operandType(result);
7944     retype= getSpec(rtype);
7945     
7946     aopOp(left,ic,FALSE);
7947     
7948     /* if left is rematerialisable and
7949        result is not bit variable type and
7950        the left is pointer to data space i.e
7951        lower 128 bytes of space */
7952     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7953         !IS_BITVAR(retype)         &&
7954         DCL_TYPE(ltype) == POINTER) {
7955       //genDataPointerGet (left,result,ic);
7956         return ;
7957     }
7958     
7959     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7960
7961         /* if the value is already in a pointer register
7962        then don't need anything more */
7963     if (!AOP_INPREG(AOP(left))) {
7964         /* otherwise get a free pointer register */
7965     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7966 /*
7967         aop = newAsmop(0);
7968         preg = getFreePtr(ic,&aop,FALSE);
7969         pic14_emitcode("mov","%s,%s",
7970                 preg->name,
7971                 aopGet(AOP(left),0,FALSE,TRUE));
7972         rname = preg->name ;
7973 */
7974     rname ="BAD";
7975     } else
7976         rname = aopGet(AOP(left),0,FALSE,FALSE);
7977     
7978     aopOp (result,ic,FALSE);
7979     
7980       /* if bitfield then unpack the bits */
7981     if (IS_BITVAR(retype)) 
7982         genUnpackBits (result,rname,POINTER);
7983     else {
7984         /* we have can just get the values */
7985       int size = AOP_SIZE(result);
7986       int offset = 0 ;  
7987         
7988       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7989
7990       emitpcode(POC_MOVFW,popGet(AOP(left),0));
7991       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7992       while(size--) {
7993         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7994         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7995         if(size)
7996           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7997       }
7998 /*
7999         while (size--) {
8000             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8001
8002                 pic14_emitcode("mov","a,@%s",rname);
8003                 aopPut(AOP(result),"a",offset);
8004             } else {
8005                 sprintf(buffer,"@%s",rname);
8006                 aopPut(AOP(result),buffer,offset);
8007             }
8008             offset++ ;
8009             if (size)
8010                 pic14_emitcode("inc","%s",rname);
8011         }
8012 */
8013     }
8014
8015     /* now some housekeeping stuff */
8016     if (aop) {
8017         /* we had to allocate for this iCode */
8018     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8019         freeAsmop(NULL,aop,ic,TRUE);
8020     } else { 
8021         /* we did not allocate which means left
8022            already in a pointer register, then
8023            if size > 0 && this could be used again
8024            we have to point it back to where it 
8025            belongs */
8026     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8027         if (AOP_SIZE(result) > 1 &&
8028             !OP_SYMBOL(left)->remat &&
8029             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8030               ic->depth )) {
8031             int size = AOP_SIZE(result) - 1;
8032             while (size--)
8033                 pic14_emitcode("dec","%s",rname);
8034         }
8035     }
8036
8037     /* done */
8038     freeAsmop(left,NULL,ic,TRUE);
8039     freeAsmop(result,NULL,ic,TRUE);
8040      
8041 }
8042
8043 /*-----------------------------------------------------------------*/
8044 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8045 /*-----------------------------------------------------------------*/
8046 static void genPagedPointerGet (operand *left, 
8047                                operand *result, 
8048                                iCode *ic)
8049 {
8050     asmop *aop = NULL;
8051     regs *preg = NULL ;
8052     char *rname ;
8053     sym_link *rtype, *retype;    
8054
8055     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8056
8057     rtype = operandType(result);
8058     retype= getSpec(rtype);
8059     
8060     aopOp(left,ic,FALSE);
8061
8062   /* if the value is already in a pointer register
8063        then don't need anything more */
8064     if (!AOP_INPREG(AOP(left))) {
8065         /* otherwise get a free pointer register */
8066         aop = newAsmop(0);
8067         preg = getFreePtr(ic,&aop,FALSE);
8068         pic14_emitcode("mov","%s,%s",
8069                 preg->name,
8070                 aopGet(AOP(left),0,FALSE,TRUE));
8071         rname = preg->name ;
8072     } else
8073         rname = aopGet(AOP(left),0,FALSE,FALSE);
8074     
8075     freeAsmop(left,NULL,ic,TRUE);
8076     aopOp (result,ic,FALSE);
8077
8078     /* if bitfield then unpack the bits */
8079     if (IS_BITVAR(retype)) 
8080         genUnpackBits (result,rname,PPOINTER);
8081     else {
8082         /* we have can just get the values */
8083         int size = AOP_SIZE(result);
8084         int offset = 0 ;        
8085         
8086         while (size--) {
8087             
8088             pic14_emitcode("movx","a,@%s",rname);
8089             aopPut(AOP(result),"a",offset);
8090             
8091             offset++ ;
8092             
8093             if (size)
8094                 pic14_emitcode("inc","%s",rname);
8095         }
8096     }
8097
8098     /* now some housekeeping stuff */
8099     if (aop) {
8100         /* we had to allocate for this iCode */
8101         freeAsmop(NULL,aop,ic,TRUE);
8102     } else { 
8103         /* we did not allocate which means left
8104            already in a pointer register, then
8105            if size > 0 && this could be used again
8106            we have to point it back to where it 
8107            belongs */
8108         if (AOP_SIZE(result) > 1 &&
8109             !OP_SYMBOL(left)->remat &&
8110             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8111               ic->depth )) {
8112             int size = AOP_SIZE(result) - 1;
8113             while (size--)
8114                 pic14_emitcode("dec","%s",rname);
8115         }
8116     }
8117
8118     /* done */
8119     freeAsmop(result,NULL,ic,TRUE);
8120     
8121         
8122 }
8123
8124 /*-----------------------------------------------------------------*/
8125 /* genFarPointerGet - gget value from far space                    */
8126 /*-----------------------------------------------------------------*/
8127 static void genFarPointerGet (operand *left,
8128                               operand *result, iCode *ic)
8129 {
8130     int size, offset ;
8131     sym_link *retype = getSpec(operandType(result));
8132
8133     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8134
8135     aopOp(left,ic,FALSE);
8136
8137     /* if the operand is already in dptr 
8138     then we do nothing else we move the value to dptr */
8139     if (AOP_TYPE(left) != AOP_STR) {
8140         /* if this is remateriazable */
8141         if (AOP_TYPE(left) == AOP_IMMD)
8142             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8143         else { /* we need to get it byte by byte */
8144             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8145             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8146             if (options.model == MODEL_FLAT24)
8147             {
8148                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8149             }
8150         }
8151     }
8152     /* so dptr know contains the address */
8153     freeAsmop(left,NULL,ic,TRUE);
8154     aopOp(result,ic,FALSE);
8155
8156     /* if bit then unpack */
8157     if (IS_BITVAR(retype)) 
8158         genUnpackBits(result,"dptr",FPOINTER);
8159     else {
8160         size = AOP_SIZE(result);
8161         offset = 0 ;
8162
8163         while (size--) {
8164             pic14_emitcode("movx","a,@dptr");
8165             aopPut(AOP(result),"a",offset++);
8166             if (size)
8167                 pic14_emitcode("inc","dptr");
8168         }
8169     }
8170
8171     freeAsmop(result,NULL,ic,TRUE);
8172 }
8173 #if 0
8174 /*-----------------------------------------------------------------*/
8175 /* genCodePointerGet - get value from code space                  */
8176 /*-----------------------------------------------------------------*/
8177 static void genCodePointerGet (operand *left,
8178                                 operand *result, iCode *ic)
8179 {
8180     int size, offset ;
8181     sym_link *retype = getSpec(operandType(result));
8182
8183     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8184
8185     aopOp(left,ic,FALSE);
8186
8187     /* if the operand is already in dptr 
8188     then we do nothing else we move the value to dptr */
8189     if (AOP_TYPE(left) != AOP_STR) {
8190         /* if this is remateriazable */
8191         if (AOP_TYPE(left) == AOP_IMMD)
8192             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8193         else { /* we need to get it byte by byte */
8194             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8195             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8196             if (options.model == MODEL_FLAT24)
8197             {
8198                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8199             }
8200         }
8201     }
8202     /* so dptr know contains the address */
8203     freeAsmop(left,NULL,ic,TRUE);
8204     aopOp(result,ic,FALSE);
8205
8206     /* if bit then unpack */
8207     if (IS_BITVAR(retype)) 
8208         genUnpackBits(result,"dptr",CPOINTER);
8209     else {
8210         size = AOP_SIZE(result);
8211         offset = 0 ;
8212
8213         while (size--) {
8214             pic14_emitcode("clr","a");
8215             pic14_emitcode("movc","a,@a+dptr");
8216             aopPut(AOP(result),"a",offset++);
8217             if (size)
8218                 pic14_emitcode("inc","dptr");
8219         }
8220     }
8221
8222     freeAsmop(result,NULL,ic,TRUE);
8223 }
8224 #endif
8225 /*-----------------------------------------------------------------*/
8226 /* genGenPointerGet - gget value from generic pointer space        */
8227 /*-----------------------------------------------------------------*/
8228 static void genGenPointerGet (operand *left,
8229                               operand *result, iCode *ic)
8230 {
8231   int size, offset ;
8232   sym_link *retype = getSpec(operandType(result));
8233
8234   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8235   aopOp(left,ic,FALSE);
8236   aopOp(result,ic,FALSE);
8237
8238
8239   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8240
8241   /* if the operand is already in dptr 
8242      then we do nothing else we move the value to dptr */
8243   //  if (AOP_TYPE(left) != AOP_STR) {
8244     /* if this is remateriazable */
8245     if (AOP_TYPE(left) == AOP_IMMD) {
8246       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8247       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8248     }
8249     else { /* we need to get it byte by byte */
8250
8251       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8252       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8253
8254       size = AOP_SIZE(result);
8255       offset = 0 ;
8256
8257       while(size--) {
8258         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8259         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8260         if(size)
8261           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8262       }
8263       goto release;
8264     }
8265     //}
8266   /* so dptr know contains the address */
8267
8268   /* if bit then unpack */
8269   //if (IS_BITVAR(retype)) 
8270   //  genUnpackBits(result,"dptr",GPOINTER);
8271
8272  release:
8273   freeAsmop(left,NULL,ic,TRUE);
8274   freeAsmop(result,NULL,ic,TRUE);
8275
8276 }
8277
8278 /*-----------------------------------------------------------------*/
8279 /* genConstPointerGet - get value from const generic pointer space */
8280 /*-----------------------------------------------------------------*/
8281 static void genConstPointerGet (operand *left,
8282                                 operand *result, iCode *ic)
8283 {
8284   //sym_link *retype = getSpec(operandType(result));
8285   symbol *albl = newiTempLabel(NULL);
8286   symbol *blbl = newiTempLabel(NULL);
8287   PIC_OPCODE poc;
8288
8289   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8290   aopOp(left,ic,FALSE);
8291   aopOp(result,ic,FALSE);
8292
8293
8294   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8295
8296   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8297
8298   emitpcode(POC_CALL,popGetLabel(albl->key));
8299   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8300   emitpLabel(albl->key);
8301
8302   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8303     
8304   emitpcode(poc,popGet(AOP(left),1));
8305   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8306   emitpcode(poc,popGet(AOP(left),0));
8307   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8308
8309   emitpLabel(blbl->key);
8310
8311   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8312
8313
8314   freeAsmop(left,NULL,ic,TRUE);
8315   freeAsmop(result,NULL,ic,TRUE);
8316
8317 }
8318 /*-----------------------------------------------------------------*/
8319 /* genPointerGet - generate code for pointer get                   */
8320 /*-----------------------------------------------------------------*/
8321 static void genPointerGet (iCode *ic)
8322 {
8323     operand *left, *result ;
8324     sym_link *type, *etype;
8325     int p_type;
8326
8327     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8328
8329     left = IC_LEFT(ic);
8330     result = IC_RESULT(ic) ;
8331
8332     /* depending on the type of pointer we need to
8333     move it to the correct pointer register */
8334     type = operandType(left);
8335     etype = getSpec(type);
8336
8337     if (IS_PTR_CONST(type))
8338       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8339
8340     /* if left is of type of pointer then it is simple */
8341     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8342         p_type = DCL_TYPE(type);
8343     else {
8344         /* we have to go by the storage class */
8345         p_type = PTR_TYPE(SPEC_OCLS(etype));
8346
8347         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8348
8349         if (SPEC_OCLS(etype)->codesp ) {
8350           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8351           //p_type = CPOINTER ; 
8352         }
8353         else
8354             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8355               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8356                /*p_type = FPOINTER ;*/ 
8357             else
8358                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8359                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8360 /*                  p_type = PPOINTER; */
8361                 else
8362                     if (SPEC_OCLS(etype) == idata )
8363                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8364 /*                      p_type = IPOINTER; */
8365                     else
8366                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8367 /*                      p_type = POINTER ; */
8368     }
8369
8370     /* now that we have the pointer type we assign
8371     the pointer values */
8372     switch (p_type) {
8373
8374     case POINTER:       
8375     case IPOINTER:
8376         genNearPointerGet (left,result,ic);
8377         break;
8378
8379     case PPOINTER:
8380         genPagedPointerGet(left,result,ic);
8381         break;
8382
8383     case FPOINTER:
8384         genFarPointerGet (left,result,ic);
8385         break;
8386
8387     case CPOINTER:
8388         genConstPointerGet (left,result,ic);
8389         //pic14_emitcodePointerGet (left,result,ic);
8390         break;
8391
8392     case GPOINTER:
8393       if (IS_PTR_CONST(type))
8394         genConstPointerGet (left,result,ic);
8395       else
8396         genGenPointerGet (left,result,ic);
8397       break;
8398     }
8399
8400 }
8401
8402 /*-----------------------------------------------------------------*/
8403 /* genPackBits - generates code for packed bit storage             */
8404 /*-----------------------------------------------------------------*/
8405 static void genPackBits (sym_link    *etype ,
8406                          operand *right ,
8407                          char *rname, int p_type)
8408 {
8409     int shCount = 0 ;
8410     int offset = 0  ;
8411     int rLen = 0 ;
8412     int blen, bstr ;   
8413     char *l ;
8414
8415     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8416     blen = SPEC_BLEN(etype);
8417     bstr = SPEC_BSTR(etype);
8418
8419     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8420     MOVA(l);   
8421
8422     /* if the bit lenth is less than or    */
8423     /* it exactly fits a byte then         */
8424     if (SPEC_BLEN(etype) <= 8 )  {
8425         shCount = SPEC_BSTR(etype) ;
8426
8427         /* shift left acc */
8428         AccLsh(shCount);
8429
8430         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8431
8432
8433             switch (p_type) {
8434                 case POINTER:
8435                     pic14_emitcode ("mov","b,a");
8436                     pic14_emitcode("mov","a,@%s",rname);
8437                     break;
8438
8439                 case FPOINTER:
8440                     pic14_emitcode ("mov","b,a");
8441                     pic14_emitcode("movx","a,@dptr");
8442                     break;
8443
8444                 case GPOINTER:
8445                     pic14_emitcode ("push","b");
8446                     pic14_emitcode ("push","acc");
8447                     pic14_emitcode ("lcall","__gptrget");
8448                     pic14_emitcode ("pop","b");
8449                     break;
8450             }
8451
8452             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8453                       ((unsigned char)(0xFF << (blen+bstr)) | 
8454                        (unsigned char)(0xFF >> (8-bstr)) ) );
8455             pic14_emitcode ("orl","a,b");
8456             if (p_type == GPOINTER)
8457                 pic14_emitcode("pop","b");
8458         }
8459     }
8460
8461     switch (p_type) {
8462         case POINTER:
8463             pic14_emitcode("mov","@%s,a",rname);
8464             break;
8465
8466         case FPOINTER:
8467             pic14_emitcode("movx","@dptr,a");
8468             break;
8469
8470         case GPOINTER:
8471             DEBUGpic14_emitcode(";lcall","__gptrput");
8472             break;
8473     }
8474
8475     /* if we r done */
8476     if ( SPEC_BLEN(etype) <= 8 )
8477         return ;
8478
8479     pic14_emitcode("inc","%s",rname);
8480     rLen = SPEC_BLEN(etype) ;     
8481
8482     /* now generate for lengths greater than one byte */
8483     while (1) {
8484
8485         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8486
8487         rLen -= 8 ;
8488         if (rLen <= 0 )
8489             break ;
8490
8491         switch (p_type) {
8492             case POINTER:
8493                 if (*l == '@') {
8494                     MOVA(l);
8495                     pic14_emitcode("mov","@%s,a",rname);
8496                 } else
8497                     pic14_emitcode("mov","@%s,%s",rname,l);
8498                 break;
8499
8500             case FPOINTER:
8501                 MOVA(l);
8502                 pic14_emitcode("movx","@dptr,a");
8503                 break;
8504
8505             case GPOINTER:
8506                 MOVA(l);
8507                 DEBUGpic14_emitcode(";lcall","__gptrput");
8508                 break;  
8509         }   
8510         pic14_emitcode ("inc","%s",rname);
8511     }
8512
8513     MOVA(l);
8514
8515     /* last last was not complete */
8516     if (rLen)   {
8517         /* save the byte & read byte */
8518         switch (p_type) {
8519             case POINTER:
8520                 pic14_emitcode ("mov","b,a");
8521                 pic14_emitcode("mov","a,@%s",rname);
8522                 break;
8523
8524             case FPOINTER:
8525                 pic14_emitcode ("mov","b,a");
8526                 pic14_emitcode("movx","a,@dptr");
8527                 break;
8528
8529             case GPOINTER:
8530                 pic14_emitcode ("push","b");
8531                 pic14_emitcode ("push","acc");
8532                 pic14_emitcode ("lcall","__gptrget");
8533                 pic14_emitcode ("pop","b");
8534                 break;
8535         }
8536
8537         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8538         pic14_emitcode ("orl","a,b");
8539     }
8540
8541     if (p_type == GPOINTER)
8542         pic14_emitcode("pop","b");
8543
8544     switch (p_type) {
8545
8546     case POINTER:
8547         pic14_emitcode("mov","@%s,a",rname);
8548         break;
8549         
8550     case FPOINTER:
8551         pic14_emitcode("movx","@dptr,a");
8552         break;
8553         
8554     case GPOINTER:
8555         DEBUGpic14_emitcode(";lcall","__gptrput");
8556         break;                  
8557     }
8558 }
8559 /*-----------------------------------------------------------------*/
8560 /* genDataPointerSet - remat pointer to data space                 */
8561 /*-----------------------------------------------------------------*/
8562 static void genDataPointerSet(operand *right,
8563                               operand *result,
8564                               iCode *ic)
8565 {
8566     int size, offset = 0 ;
8567     char *l, buffer[256];
8568
8569     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8570     aopOp(right,ic,FALSE);
8571     
8572     l = aopGet(AOP(result),0,FALSE,TRUE);
8573     size = AOP_SIZE(right);
8574 /*
8575     if ( AOP_TYPE(result) == AOP_PCODE) {
8576       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8577               AOP(result)->aopu.pcop->name,
8578               PCOI(AOP(result)->aopu.pcop)->offset);
8579     }
8580 */
8581
8582     // tsd, was l+1 - the underline `_' prefix was being stripped
8583     while (size--) {
8584       if (offset) {
8585         sprintf(buffer,"(%s + %d)",l,offset);
8586         fprintf(stderr,"oops  %s\n",buffer);
8587       } else
8588         sprintf(buffer,"%s",l);
8589
8590         if (AOP_TYPE(right) == AOP_LIT) {
8591           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8592           lit = lit >> (8*offset);
8593           if(lit&0xff) {
8594             pic14_emitcode("movlw","%d",lit);
8595             pic14_emitcode("movwf","%s",buffer);
8596
8597             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8598             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8599             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8600
8601           } else {
8602             pic14_emitcode("clrf","%s",buffer);
8603             //emitpcode(POC_CLRF, popRegFromString(buffer));
8604             emitpcode(POC_CLRF, popGet(AOP(result),0));
8605           }
8606         }else {
8607           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8608           pic14_emitcode("movwf","%s",buffer);
8609
8610           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8611           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8612           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8613
8614         }
8615
8616         offset++;
8617     }
8618
8619     freeAsmop(right,NULL,ic,TRUE);
8620     freeAsmop(result,NULL,ic,TRUE);
8621 }
8622
8623 /*-----------------------------------------------------------------*/
8624 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8625 /*-----------------------------------------------------------------*/
8626 static void genNearPointerSet (operand *right,
8627                                operand *result, 
8628                                iCode *ic)
8629 {
8630   asmop *aop = NULL;
8631   char *l;
8632   sym_link *retype;
8633   sym_link *ptype = operandType(result);
8634
8635     
8636   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8637   retype= getSpec(operandType(right));
8638
8639   aopOp(result,ic,FALSE);
8640
8641     
8642   /* if the result is rematerializable &
8643      in data space & not a bit variable */
8644   //if (AOP_TYPE(result) == AOP_IMMD &&
8645   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8646       DCL_TYPE(ptype) == POINTER   &&
8647       !IS_BITVAR(retype)) {
8648     genDataPointerSet (right,result,ic);
8649     freeAsmop(result,NULL,ic,TRUE);
8650     return;
8651   }
8652
8653   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8654   aopOp(right,ic,FALSE);
8655   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8656
8657   /* if the value is already in a pointer register
8658      then don't need anything more */
8659   if (!AOP_INPREG(AOP(result))) {
8660     /* otherwise get a free pointer register */
8661     //aop = newAsmop(0);
8662     //preg = getFreePtr(ic,&aop,FALSE);
8663     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8664     //pic14_emitcode("mov","%s,%s",
8665     //         preg->name,
8666     //         aopGet(AOP(result),0,FALSE,TRUE));
8667     //rname = preg->name ;
8668     //pic14_emitcode("movwf","fsr");
8669     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8670     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8671     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8672     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8673     goto release;
8674
8675   }// else
8676   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8677
8678
8679   /* if bitfield then unpack the bits */
8680   if (IS_BITVAR(retype)) {
8681     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8682            "The programmer is obviously confused");
8683     //genPackBits (retype,right,rname,POINTER);
8684     exit(1);
8685   }
8686   else {
8687     /* we have can just get the values */
8688     int size = AOP_SIZE(right);
8689     int offset = 0 ;    
8690
8691     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8692     while (size--) {
8693       l = aopGet(AOP(right),offset,FALSE,TRUE);
8694       if (*l == '@' ) {
8695         //MOVA(l);
8696         //pic14_emitcode("mov","@%s,a",rname);
8697         pic14_emitcode("movf","indf,w ;1");
8698       } else {
8699
8700         if (AOP_TYPE(right) == AOP_LIT) {
8701           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8702           if(lit) {
8703             pic14_emitcode("movlw","%s",l);
8704             pic14_emitcode("movwf","indf ;2");
8705           } else 
8706             pic14_emitcode("clrf","indf");
8707         }else {
8708           pic14_emitcode("movf","%s,w",l);
8709           pic14_emitcode("movwf","indf ;2");
8710         }
8711         //pic14_emitcode("mov","@%s,%s",rname,l);
8712       }
8713       if (size)
8714         pic14_emitcode("incf","fsr,f ;3");
8715       //pic14_emitcode("inc","%s",rname);
8716       offset++;
8717     }
8718   }
8719
8720   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8721   /* now some housekeeping stuff */
8722   if (aop) {
8723     /* we had to allocate for this iCode */
8724     freeAsmop(NULL,aop,ic,TRUE);
8725   } else { 
8726     /* we did not allocate which means left
8727        already in a pointer register, then
8728        if size > 0 && this could be used again
8729        we have to point it back to where it 
8730        belongs */
8731     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8732     if (AOP_SIZE(right) > 1 &&
8733         !OP_SYMBOL(result)->remat &&
8734         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8735           ic->depth )) {
8736       int size = AOP_SIZE(right) - 1;
8737       while (size--)
8738         pic14_emitcode("decf","fsr,f");
8739       //pic14_emitcode("dec","%s",rname);
8740     }
8741   }
8742
8743   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8744   /* done */
8745  release:
8746   freeAsmop(right,NULL,ic,TRUE);
8747   freeAsmop(result,NULL,ic,TRUE);
8748 }
8749
8750 /*-----------------------------------------------------------------*/
8751 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8752 /*-----------------------------------------------------------------*/
8753 static void genPagedPointerSet (operand *right,
8754                                operand *result, 
8755                                iCode *ic)
8756 {
8757     asmop *aop = NULL;
8758     regs *preg = NULL ;
8759     char *rname , *l;
8760     sym_link *retype;
8761        
8762     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8763
8764     retype= getSpec(operandType(right));
8765     
8766     aopOp(result,ic,FALSE);
8767     
8768     /* if the value is already in a pointer register
8769        then don't need anything more */
8770     if (!AOP_INPREG(AOP(result))) {
8771         /* otherwise get a free pointer register */
8772         aop = newAsmop(0);
8773         preg = getFreePtr(ic,&aop,FALSE);
8774         pic14_emitcode("mov","%s,%s",
8775                 preg->name,
8776                 aopGet(AOP(result),0,FALSE,TRUE));
8777         rname = preg->name ;
8778     } else
8779         rname = aopGet(AOP(result),0,FALSE,FALSE);
8780     
8781     freeAsmop(result,NULL,ic,TRUE);
8782     aopOp (right,ic,FALSE);
8783
8784     /* if bitfield then unpack the bits */
8785     if (IS_BITVAR(retype)) 
8786         genPackBits (retype,right,rname,PPOINTER);
8787     else {
8788         /* we have can just get the values */
8789         int size = AOP_SIZE(right);
8790         int offset = 0 ;        
8791         
8792         while (size--) {
8793             l = aopGet(AOP(right),offset,FALSE,TRUE);
8794             
8795             MOVA(l);
8796             pic14_emitcode("movx","@%s,a",rname);
8797
8798             if (size)
8799                 pic14_emitcode("inc","%s",rname);
8800
8801             offset++;
8802         }
8803     }
8804     
8805     /* now some housekeeping stuff */
8806     if (aop) {
8807         /* we had to allocate for this iCode */
8808         freeAsmop(NULL,aop,ic,TRUE);
8809     } else { 
8810         /* we did not allocate which means left
8811            already in a pointer register, then
8812            if size > 0 && this could be used again
8813            we have to point it back to where it 
8814            belongs */
8815         if (AOP_SIZE(right) > 1 &&
8816             !OP_SYMBOL(result)->remat &&
8817             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8818               ic->depth )) {
8819             int size = AOP_SIZE(right) - 1;
8820             while (size--)
8821                 pic14_emitcode("dec","%s",rname);
8822         }
8823     }
8824
8825     /* done */
8826     freeAsmop(right,NULL,ic,TRUE);
8827     
8828         
8829 }
8830
8831 /*-----------------------------------------------------------------*/
8832 /* genFarPointerSet - set value from far space                     */
8833 /*-----------------------------------------------------------------*/
8834 static void genFarPointerSet (operand *right,
8835                               operand *result, iCode *ic)
8836 {
8837     int size, offset ;
8838     sym_link *retype = getSpec(operandType(right));
8839
8840     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8841     aopOp(result,ic,FALSE);
8842
8843     /* if the operand is already in dptr 
8844     then we do nothing else we move the value to dptr */
8845     if (AOP_TYPE(result) != AOP_STR) {
8846         /* if this is remateriazable */
8847         if (AOP_TYPE(result) == AOP_IMMD)
8848             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8849         else { /* we need to get it byte by byte */
8850             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8851             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8852             if (options.model == MODEL_FLAT24)
8853             {
8854                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8855             }
8856         }
8857     }
8858     /* so dptr know contains the address */
8859     freeAsmop(result,NULL,ic,TRUE);
8860     aopOp(right,ic,FALSE);
8861
8862     /* if bit then unpack */
8863     if (IS_BITVAR(retype)) 
8864         genPackBits(retype,right,"dptr",FPOINTER);
8865     else {
8866         size = AOP_SIZE(right);
8867         offset = 0 ;
8868
8869         while (size--) {
8870             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8871             MOVA(l);
8872             pic14_emitcode("movx","@dptr,a");
8873             if (size)
8874                 pic14_emitcode("inc","dptr");
8875         }
8876     }
8877
8878     freeAsmop(right,NULL,ic,TRUE);
8879 }
8880
8881 /*-----------------------------------------------------------------*/
8882 /* genGenPointerSet - set value from generic pointer space         */
8883 /*-----------------------------------------------------------------*/
8884 static void genGenPointerSet (operand *right,
8885                               operand *result, iCode *ic)
8886 {
8887   int size, offset ;
8888   sym_link *retype = getSpec(operandType(right));
8889
8890   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8891
8892   aopOp(result,ic,FALSE);
8893   aopOp(right,ic,FALSE);
8894   size = AOP_SIZE(right);
8895
8896   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8897
8898   /* if the operand is already in dptr 
8899      then we do nothing else we move the value to dptr */
8900   if (AOP_TYPE(result) != AOP_STR) {
8901     /* if this is remateriazable */
8902     if (AOP_TYPE(result) == AOP_IMMD) {
8903       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8904       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8905     }
8906     else { /* we need to get it byte by byte */
8907       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8908       size = AOP_SIZE(right);
8909       offset = 0 ;
8910
8911       /* hack hack! see if this the FSR. If so don't load W */
8912       if(AOP_TYPE(right) != AOP_ACC) {
8913
8914         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8915         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8916
8917         //if(size==2)
8918         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8919         //if(size==4) {
8920         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8921         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8922         //}
8923
8924         while(size--) {
8925           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8926           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8927           
8928           if(size)
8929             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8930         }
8931
8932
8933         goto release;
8934       } 
8935
8936       if(aopIdx(AOP(result),0) != 4) {
8937
8938         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8939         goto release;
8940       }
8941
8942       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8943       goto release;
8944
8945     }
8946   }
8947   /* so dptr know contains the address */
8948
8949
8950   /* if bit then unpack */
8951   if (IS_BITVAR(retype)) 
8952     genPackBits(retype,right,"dptr",GPOINTER);
8953   else {
8954     size = AOP_SIZE(right);
8955     offset = 0 ;
8956
8957   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8958
8959     while (size--) {
8960
8961       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8962       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8963
8964       if (AOP_TYPE(right) == AOP_LIT) 
8965         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8966       else
8967         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8968
8969       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8970
8971       offset++;
8972     }
8973   }
8974
8975  release:
8976   freeAsmop(right,NULL,ic,TRUE);
8977   freeAsmop(result,NULL,ic,TRUE);
8978 }
8979
8980 /*-----------------------------------------------------------------*/
8981 /* genPointerSet - stores the value into a pointer location        */
8982 /*-----------------------------------------------------------------*/
8983 static void genPointerSet (iCode *ic)
8984 {    
8985     operand *right, *result ;
8986     sym_link *type, *etype;
8987     int p_type;
8988
8989     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8990
8991     right = IC_RIGHT(ic);
8992     result = IC_RESULT(ic) ;
8993
8994     /* depending on the type of pointer we need to
8995     move it to the correct pointer register */
8996     type = operandType(result);
8997     etype = getSpec(type);
8998     /* if left is of type of pointer then it is simple */
8999     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9000         p_type = DCL_TYPE(type);
9001     }
9002     else {
9003         /* we have to go by the storage class */
9004         p_type = PTR_TYPE(SPEC_OCLS(etype));
9005
9006 /*      if (SPEC_OCLS(etype)->codesp ) { */
9007 /*          p_type = CPOINTER ;  */
9008 /*      } */
9009 /*      else */
9010 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9011 /*              p_type = FPOINTER ; */
9012 /*          else */
9013 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9014 /*                  p_type = PPOINTER ; */
9015 /*              else */
9016 /*                  if (SPEC_OCLS(etype) == idata ) */
9017 /*                      p_type = IPOINTER ; */
9018 /*                  else */
9019 /*                      p_type = POINTER ; */
9020     }
9021
9022     /* now that we have the pointer type we assign
9023     the pointer values */
9024     switch (p_type) {
9025
9026     case POINTER:
9027     case IPOINTER:
9028         genNearPointerSet (right,result,ic);
9029         break;
9030
9031     case PPOINTER:
9032         genPagedPointerSet (right,result,ic);
9033         break;
9034
9035     case FPOINTER:
9036         genFarPointerSet (right,result,ic);
9037         break;
9038
9039     case GPOINTER:
9040         genGenPointerSet (right,result,ic);
9041         break;
9042
9043     default:
9044       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9045               "genPointerSet: illegal pointer type");
9046     }
9047 }
9048
9049 /*-----------------------------------------------------------------*/
9050 /* genIfx - generate code for Ifx statement                        */
9051 /*-----------------------------------------------------------------*/
9052 static void genIfx (iCode *ic, iCode *popIc)
9053 {
9054   operand *cond = IC_COND(ic);
9055   int isbit =0;
9056
9057   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9058
9059   aopOp(cond,ic,FALSE);
9060
9061   /* get the value into acc */
9062   if (AOP_TYPE(cond) != AOP_CRY)
9063     pic14_toBoolean(cond);
9064   else
9065     isbit = 1;
9066   /* the result is now in the accumulator */
9067   freeAsmop(cond,NULL,ic,TRUE);
9068
9069   /* if there was something to be popped then do it */
9070   if (popIc)
9071     genIpop(popIc);
9072
9073   /* if the condition is  a bit variable */
9074   if (isbit && IS_ITEMP(cond) && 
9075       SPIL_LOC(cond)) {
9076     genIfxJump(ic,SPIL_LOC(cond)->rname);
9077     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9078   }
9079   else {
9080     if (isbit && !IS_ITEMP(cond))
9081       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9082     else
9083       genIfxJump(ic,"a");
9084   }
9085   ic->generated = 1;
9086
9087 }
9088
9089 /*-----------------------------------------------------------------*/
9090 /* genAddrOf - generates code for address of                       */
9091 /*-----------------------------------------------------------------*/
9092 static void genAddrOf (iCode *ic)
9093 {
9094   operand *right, *result, *left;
9095   int size, offset ;
9096
9097   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9098
9099
9100   //aopOp(IC_RESULT(ic),ic,FALSE);
9101
9102   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9103   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9104   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9105
9106   DEBUGpic14_AopType(__LINE__,left,right,result);
9107
9108   size = AOP_SIZE(IC_RESULT(ic));
9109   offset = 0;
9110
9111   while (size--) {
9112     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9113     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9114     offset++;
9115   }
9116
9117   freeAsmop(left,NULL,ic,FALSE);
9118   freeAsmop(result,NULL,ic,TRUE);
9119
9120 }
9121
9122 #if 0
9123 /*-----------------------------------------------------------------*/
9124 /* genFarFarAssign - assignment when both are in far space         */
9125 /*-----------------------------------------------------------------*/
9126 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9127 {
9128     int size = AOP_SIZE(right);
9129     int offset = 0;
9130     char *l ;
9131     /* first push the right side on to the stack */
9132     while (size--) {
9133         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9134         MOVA(l);
9135         pic14_emitcode ("push","acc");
9136     }
9137     
9138     freeAsmop(right,NULL,ic,FALSE);
9139     /* now assign DPTR to result */
9140     aopOp(result,ic,FALSE);
9141     size = AOP_SIZE(result);
9142     while (size--) {
9143         pic14_emitcode ("pop","acc");
9144         aopPut(AOP(result),"a",--offset);
9145     }
9146     freeAsmop(result,NULL,ic,FALSE);
9147         
9148 }
9149 #endif
9150
9151 /*-----------------------------------------------------------------*/
9152 /* genAssign - generate code for assignment                        */
9153 /*-----------------------------------------------------------------*/
9154 static void genAssign (iCode *ic)
9155 {
9156   operand *result, *right;
9157   int size, offset,know_W;
9158   unsigned long lit = 0L;
9159
9160   result = IC_RESULT(ic);
9161   right  = IC_RIGHT(ic) ;
9162
9163   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9164
9165   /* if they are the same */
9166   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9167     return ;
9168
9169   aopOp(right,ic,FALSE);
9170   aopOp(result,ic,TRUE);
9171
9172   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9173
9174   /* if they are the same registers */
9175   if (pic14_sameRegs(AOP(right),AOP(result)))
9176     goto release;
9177
9178   /* if the result is a bit */
9179   if (AOP_TYPE(result) == AOP_CRY) {
9180
9181     /* if the right size is a literal then
9182        we know what the value is */
9183     if (AOP_TYPE(right) == AOP_LIT) {
9184           
9185       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9186                   popGet(AOP(result),0));
9187
9188       if (((int) operandLitValue(right))) 
9189         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9190                        AOP(result)->aopu.aop_dir,
9191                        AOP(result)->aopu.aop_dir);
9192       else
9193         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9194                        AOP(result)->aopu.aop_dir,
9195                        AOP(result)->aopu.aop_dir);
9196       goto release;
9197     }
9198
9199     /* the right is also a bit variable */
9200     if (AOP_TYPE(right) == AOP_CRY) {
9201       emitpcode(POC_BCF,    popGet(AOP(result),0));
9202       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9203       emitpcode(POC_BSF,    popGet(AOP(result),0));
9204
9205       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9206                      AOP(result)->aopu.aop_dir,
9207                      AOP(result)->aopu.aop_dir);
9208       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9209                      AOP(right)->aopu.aop_dir,
9210                      AOP(right)->aopu.aop_dir);
9211       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9212                      AOP(result)->aopu.aop_dir,
9213                      AOP(result)->aopu.aop_dir);
9214       goto release ;
9215     }
9216
9217     /* we need to or */
9218     emitpcode(POC_BCF,    popGet(AOP(result),0));
9219     pic14_toBoolean(right);
9220     emitSKPZ;
9221     emitpcode(POC_BSF,    popGet(AOP(result),0));
9222     //aopPut(AOP(result),"a",0);
9223     goto release ;
9224   }
9225
9226   /* bit variables done */
9227   /* general case */
9228   size = AOP_SIZE(result);
9229   offset = 0 ;
9230   if(AOP_TYPE(right) == AOP_LIT)
9231     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9232
9233   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9234   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9235     if(aopIdx(AOP(result),0) == 4) {
9236   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9237       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9238       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9239       goto release;
9240     } else
9241       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9242   }
9243
9244   know_W=-1;
9245   while (size--) {
9246   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9247     if(AOP_TYPE(right) == AOP_LIT) {
9248       if(lit&0xff) {
9249         if(know_W != (lit&0xff))
9250           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9251         know_W = lit&0xff;
9252         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9253       } else
9254         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9255
9256       lit >>= 8;
9257
9258     } else if (AOP_TYPE(right) == AOP_CRY) {
9259       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9260       if(offset == 0) {
9261         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9262         emitpcode(POC_INCF, popGet(AOP(result),0));
9263       }
9264     } else {
9265   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9266       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9267       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9268     }
9269             
9270     offset++;
9271   }
9272
9273     
9274  release:
9275   freeAsmop (right,NULL,ic,FALSE);
9276   freeAsmop (result,NULL,ic,TRUE);
9277 }   
9278
9279 /*-----------------------------------------------------------------*/
9280 /* genJumpTab - genrates code for jump table                       */
9281 /*-----------------------------------------------------------------*/
9282 static void genJumpTab (iCode *ic)
9283 {
9284     symbol *jtab;
9285     char *l;
9286
9287     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9288
9289     aopOp(IC_JTCOND(ic),ic,FALSE);
9290     /* get the condition into accumulator */
9291     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9292     MOVA(l);
9293     /* multiply by three */
9294     pic14_emitcode("add","a,acc");
9295     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9296
9297     jtab = newiTempLabel(NULL);
9298     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9299     pic14_emitcode("jmp","@a+dptr");
9300     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9301
9302     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9303     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9304     emitSKPNC;
9305     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9306     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9307     emitpLabel(jtab->key);
9308
9309     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9310
9311     /* now generate the jump labels */
9312     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9313          jtab = setNextItem(IC_JTLABELS(ic))) {
9314         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9315         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9316         
9317     }
9318
9319 }
9320
9321 /*-----------------------------------------------------------------*/
9322 /* genMixedOperation - gen code for operators between mixed types  */
9323 /*-----------------------------------------------------------------*/
9324 /*
9325   TSD - Written for the PIC port - but this unfortunately is buggy.
9326   This routine is good in that it is able to efficiently promote 
9327   types to different (larger) sizes. Unfortunately, the temporary
9328   variables that are optimized out by this routine are sometimes
9329   used in other places. So until I know how to really parse the 
9330   iCode tree, I'm going to not be using this routine :(.
9331 */
9332 static int genMixedOperation (iCode *ic)
9333 {
9334 #if 0
9335   operand *result = IC_RESULT(ic);
9336   sym_link *ctype = operandType(IC_LEFT(ic));
9337   operand *right = IC_RIGHT(ic);
9338   int ret = 0;
9339   int big,small;
9340   int offset;
9341
9342   iCode *nextic;
9343   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9344
9345   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9346
9347   nextic = ic->next;
9348   if(!nextic)
9349     return 0;
9350
9351   nextright = IC_RIGHT(nextic);
9352   nextleft  = IC_LEFT(nextic);
9353   nextresult = IC_RESULT(nextic);
9354
9355   aopOp(right,ic,FALSE);
9356   aopOp(result,ic,FALSE);
9357   aopOp(nextright,  nextic, FALSE);
9358   aopOp(nextleft,   nextic, FALSE);
9359   aopOp(nextresult, nextic, FALSE);
9360
9361   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9362
9363     operand *t = right;
9364     right = nextright;
9365     nextright = t; 
9366
9367     pic14_emitcode(";remove right +","");
9368
9369   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9370 /*
9371     operand *t = right;
9372     right = nextleft;
9373     nextleft = t; 
9374 */
9375     pic14_emitcode(";remove left +","");
9376   } else
9377     return 0;
9378
9379   big = AOP_SIZE(nextleft);
9380   small = AOP_SIZE(nextright);
9381
9382   switch(nextic->op) {
9383
9384   case '+':
9385     pic14_emitcode(";optimize a +","");
9386     /* if unsigned or not an integral type */
9387     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9388       pic14_emitcode(";add a bit to something","");
9389     } else {
9390
9391       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9392
9393       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9394         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9395         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9396       } else
9397         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9398
9399       offset = 0;
9400       while(--big) {
9401
9402         offset++;
9403
9404         if(--small) {
9405           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9406             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9407             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9408           }
9409
9410           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9411           emitSKPNC;
9412           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9413                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9414                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9415           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9416           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9417
9418         } else {
9419           pic14_emitcode("rlf","known_zero,w");
9420
9421           /*
9422             if right is signed
9423               btfsc  right,7
9424                addlw ff
9425           */
9426           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9427             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9429           } else {
9430             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9431           }
9432         }
9433       }
9434       ret = 1;
9435     }
9436   }
9437   ret = 1;
9438
9439 release:
9440   freeAsmop(right,NULL,ic,TRUE);
9441   freeAsmop(result,NULL,ic,TRUE);
9442   freeAsmop(nextright,NULL,ic,TRUE);
9443   freeAsmop(nextleft,NULL,ic,TRUE);
9444   if(ret)
9445     nextic->generated = 1;
9446
9447   return ret;
9448 #else
9449   return 0;
9450 #endif
9451 }
9452 /*-----------------------------------------------------------------*/
9453 /* genCast - gen code for casting                                  */
9454 /*-----------------------------------------------------------------*/
9455 static void genCast (iCode *ic)
9456 {
9457     operand *result = IC_RESULT(ic);
9458     sym_link *ctype = operandType(IC_LEFT(ic));
9459     sym_link *rtype = operandType(IC_RIGHT(ic));
9460     operand *right = IC_RIGHT(ic);
9461     int size, offset ;
9462
9463     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9464     /* if they are equivalent then do nothing */
9465     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9466         return ;
9467
9468     aopOp(right,ic,FALSE) ;
9469     aopOp(result,ic,FALSE);
9470
9471     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9472
9473     /* if the result is a bit */
9474     if (AOP_TYPE(result) == AOP_CRY) {
9475         /* if the right size is a literal then
9476         we know what the value is */
9477       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9478         if (AOP_TYPE(right) == AOP_LIT) {
9479
9480           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9481                       popGet(AOP(result),0));
9482
9483             if (((int) operandLitValue(right))) 
9484               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9485                        AOP(result)->aopu.aop_dir,
9486                        AOP(result)->aopu.aop_dir);
9487             else
9488               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9489                        AOP(result)->aopu.aop_dir,
9490                        AOP(result)->aopu.aop_dir);
9491
9492             goto release;
9493         }
9494
9495         /* the right is also a bit variable */
9496         if (AOP_TYPE(right) == AOP_CRY) {
9497
9498           emitCLRC;
9499           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9500
9501           pic14_emitcode("clrc","");
9502           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9503                    AOP(right)->aopu.aop_dir,
9504                    AOP(right)->aopu.aop_dir);
9505             aopPut(AOP(result),"c",0);
9506             goto release ;
9507         }
9508
9509         /* we need to or */
9510         if (AOP_TYPE(right) == AOP_REG) {
9511           emitpcode(POC_BCF,    popGet(AOP(result),0));
9512           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9513           emitpcode(POC_BSF,    popGet(AOP(result),0));
9514         }
9515         pic14_toBoolean(right);
9516         aopPut(AOP(result),"a",0);
9517         goto release ;
9518     }
9519
9520     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9521       int offset = 1;
9522       size = AOP_SIZE(result);
9523
9524       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9525
9526       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9527       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9528       emitpcode(POC_INCF,   popGet(AOP(result),0));
9529
9530       while (size--)
9531         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9532
9533       goto release;
9534     }
9535
9536     /* if they are the same size : or less */
9537     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9538
9539         /* if they are in the same place */
9540       if (pic14_sameRegs(AOP(right),AOP(result)))
9541         goto release;
9542
9543       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9544       if (IS_PTR_CONST(rtype))
9545         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9546       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9547         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9548
9549       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9550         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9551         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9552         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9553         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9554         if(AOP_SIZE(result) <2)
9555           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9556
9557       } else {
9558
9559         /* if they in different places then copy */
9560         size = AOP_SIZE(result);
9561         offset = 0 ;
9562         while (size--) {
9563           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9564           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9565
9566           //aopPut(AOP(result),
9567           // aopGet(AOP(right),offset,FALSE,FALSE),
9568           // offset);
9569
9570           offset++;
9571         }
9572       }
9573       goto release;
9574     }
9575
9576
9577     /* if the result is of type pointer */
9578     if (IS_PTR(ctype)) {
9579
9580         int p_type;
9581         sym_link *type = operandType(right);
9582         sym_link *etype = getSpec(type);
9583       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9584
9585         /* pointer to generic pointer */
9586         if (IS_GENPTR(ctype)) {
9587             char *l = zero;
9588             
9589             if (IS_PTR(type)) 
9590                 p_type = DCL_TYPE(type);
9591             else {
9592                 /* we have to go by the storage class */
9593                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9594
9595 /*              if (SPEC_OCLS(etype)->codesp )  */
9596 /*                  p_type = CPOINTER ;  */
9597 /*              else */
9598 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9599 /*                      p_type = FPOINTER ; */
9600 /*                  else */
9601 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9602 /*                          p_type = PPOINTER; */
9603 /*                      else */
9604 /*                          if (SPEC_OCLS(etype) == idata ) */
9605 /*                              p_type = IPOINTER ; */
9606 /*                          else */
9607 /*                              p_type = POINTER ; */
9608             }
9609                 
9610             /* the first two bytes are known */
9611       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9612             size = GPTRSIZE - 1; 
9613             offset = 0 ;
9614             while (size--) {
9615               if(offset < AOP_SIZE(right)) {
9616       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9617                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9618                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9619                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9620                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9621                 } else { 
9622                   aopPut(AOP(result),
9623                          aopGet(AOP(right),offset,FALSE,FALSE),
9624                          offset);
9625                 }
9626               } else 
9627                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9628               offset++;
9629             }
9630             /* the last byte depending on type */
9631             switch (p_type) {
9632             case IPOINTER:
9633             case POINTER:
9634                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9635                 break;
9636             case FPOINTER:
9637               pic14_emitcode(";BUG!? ","%d",__LINE__);
9638                 l = one;
9639                 break;
9640             case CPOINTER:
9641               pic14_emitcode(";BUG!? ","%d",__LINE__);
9642                 l = "#0x02";
9643                 break;                          
9644             case PPOINTER:
9645               pic14_emitcode(";BUG!? ","%d",__LINE__);
9646                 l = "#0x03";
9647                 break;
9648                 
9649             default:
9650                 /* this should never happen */
9651                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9652                        "got unknown pointer type");
9653                 exit(1);
9654             }
9655             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9656             goto release ;
9657         }
9658         
9659         /* just copy the pointers */
9660         size = AOP_SIZE(result);
9661         offset = 0 ;
9662         while (size--) {
9663             aopPut(AOP(result),
9664                    aopGet(AOP(right),offset,FALSE,FALSE),
9665                    offset);
9666             offset++;
9667         }
9668         goto release ;
9669     }
9670     
9671
9672
9673     /* so we now know that the size of destination is greater
9674     than the size of the source.
9675     Now, if the next iCode is an operator then we might be
9676     able to optimize the operation without performing a cast.
9677     */
9678     if(genMixedOperation(ic))
9679       goto release;
9680
9681     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9682     
9683     /* we move to result for the size of source */
9684     size = AOP_SIZE(right);
9685     offset = 0 ;
9686     while (size--) {
9687       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9688       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9689       offset++;
9690     }
9691
9692     /* now depending on the sign of the destination */
9693     size = AOP_SIZE(result) - AOP_SIZE(right);
9694     /* if unsigned or not an integral type */
9695     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9696       while (size--)
9697         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9698     } else {
9699       /* we need to extend the sign :{ */
9700
9701       if(size == 1) {
9702         /* Save one instruction of casting char to int */
9703         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9704         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9705         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9706       } else {
9707         emitpcodeNULLop(POC_CLRW);
9708
9709         if(offset)
9710           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9711         else
9712           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9713         
9714         emitpcode(POC_MOVLW,   popGetLit(0xff));
9715
9716         while (size--)
9717           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9718       }
9719     }
9720
9721 release:
9722     freeAsmop(right,NULL,ic,TRUE);
9723     freeAsmop(result,NULL,ic,TRUE);
9724
9725 }
9726
9727 /*-----------------------------------------------------------------*/
9728 /* genDjnz - generate decrement & jump if not zero instrucion      */
9729 /*-----------------------------------------------------------------*/
9730 static int genDjnz (iCode *ic, iCode *ifx)
9731 {
9732     symbol *lbl, *lbl1;
9733     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9734
9735     if (!ifx)
9736         return 0;
9737     
9738     /* if the if condition has a false label
9739        then we cannot save */
9740     if (IC_FALSE(ifx))
9741         return 0;
9742
9743     /* if the minus is not of the form 
9744        a = a - 1 */
9745     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9746         !IS_OP_LITERAL(IC_RIGHT(ic)))
9747         return 0;
9748
9749     if (operandLitValue(IC_RIGHT(ic)) != 1)
9750         return 0;
9751
9752     /* if the size of this greater than one then no
9753        saving */
9754     if (getSize(operandType(IC_RESULT(ic))) > 1)
9755         return 0;
9756
9757     /* otherwise we can save BIG */
9758     lbl = newiTempLabel(NULL);
9759     lbl1= newiTempLabel(NULL);
9760
9761     aopOp(IC_RESULT(ic),ic,FALSE);
9762     
9763     if (IS_AOP_PREG(IC_RESULT(ic))) {
9764         pic14_emitcode("dec","%s",
9765                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9766         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9767         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9768     } else {    
9769
9770
9771       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9772       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9773
9774       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9775       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9776
9777     }
9778 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9779 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9780 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9781 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9782
9783     
9784     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9785     ifx->generated = 1;
9786     return 1;
9787 }
9788
9789 /*-----------------------------------------------------------------*/
9790 /* genReceive - generate code for a receive iCode                  */
9791 /*-----------------------------------------------------------------*/
9792 static void genReceive (iCode *ic)
9793 {    
9794   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9795
9796   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9797       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9798         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9799
9800     int size = getSize(operandType(IC_RESULT(ic)));
9801     int offset =  fReturnSizePic - size;
9802     while (size--) {
9803       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9804                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9805       offset++;
9806     }
9807     aopOp(IC_RESULT(ic),ic,FALSE);  
9808     size = AOP_SIZE(IC_RESULT(ic));
9809     offset = 0;
9810     while (size--) {
9811       pic14_emitcode ("pop","acc");
9812       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9813     }
9814         
9815   } else {
9816     _G.accInUse++;
9817     aopOp(IC_RESULT(ic),ic,FALSE);  
9818     _G.accInUse--;
9819     assignResultValue(IC_RESULT(ic));   
9820   }
9821
9822   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9823 }
9824
9825 /*-----------------------------------------------------------------*/
9826 /* genpic14Code - generate code for pic14 based controllers        */
9827 /*-----------------------------------------------------------------*/
9828 /*
9829  * At this point, ralloc.c has gone through the iCode and attempted
9830  * to optimize in a way suitable for a PIC. Now we've got to generate
9831  * PIC instructions that correspond to the iCode.
9832  *
9833  * Once the instructions are generated, we'll pass through both the
9834  * peep hole optimizer and the pCode optimizer.
9835  *-----------------------------------------------------------------*/
9836
9837 void genpic14Code (iCode *lic)
9838 {
9839     iCode *ic;
9840     int cln = 0;
9841
9842     lineHead = lineCurr = NULL;
9843
9844     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9845     addpBlock(pb);
9846
9847     /* if debug information required */
9848     if (options.debug && currFunc) { 
9849       if (currFunc) {
9850         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9851         _G.debugLine = 1;
9852         if (IS_STATIC(currFunc->etype)) {
9853           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9854           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9855         } else {
9856           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9857           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9858         }
9859         _G.debugLine = 0;
9860       }
9861     }
9862
9863
9864     for (ic = lic ; ic ; ic = ic->next ) {
9865
9866       DEBUGpic14_emitcode(";ic","");
9867         if ( cln != ic->lineno ) {
9868             if ( options.debug ) {
9869                 _G.debugLine = 1;
9870                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9871                          FileBaseName(ic->filename),ic->lineno,
9872                          ic->level,ic->block);
9873                 _G.debugLine = 0;
9874             }
9875             /*
9876               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9877               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9878               printCLine(ic->filename, ic->lineno));
9879             */
9880             addpCode2pBlock(pb,
9881                             newpCodeCSource(ic->lineno, 
9882                                             ic->filename, 
9883                                             printCLine(ic->filename, ic->lineno)));
9884
9885             cln = ic->lineno ;
9886         }
9887         /* if the result is marked as
9888            spilt and rematerializable or code for
9889            this has already been generated then
9890            do nothing */
9891         if (resultRemat(ic) || ic->generated ) 
9892             continue ;
9893         
9894         /* depending on the operation */
9895         switch (ic->op) {
9896         case '!' :
9897             genNot(ic);
9898             break;
9899             
9900         case '~' :
9901             genCpl(ic);
9902             break;
9903             
9904         case UNARYMINUS:
9905             genUminus (ic);
9906             break;
9907             
9908         case IPUSH:
9909             genIpush (ic);
9910             break;
9911             
9912         case IPOP:
9913             /* IPOP happens only when trying to restore a 
9914                spilt live range, if there is an ifx statement
9915                following this pop then the if statement might
9916                be using some of the registers being popped which
9917                would destory the contents of the register so
9918                we need to check for this condition and handle it */
9919             if (ic->next            && 
9920                 ic->next->op == IFX &&
9921                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9922                 genIfx (ic->next,ic);
9923             else
9924                 genIpop (ic);
9925             break; 
9926             
9927         case CALL:
9928             genCall (ic);
9929             break;
9930             
9931         case PCALL:
9932             genPcall (ic);
9933             break;
9934             
9935         case FUNCTION:
9936             genFunction (ic);
9937             break;
9938             
9939         case ENDFUNCTION:
9940             genEndFunction (ic);
9941             break;
9942             
9943         case RETURN:
9944             genRet (ic);
9945             break;
9946             
9947         case LABEL:
9948             genLabel (ic);
9949             break;
9950             
9951         case GOTO:
9952             genGoto (ic);
9953             break;
9954             
9955         case '+' :
9956             genPlus (ic) ;
9957             break;
9958             
9959         case '-' :
9960             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9961                 genMinus (ic);
9962             break;
9963             
9964         case '*' :
9965             genMult (ic);
9966             break;
9967             
9968         case '/' :
9969             genDiv (ic) ;
9970             break;
9971             
9972         case '%' :
9973             genMod (ic);
9974             break;
9975             
9976         case '>' :
9977             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9978             break;
9979             
9980         case '<' :
9981             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9982             break;
9983             
9984         case LE_OP:
9985         case GE_OP:
9986         case NE_OP:
9987             
9988             /* note these two are xlated by algebraic equivalence
9989                during parsing SDCC.y */
9990             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9991                    "got '>=' or '<=' shouldn't have come here");
9992             break;      
9993             
9994         case EQ_OP:
9995             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9996             break;          
9997             
9998         case AND_OP:
9999             genAndOp (ic);
10000             break;
10001             
10002         case OR_OP:
10003             genOrOp (ic);
10004             break;
10005             
10006         case '^' :
10007             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10008             break;
10009             
10010         case '|' :
10011                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10012             break;
10013             
10014         case BITWISEAND:
10015             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10016             break;
10017             
10018         case INLINEASM:
10019             genInline (ic);
10020             break;
10021             
10022         case RRC:
10023             genRRC (ic);
10024             break;
10025             
10026         case RLC:
10027             genRLC (ic);
10028             break;
10029             
10030         case GETHBIT:
10031             genGetHbit (ic);
10032             break;
10033             
10034         case LEFT_OP:
10035             genLeftShift (ic);
10036             break;
10037             
10038         case RIGHT_OP:
10039             genRightShift (ic);
10040             break;
10041             
10042         case GET_VALUE_AT_ADDRESS:
10043             genPointerGet(ic);
10044             break;
10045             
10046         case '=' :
10047             if (POINTER_SET(ic))
10048                 genPointerSet(ic);
10049             else
10050                 genAssign(ic);
10051             break;
10052             
10053         case IFX:
10054             genIfx (ic,NULL);
10055             break;
10056             
10057         case ADDRESS_OF:
10058             genAddrOf (ic);
10059             break;
10060             
10061         case JUMPTABLE:
10062             genJumpTab (ic);
10063             break;
10064             
10065         case CAST:
10066             genCast (ic);
10067             break;
10068             
10069         case RECEIVE:
10070             genReceive(ic);
10071             break;
10072             
10073         case SEND:
10074             addSet(&_G.sendSet,ic);
10075             break;
10076
10077         default :
10078             ic = ic;
10079         }
10080     }
10081     
10082
10083     /* now we are ready to call the 
10084        peep hole optimizer */
10085     if (!options.nopeep) {
10086       peepHole (&lineHead);
10087     }
10088     /* now do the actual printing */
10089     printLine (lineHead,codeOutFile);
10090
10091 #ifdef PCODE_DEBUG
10092     DFPRINTF((stderr,"printing pBlock\n\n"));
10093     printpBlock(stdout,pb);
10094 #endif
10095
10096     return;
10097 }