The function name in a pointer to function variable was getting declared
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #include "common.h"
40 #include "SDCCpeeph.h"
41 #include "ralloc.h"
42 #include "pcode.h"
43 #include "gen.h"
44
45
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
51
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
55
56 /* max_key keeps track of the largest label number used in 
57    a function. This is then used to adjust the label offset
58    for the next function.
59 */
60 static int max_key=0;
61 static int GpsuedoStkPtr=0;
62
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
67
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69
70 /* this is the down and dirty file with all kinds of 
71    kludgy & hacky stuff. This is what it is all about
72    CODE GENERATION for a specific MCU . some of the
73    routines may be reusable, will have to see */
74
75 static char *zero = "#0x00";
76 static char *one  = "#0x01";
77 static char *spname = "sp";
78
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
83
84 static char *accUse[] = {"a","b"};
85
86 //static short rbank = -1;
87
88 static struct {
89     short r0Pushed;
90     short r1Pushed;
91     short accInUse;
92     short inLine;
93     short debugLine;
94     short nRegsSaved;
95     set *sendSet;
96 } _G;
97
98 /* Resolved ifx structure. This structure stores information
99    about an iCode ifx that makes it easier to generate code.
100 */
101 typedef struct resolvedIfx {
102   symbol *lbl;     /* pointer to a label */
103   int condition;   /* true or false ifx */
104   int generated;   /* set true when the code associated with the ifx
105                     * is generated */
106 } resolvedIfx;
107
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
112
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
115
116 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
120
121 static  pBlock *pb;
122
123 /*-----------------------------------------------------------------*/
124 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
125 /*                 exponent of 2 is returned, otherwise -1 is      */
126 /*                 returned.                                       */
127 /* note that this is similar to the function `powof2' in SDCCsymt  */
128 /* if(n == 2^y)                                                    */
129 /*   return y;                                                     */
130 /* return -1;                                                      */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
133 {
134   if(num) {
135     if( (num & (num-1)) == 0) {
136       int nshifts = -1;
137       while(num) {
138         num>>=1;
139         nshifts++;
140       }
141       return nshifts;
142     }
143   }
144
145   return -1;
146 }
147
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
149 {
150
151   DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
152                        line_no,
153                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
154                        ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
156                        ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
158                        ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159                        ((result) ? AOP_SIZE(result) : 0));
160
161 }
162
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
164 {
165
166   DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
167                        line_no,
168                        ((result) ? AopType(AOP_TYPE(result)) : "-"),
169                        ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170                        ((left)   ? AopType(AOP_TYPE(left)) : "-"),
171                        ((left)   ? (SPEC_USIGN(operandType(left))   ? 'u' : 's') : '-'),
172                        ((right)  ? AopType(AOP_TYPE(right)) : "-"),
173                        ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
174
175 }
176
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
178 {
179     va_list ap;
180     char lb[INITIAL_INLINEASM];  
181     char *lbp = lb;
182
183     if(!debug_verbose)
184       return;
185
186     va_start(ap,fmt);   
187
188     if (inst && *inst) {
189         if (fmt && *fmt)
190             sprintf(lb,"%s\t",inst);
191         else
192             sprintf(lb,"%s",inst);
193         vsprintf(lb+(strlen(lb)),fmt,ap);
194     }  else
195         vsprintf(lb,fmt,ap);
196
197     while (isspace(*lbp)) lbp++;
198
199     if (lbp && *lbp) 
200         lineCurr = (lineCurr ?
201                     connectLine(lineCurr,newLineNode(lb)) :
202                     (lineHead = newLineNode(lb)));
203     lineCurr->isInline = _G.inLine;
204     lineCurr->isDebug  = _G.debugLine;
205
206     addpCode2pBlock(pb,newpCodeCharP(lb));
207
208     va_end(ap);
209 }
210
211
212 void emitpLabel(int key)
213 {
214   addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
215 }
216
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
218 {
219
220   if(pcop)
221     addpCode2pBlock(pb,newpCode(poc,pcop));
222   else
223     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
224 }
225
226 void emitpcodeNULLop(PIC_OPCODE poc)
227 {
228
229   addpCode2pBlock(pb,newpCode(poc,NULL));
230
231 }
232
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple    */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
237 {
238     va_list ap;
239     char lb[INITIAL_INLINEASM];  
240     char *lbp = lb;
241
242     va_start(ap,fmt);   
243
244     if (inst && *inst) {
245         if (fmt && *fmt)
246             sprintf(lb,"%s\t",inst);
247         else
248             sprintf(lb,"%s",inst);
249         vsprintf(lb+(strlen(lb)),fmt,ap);
250     }  else
251         vsprintf(lb,fmt,ap);
252
253     while (isspace(*lbp)) lbp++;
254
255     if (lbp && *lbp) 
256         lineCurr = (lineCurr ?
257                     connectLine(lineCurr,newLineNode(lb)) :
258                     (lineHead = newLineNode(lb)));
259     lineCurr->isInline = _G.inLine;
260     lineCurr->isDebug  = _G.debugLine;
261
262     if(debug_verbose)
263       addpCode2pBlock(pb,newpCodeCharP(lb));
264
265     va_end(ap);
266 }
267
268
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
273 {
274     bool r0iu = FALSE , r1iu = FALSE;
275     bool r0ou = FALSE , r1ou = FALSE;
276
277     /* the logic: if r0 & r1 used in the instruction
278     then we are in trouble otherwise */
279
280     /* first check if r0 & r1 are used by this
281     instruction, in which case we are in trouble */
282     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
284     {
285         goto endOfWorld;      
286     }
287
288     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
290
291     /* if no usage of r0 then return it */
292     if (!r0iu && !r0ou) {
293         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294         (*aopp)->type = AOP_R0;
295         
296         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
297     }
298
299     /* if no usage of r1 then return it */
300     if (!r1iu && !r1ou) {
301         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302         (*aopp)->type = AOP_R1;
303
304         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
305     }    
306
307     /* now we know they both have usage */
308     /* if r0 not used in this instruction */
309     if (!r0iu) {
310         /* push it if not already pushed */
311         if (!_G.r0Pushed) {
312           //pic14_emitcode ("push","%s",
313           //          pic14_regWithIdx(R0_IDX)->dname);
314             _G.r0Pushed++ ;
315         }
316         
317         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318         (*aopp)->type = AOP_R0;
319
320         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
321     }
322
323     /* if r1 not used then */
324
325     if (!r1iu) {
326         /* push it if not already pushed */
327         if (!_G.r1Pushed) {
328           //pic14_emitcode ("push","%s",
329           //          pic14_regWithIdx(R1_IDX)->dname);
330             _G.r1Pushed++ ;
331         }
332         
333         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334         (*aopp)->type = AOP_R1;
335         return pic14_regWithIdx(R1_IDX);
336     }
337
338 endOfWorld :
339     /* I said end of world but not quite end of world yet */
340     /* if this is a result then we can push it on the stack*/
341     if (result) {
342         (*aopp)->type = AOP_STK;    
343         return NULL;
344     }
345
346     /* other wise this is true end of the world */
347     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348            "getFreePtr should never reach here");
349     exit(0);
350 }
351
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp                                  */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
356 {
357     asmop *aop;
358
359     aop = Safe_calloc(1,sizeof(asmop));
360     aop->type = type;
361     return aop;
362 }
363
364 static void genSetDPTR(int n)
365 {
366     if (!n)
367     {
368         pic14_emitcode(";", "Select standard DPTR");
369         pic14_emitcode("mov", "dps, #0x00");
370     }
371     else
372     {
373         pic14_emitcode(";", "Select alternate DPTR");
374         pic14_emitcode("mov", "dps, #0x01");
375     }
376 }
377
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for  */
380 /*              generating code                                    */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
383 {
384   if(!resIfx) 
385     return;
386
387   //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
388
389   resIfx->condition = 1;    /* assume that the ifx is true */
390   resIfx->generated = 0;    /* indicate that the ifx has not been used */
391
392   if(!ifx) {
393     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
394 /*
395     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396                         __FUNCTION__,__LINE__,resIfx->lbl->key);
397 */
398   } else {
399     if(IC_TRUE(ifx)) {
400       resIfx->lbl = IC_TRUE(ifx);
401     } else {
402       resIfx->lbl = IC_FALSE(ifx);
403       resIfx->condition = 0;
404     }
405 /*
406     if(IC_TRUE(ifx)) 
407       DEBUGpic14_emitcode("; ***","ifx true is non-null");
408     if(IC_FALSE(ifx)) 
409       DEBUGpic14_emitcode("; ***","ifx false is non-null");
410 */
411   }
412
413   //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
414
415 }
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type               */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
420 {
421
422     return PTR_TYPE(SPEC_OCLS(etype));
423
424 }
425
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol                                   */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
430 {
431     asmop *aop;
432     memmap *space= SPEC_OCLS(sym->etype);
433
434     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435     /* if already has one */
436     if (sym->aop)
437         return sym->aop;
438
439     /* assign depending on the storage class */
440     /* if it is on the stack or indirectly addressable */
441     /* space we need to assign either r0 or r1 to it   */    
442     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443         sym->aop = aop = newAsmop(0);
444         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445         aop->size = getSize(sym->type);
446
447         /* now assign the address of the variable to 
448         the pointer register */
449         if (aop->type != AOP_STK) {
450
451             if (sym->onStack) {
452                     if ( _G.accInUse )
453                         pic14_emitcode("push","acc");
454
455                     pic14_emitcode("mov","a,_bp");
456                     pic14_emitcode("add","a,#0x%02x",
457                              ((sym->stack < 0) ?
458                               ((char)(sym->stack - _G.nRegsSaved )) :
459                               ((char)sym->stack)) & 0xff);
460                     pic14_emitcode("mov","%s,a",
461                              aop->aopu.aop_ptr->name);
462
463                     if ( _G.accInUse )
464                         pic14_emitcode("pop","acc");
465             } else
466                 pic14_emitcode("mov","%s,#%s",
467                          aop->aopu.aop_ptr->name,
468                          sym->rname);
469             aop->paged = space->paged;
470         } else
471             aop->aopu.aop_stk = sym->stack;
472         return aop;
473     }
474     
475     if (sym->onStack && options.stack10bit)
476     {
477         /* It's on the 10 bit stack, which is located in
478          * far data space.
479          */
480          
481       //DEBUGpic14_emitcode(";","%d",__LINE__);
482
483         if ( _G.accInUse )
484                 pic14_emitcode("push","acc");
485
486         pic14_emitcode("mov","a,_bp");
487         pic14_emitcode("add","a,#0x%02x",
488                  ((sym->stack < 0) ?
489                    ((char)(sym->stack - _G.nRegsSaved )) :
490                    ((char)sym->stack)) & 0xff);
491         
492         genSetDPTR(1);
493         pic14_emitcode ("mov","dpx1,#0x40");
494         pic14_emitcode ("mov","dph1,#0x00");
495         pic14_emitcode ("mov","dpl1, a");
496         genSetDPTR(0);
497         
498         if ( _G.accInUse )
499             pic14_emitcode("pop","acc");
500             
501         sym->aop = aop = newAsmop(AOP_DPTR2);
502         aop->size = getSize(sym->type); 
503         return aop;
504     }
505
506     //DEBUGpic14_emitcode(";","%d",__LINE__);
507     /* if in bit space */
508     if (IN_BITSPACE(space)) {
509         sym->aop = aop = newAsmop (AOP_CRY);
510         aop->aopu.aop_dir = sym->rname ;
511         aop->size = getSize(sym->type);
512         //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
513         return aop;
514     }
515     /* if it is in direct space */
516     if (IN_DIRSPACE(space)) {
517         sym->aop = aop = newAsmop (AOP_DIR);
518         aop->aopu.aop_dir = sym->rname ;
519         aop->size = getSize(sym->type);
520         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
521         return aop;
522     }
523
524     /* special case for a function */
525     if (IS_FUNC(sym->type)) {   
526
527       sym->aop = aop = newAsmop(AOP_PCODE);
528       aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
529       PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
530       PCOI(aop->aopu.pcop)->_function = 1;
531       PCOI(aop->aopu.pcop)->index = 0;
532       aop->size = FPTRSIZE; 
533       /*
534         sym->aop = aop = newAsmop(AOP_IMMD);    
535         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
536         strcpy(aop->aopu.aop_immd,sym->rname);
537         aop->size = FPTRSIZE; 
538       */
539         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
540         return aop;
541     }
542
543
544     /* only remaining is far space */
545     /* in which case DPTR gets the address */
546     sym->aop = aop = newAsmop(AOP_PCODE);
547
548     aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
549     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
550     PCOI(aop->aopu.pcop)->index = 0;
551
552     DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
553                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
554
555     allocDirReg (IC_LEFT(ic));
556
557     aop->size = FPTRSIZE; 
558 /*
559     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
560     sym->aop = aop = newAsmop(AOP_DPTR);
561     pic14_emitcode ("mov","dptr,#%s", sym->rname);
562     aop->size = getSize(sym->type);
563
564     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
565 */
566
567     /* if it is in code space */
568     if (IN_CODESPACE(space))
569         aop->code = 1;
570
571     return aop;     
572 }
573
574 /*-----------------------------------------------------------------*/
575 /* aopForRemat - rematerialzes an object                           */
576 /*-----------------------------------------------------------------*/
577 static asmop *aopForRemat (operand *op) // x symbol *sym)
578 {
579   symbol *sym = OP_SYMBOL(op);
580   iCode *ic = NULL;
581   asmop *aop = newAsmop(AOP_PCODE);
582   int val = 0;
583   int offset = 0;
584
585   ic = sym->rematiCode;
586
587   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
588   if(IS_OP_POINTER(op)) {
589     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
590   }
591   for (;;) {
592     if (ic->op == '+') {
593       val += (int) operandLitValue(IC_RIGHT(ic));
594     } else if (ic->op == '-') {
595       val -= (int) operandLitValue(IC_RIGHT(ic));
596     } else
597       break;
598         
599     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
600   }
601
602   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
603   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
604   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
605   PCOI(aop->aopu.pcop)->index = val;
606
607   DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
608                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
609                       val, IS_PTR_CONST(operandType(op)));
610
611   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
612
613   allocDirReg (IC_LEFT(ic));
614
615   return aop;        
616 }
617
618 int aopIdx (asmop *aop, int offset)
619 {
620   if(!aop)
621     return -1;
622
623   if(aop->type !=  AOP_REG)
624     return -2;
625         
626   return aop->aopu.aop_reg[offset]->rIdx;
627
628 }
629 /*-----------------------------------------------------------------*/
630 /* regsInCommon - two operands have some registers in common       */
631 /*-----------------------------------------------------------------*/
632 static bool regsInCommon (operand *op1, operand *op2)
633 {
634     symbol *sym1, *sym2;
635     int i;
636
637     /* if they have registers in common */
638     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
639         return FALSE ;
640
641     sym1 = OP_SYMBOL(op1);
642     sym2 = OP_SYMBOL(op2);
643
644     if (sym1->nRegs == 0 || sym2->nRegs == 0)
645         return FALSE ;
646
647     for (i = 0 ; i < sym1->nRegs ; i++) {
648         int j;
649         if (!sym1->regs[i])
650             continue ;
651
652         for (j = 0 ; j < sym2->nRegs ;j++ ) {
653             if (!sym2->regs[j])
654                 continue ;
655
656             if (sym2->regs[j] == sym1->regs[i])
657                 return TRUE ;
658         }
659     }
660
661     return FALSE ;
662 }
663
664 /*-----------------------------------------------------------------*/
665 /* operandsEqu - equivalent                                        */
666 /*-----------------------------------------------------------------*/
667 static bool operandsEqu ( operand *op1, operand *op2)
668 {
669     symbol *sym1, *sym2;
670
671     /* if they not symbols */
672     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
673         return FALSE;
674
675     sym1 = OP_SYMBOL(op1);
676     sym2 = OP_SYMBOL(op2);
677
678     /* if both are itemps & one is spilt
679        and the other is not then false */
680     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
681         sym1->isspilt != sym2->isspilt )
682         return FALSE ;
683
684     /* if they are the same */
685     if (sym1 == sym2)
686         return TRUE ;
687
688     if (strcmp(sym1->rname,sym2->rname) == 0)
689         return TRUE;
690
691
692     /* if left is a tmp & right is not */
693     if (IS_ITEMP(op1)  && 
694         !IS_ITEMP(op2) &&
695         sym1->isspilt  &&
696         (sym1->usl.spillLoc == sym2))
697         return TRUE;
698
699     if (IS_ITEMP(op2)  && 
700         !IS_ITEMP(op1) &&
701         sym2->isspilt  &&
702         sym1->level > 0 &&
703         (sym2->usl.spillLoc == sym1))
704         return TRUE ;
705
706     return FALSE ;
707 }
708
709 /*-----------------------------------------------------------------*/
710 /* pic14_sameRegs - two asmops have the same registers                   */
711 /*-----------------------------------------------------------------*/
712 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
713 {
714     int i;
715
716     if (aop1 == aop2)
717         return TRUE ;
718
719     if (aop1->type != AOP_REG ||
720         aop2->type != AOP_REG )
721         return FALSE ;
722
723     if (aop1->size != aop2->size )
724         return FALSE ;
725
726     for (i = 0 ; i < aop1->size ; i++ )
727         if (aop1->aopu.aop_reg[i] !=
728             aop2->aopu.aop_reg[i] )
729             return FALSE ;
730
731     return TRUE ;
732 }
733
734 /*-----------------------------------------------------------------*/
735 /* aopOp - allocates an asmop for an operand  :                    */
736 /*-----------------------------------------------------------------*/
737 void aopOp (operand *op, iCode *ic, bool result)
738 {
739     asmop *aop;
740     symbol *sym;
741     int i;
742
743     if (!op)
744         return ;
745
746     //    DEBUGpic14_emitcode(";","%d",__LINE__);
747     /* if this a literal */
748     if (IS_OP_LITERAL(op)) {
749         op->aop = aop = newAsmop(AOP_LIT);
750         aop->aopu.aop_lit = op->operand.valOperand;
751         aop->size = getSize(operandType(op));
752         return;
753     }
754
755     {
756       sym_link *type = operandType(op);
757       if(IS_PTR_CONST(type))
758         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
759     }
760
761     /* if already has a asmop then continue */
762     if (op->aop)
763         return ;
764
765     /* if the underlying symbol has a aop */
766     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
767       DEBUGpic14_emitcode(";","%d",__LINE__);
768         op->aop = OP_SYMBOL(op)->aop;
769         return;
770     }
771
772     /* if this is a true symbol */
773     if (IS_TRUE_SYMOP(op)) {    
774       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
775       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
776       return ;
777     }
778
779     /* this is a temporary : this has
780     only four choices :
781     a) register
782     b) spillocation
783     c) rematerialize 
784     d) conditional   
785     e) can be a return use only */
786
787     sym = OP_SYMBOL(op);
788
789
790     /* if the type is a conditional */
791     if (sym->regType == REG_CND) {
792         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
793         aop->size = 0;
794         return;
795     }
796
797     /* if it is spilt then two situations
798     a) is rematerialize 
799     b) has a spill location */
800     if (sym->isspilt || sym->nRegs == 0) {
801
802       DEBUGpic14_emitcode(";","%d",__LINE__);
803         /* rematerialize it NOW */
804         if (sym->remat) {
805
806             sym->aop = op->aop = aop =
807                                       aopForRemat (op);
808             aop->size = getSize(sym->type);
809             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
810             return;
811         }
812
813         if (sym->accuse) {
814             int i;
815             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
816             aop->size = getSize(sym->type);
817             for ( i = 0 ; i < 2 ; i++ )
818                 aop->aopu.aop_str[i] = accUse[i];
819             DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
820             return;  
821         }
822
823         if (sym->ruonly ) {
824           if(sym->isptr) {  // && sym->uptr 
825             aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
826             aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
827
828             //PCOI(aop->aopu.pcop)->_const = 0;
829             //PCOI(aop->aopu.pcop)->index = 0;
830             /*
831               DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
832               __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
833             */
834             //allocDirReg (IC_LEFT(ic));
835
836             aop->size = getSize(sym->type);
837             DEBUGpic14_emitcode(";","%d",__LINE__);
838             return;
839
840           } else {
841
842             unsigned i;
843
844             aop = op->aop = sym->aop = newAsmop(AOP_STR);
845             aop->size = getSize(sym->type);
846             for ( i = 0 ; i < fReturnSizePic ; i++ )
847               aop->aopu.aop_str[i] = fReturn[i];
848
849             DEBUGpic14_emitcode(";","%d",__LINE__);
850             return;
851           }
852         }
853
854         /* else spill location  */
855         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
856             /* force a new aop if sizes differ */
857             sym->usl.spillLoc->aop = NULL;
858         }
859         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
860                             __FUNCTION__,__LINE__,
861                             sym->usl.spillLoc->rname,
862                             sym->rname, sym->usl.spillLoc->offset);
863
864         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
865         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
866         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
867                                           getSize(sym->type), 
868                                           sym->usl.spillLoc->offset);
869         aop->size = getSize(sym->type);
870
871         return;
872     }
873
874     {
875       sym_link *type = operandType(op);
876       if(IS_PTR_CONST(type)) 
877         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
878     }
879
880     /* must be in a register */
881     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
882     sym->aop = op->aop = aop = newAsmop(AOP_REG);
883     aop->size = sym->nRegs;
884     for ( i = 0 ; i < sym->nRegs ;i++)
885         aop->aopu.aop_reg[i] = sym->regs[i];
886 }
887
888 /*-----------------------------------------------------------------*/
889 /* freeAsmop - free up the asmop given to an operand               */
890 /*----------------------------------------------------------------*/
891 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
892 {   
893     asmop *aop ;
894
895     if (!op)
896         aop = aaop;
897     else 
898         aop = op->aop;
899
900     if (!aop)
901         return ;
902
903     if (aop->freed)
904         goto dealloc; 
905
906     aop->freed = 1;
907
908     /* depending on the asmop type only three cases need work AOP_RO
909        , AOP_R1 && AOP_STK */
910 #if 0
911     switch (aop->type) {
912         case AOP_R0 :
913             if (_G.r0Pushed ) {
914                 if (pop) {
915                     pic14_emitcode ("pop","ar0");     
916                     _G.r0Pushed--;
917                 }
918             }
919             bitVectUnSetBit(ic->rUsed,R0_IDX);
920             break;
921
922         case AOP_R1 :
923             if (_G.r1Pushed ) {
924                 if (pop) {
925                     pic14_emitcode ("pop","ar1");
926                     _G.r1Pushed--;
927                 }
928             }
929             bitVectUnSetBit(ic->rUsed,R1_IDX);          
930             break;
931
932         case AOP_STK :
933         {
934             int sz = aop->size;    
935             int stk = aop->aopu.aop_stk + aop->size;
936             bitVectUnSetBit(ic->rUsed,R0_IDX);
937             bitVectUnSetBit(ic->rUsed,R1_IDX);          
938
939             getFreePtr(ic,&aop,FALSE);
940             
941             if (options.stack10bit)
942             {
943                 /* I'm not sure what to do here yet... */
944                 /* #STUB */
945                 fprintf(stderr, 
946                         "*** Warning: probably generating bad code for "
947                         "10 bit stack mode.\n");
948             }
949             
950             if (stk) {
951                 pic14_emitcode ("mov","a,_bp");
952                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
953                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
954             } else {
955                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
956             }
957
958             while (sz--) {
959                 pic14_emitcode("pop","acc");
960                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
961                 if (!sz) break;
962                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
963             }
964             op->aop = aop;
965             freeAsmop(op,NULL,ic,TRUE);
966             if (_G.r0Pushed) {
967                 pic14_emitcode("pop","ar0");
968                 _G.r0Pushed--;
969             }
970
971             if (_G.r1Pushed) {
972                 pic14_emitcode("pop","ar1");
973                 _G.r1Pushed--;
974             }       
975         }
976     }
977 #endif
978
979 dealloc:
980     /* all other cases just dealloc */
981     if (op ) {
982         op->aop = NULL;
983         if (IS_SYMOP(op)) {
984             OP_SYMBOL(op)->aop = NULL;    
985             /* if the symbol has a spill */
986             if (SPIL_LOC(op))
987                 SPIL_LOC(op)->aop = NULL;
988         }
989     }
990 }
991
992 /*-----------------------------------------------------------------*/
993 /* aopGet - for fetching value of the aop                          */
994 /*-----------------------------------------------------------------*/
995 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
996 {
997     char *s = buffer ;
998     char *rs;
999
1000     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1001     /* offset is greater than
1002     size then zero */
1003     if (offset > (aop->size - 1) &&
1004         aop->type != AOP_LIT)
1005         return zero;
1006
1007     /* depending on type */
1008     switch (aop->type) {
1009         
1010     case AOP_R0:
1011     case AOP_R1:
1012         DEBUGpic14_emitcode(";","%d",__LINE__);
1013         /* if we need to increment it */       
1014         while (offset > aop->coff) {        
1015             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
1016             aop->coff++;
1017         }
1018         
1019         while (offset < aop->coff) {
1020             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1021             aop->coff--;
1022         }
1023         
1024         aop->coff = offset ;
1025         if (aop->paged) {
1026             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1027             return (dname ? "acc" : "a");
1028         }       
1029         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1030         rs = Safe_calloc(1,strlen(s)+1);
1031         strcpy(rs,s);   
1032         return rs;
1033         
1034     case AOP_DPTR:
1035     case AOP_DPTR2:
1036         DEBUGpic14_emitcode(";","%d",__LINE__);
1037     if (aop->type == AOP_DPTR2)
1038     {
1039         genSetDPTR(1);
1040     }
1041     
1042         while (offset > aop->coff) {
1043             pic14_emitcode ("inc","dptr");
1044             aop->coff++;
1045         }
1046         
1047         while (offset < aop->coff) {        
1048             pic14_emitcode("lcall","__decdptr");
1049             aop->coff--;
1050         }
1051         
1052         aop->coff = offset;
1053         if (aop->code) {
1054             pic14_emitcode("clr","a");
1055             pic14_emitcode("movc","a,@a+dptr");
1056         }
1057     else {
1058             pic14_emitcode("movx","a,@dptr");
1059     }
1060             
1061     if (aop->type == AOP_DPTR2)
1062     {
1063         genSetDPTR(0);
1064     }
1065             
1066     return (dname ? "acc" : "a");
1067         
1068         
1069     case AOP_IMMD:
1070         if (bit16) 
1071             sprintf (s,"%s",aop->aopu.aop_immd);
1072         else
1073             if (offset) 
1074                 sprintf(s,"(%s >> %d)",
1075                         aop->aopu.aop_immd,
1076                         offset*8);
1077             else
1078                 sprintf(s,"%s",
1079                         aop->aopu.aop_immd);
1080         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1081         rs = Safe_calloc(1,strlen(s)+1);
1082         strcpy(rs,s);   
1083         return rs;
1084         
1085     case AOP_DIR:
1086       if (offset) {
1087         sprintf(s,"(%s + %d)",
1088                 aop->aopu.aop_dir,
1089                 offset);
1090         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1091       } else
1092             sprintf(s,"%s",aop->aopu.aop_dir);
1093         rs = Safe_calloc(1,strlen(s)+1);
1094         strcpy(rs,s);   
1095         return rs;
1096         
1097     case AOP_REG:
1098       //if (dname) 
1099       //    return aop->aopu.aop_reg[offset]->dname;
1100       //else
1101             return aop->aopu.aop_reg[offset]->name;
1102         
1103     case AOP_CRY:
1104       //pic14_emitcode(";","%d",__LINE__);
1105       return aop->aopu.aop_dir;
1106         
1107     case AOP_ACC:
1108         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1109         return "AOP_accumulator_bug";
1110
1111     case AOP_LIT:
1112         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1113         rs = Safe_calloc(1,strlen(s)+1);
1114         strcpy(rs,s);   
1115         return rs;
1116         
1117     case AOP_STR:
1118         aop->coff = offset ;
1119         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1120             dname)
1121             return "acc";
1122         DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1123         
1124         return aop->aopu.aop_str[offset];
1125         
1126     case AOP_PCODE:
1127       {
1128         pCodeOp *pcop = aop->aopu.pcop;
1129         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1130         if(pcop->name) {
1131           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1132           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1133           sprintf(s,"%s", pcop->name);
1134         } else
1135           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1136
1137       }
1138       rs = Safe_calloc(1,strlen(s)+1);
1139       strcpy(rs,s);   
1140       return rs;
1141
1142     }
1143
1144     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1145            "aopget got unsupported aop->type");
1146     exit(0);
1147 }
1148
1149
1150 /*-----------------------------------------------------------------*/
1151 /* popGetTempReg - create a new temporary pCodeOp                  */
1152 /*-----------------------------------------------------------------*/
1153 pCodeOp *popGetTempReg(void)
1154 {
1155
1156   pCodeOp *pcop;
1157
1158   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1159   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1160     PCOR(pcop)->r->wasUsed=1;
1161     PCOR(pcop)->r->isFree=0;
1162   }
1163
1164   return pcop;
1165 }
1166
1167 /*-----------------------------------------------------------------*/
1168 /* popGetTempReg - create a new temporary pCodeOp                  */
1169 /*-----------------------------------------------------------------*/
1170 void popReleaseTempReg(pCodeOp *pcop)
1171 {
1172
1173   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1174     PCOR(pcop)->r->isFree = 1;
1175
1176 }
1177 /*-----------------------------------------------------------------*/
1178 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1179 /*-----------------------------------------------------------------*/
1180 pCodeOp *popGetLabel(unsigned int key)
1181 {
1182
1183   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1184
1185   if(key>max_key)
1186     max_key = key;
1187
1188   return newpCodeOpLabel(NULL,key+100+labelOffset);
1189 }
1190
1191 /*-----------------------------------------------------------------*/
1192 /* popCopyReg - copy a pcode operator                              */
1193 /*-----------------------------------------------------------------*/
1194 pCodeOp *popCopyReg(pCodeOpReg *pc)
1195 {
1196   pCodeOpReg *pcor;
1197
1198   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1199   pcor->pcop.type = pc->pcop.type;
1200   if(pc->pcop.name) {
1201     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1202       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1203   } else
1204     pcor->pcop.name = NULL;
1205
1206   pcor->r = pc->r;
1207   pcor->rIdx = pc->rIdx;
1208   pcor->r->wasUsed=1;
1209
1210   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1211
1212   return PCOP(pcor);
1213 }
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion              */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1218 {
1219
1220   return newpCodeOpLit(lit);
1221 }
1222
1223
1224 /*-----------------------------------------------------------------*/
1225 /* popGetImmd - asm operator to pcode immediate conversion         */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1228 {
1229
1230   return newpCodeOpImmd(name, offset,index, 0, is_func);
1231 }
1232
1233
1234 /*-----------------------------------------------------------------*/
1235 /* popGet - asm operator to pcode operator conversion              */
1236 /*-----------------------------------------------------------------*/
1237 pCodeOp *popGetWithString(char *str)
1238 {
1239   pCodeOp *pcop;
1240
1241
1242   if(!str) {
1243     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1244     exit (1);
1245   }
1246
1247   pcop = newpCodeOp(str,PO_STR);
1248
1249   return pcop;
1250 }
1251
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString -                                              */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1256 {
1257
1258   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259   pcop->type = PO_DIR;
1260
1261   DEBUGpic14_emitcode(";","%d",__LINE__);
1262
1263   if(!str)
1264     str = "BAD_STRING";
1265
1266   pcop->name = Safe_calloc(1,strlen(str)+1);
1267   strcpy(pcop->name,str);
1268
1269   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1270
1271   PCOR(pcop)->r = dirregWithName(pcop->name);
1272   if(PCOR(pcop)->r == NULL) {
1273     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1276   } else {
1277     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1278   }
1279   PCOR(pcop)->instance = offset;
1280
1281   return pcop;
1282 }
1283
1284 pCodeOp *popRegFromIdx(int rIdx)
1285 {
1286   pCodeOp *pcop;
1287
1288   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1289                        __FUNCTION__,__LINE__,rIdx);
1290
1291   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1292
1293   PCOR(pcop)->rIdx = rIdx;
1294   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1295   PCOR(pcop)->r->isFree = 0;
1296   PCOR(pcop)->r->wasUsed = 1;
1297
1298   pcop->type = PCOR(pcop)->r->pc_type;
1299
1300
1301   return pcop;
1302 }
1303 /*-----------------------------------------------------------------*/
1304 /* popGet - asm operator to pcode operator conversion              */
1305 /*-----------------------------------------------------------------*/
1306 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1307 {
1308   //char *s = buffer ;
1309     //char *rs;
1310
1311     pCodeOp *pcop;
1312
1313     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1314     /* offset is greater than
1315     size then zero */
1316
1317     if (offset > (aop->size - 1) &&
1318         aop->type != AOP_LIT)
1319       return NULL;  //zero;
1320
1321     /* depending on type */
1322     switch (aop->type) {
1323         
1324     case AOP_R0:
1325     case AOP_R1:
1326     case AOP_DPTR:
1327     case AOP_DPTR2:
1328     case AOP_ACC:
1329         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1330         return NULL;
1331         
1332     case AOP_IMMD:
1333       DEBUGpic14_emitcode(";","%d",__LINE__);
1334       return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1335
1336     case AOP_DIR:
1337       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1338 #if 0
1339         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1340         pcop->type = PO_DIR;
1341
1342         /*
1343         if (offset)
1344             sprintf(s,"(%s + %d)",
1345                     aop->aopu.aop_dir,
1346                     offset);
1347         else
1348             sprintf(s,"%s",aop->aopu.aop_dir);
1349         pcop->name = Safe_calloc(1,strlen(s)+1);
1350         strcpy(pcop->name,s);   
1351         */
1352         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1353         strcpy(pcop->name,aop->aopu.aop_dir);   
1354         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1355         if(PCOR(pcop)->r == NULL) {
1356           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1357           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1358           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1359         } else {
1360           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1361         }
1362         PCOR(pcop)->instance = offset;
1363
1364         return pcop;
1365 #endif
1366         
1367     case AOP_REG:
1368       {
1369         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1370
1371         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1372         PCOR(pcop)->rIdx = rIdx;
1373         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1374         PCOR(pcop)->r->wasUsed=1;
1375         PCOR(pcop)->r->isFree=0;
1376
1377         PCOR(pcop)->instance = offset;
1378         pcop->type = PCOR(pcop)->r->pc_type;
1379         //rs = aop->aopu.aop_reg[offset]->name;
1380         DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1381         return pcop;
1382       }
1383
1384     case AOP_CRY:
1385       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1386       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1387       //if(PCOR(pcop)->r == NULL)
1388       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1389       return pcop;
1390         
1391     case AOP_LIT:
1392       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1393
1394     case AOP_STR:
1395       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1396       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1397       /*
1398       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1399       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1400       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1401       pcop->type = PCOR(pcop)->r->pc_type;
1402       pcop->name = PCOR(pcop)->r->name;
1403
1404       return pcop;
1405       */
1406
1407     case AOP_PCODE:
1408       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1409                           __LINE__, 
1410                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1411       pcop = pCodeOpCopy(aop->aopu.pcop);
1412       PCOI(pcop)->offset = offset;
1413       return pcop;
1414     }
1415
1416     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1417            "popGet got unsupported aop->type");
1418     exit(0);
1419 }
1420 /*-----------------------------------------------------------------*/
1421 /* aopPut - puts a string for a aop                                */
1422 /*-----------------------------------------------------------------*/
1423 void aopPut (asmop *aop, char *s, int offset)
1424 {
1425     char *d = buffer ;
1426     symbol *lbl ;
1427
1428     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1429
1430     if (aop->size && offset > ( aop->size - 1)) {
1431         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1432                "aopPut got offset > aop->size");
1433         exit(0);
1434     }
1435
1436     /* will assign value to value */
1437     /* depending on where it is ofcourse */
1438     switch (aop->type) {
1439     case AOP_DIR:
1440       if (offset) {
1441         sprintf(d,"(%s + %d)",
1442                 aop->aopu.aop_dir,offset);
1443         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1444
1445       } else
1446             sprintf(d,"%s",aop->aopu.aop_dir);
1447         
1448         if (strcmp(d,s)) {
1449           DEBUGpic14_emitcode(";","%d",__LINE__);
1450           if(strcmp(s,"W"))
1451             pic14_emitcode("movf","%s,w",s);
1452           pic14_emitcode("movwf","%s",d);
1453
1454           if(strcmp(s,"W")) {
1455             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1456             if(offset >= aop->size) {
1457               emitpcode(POC_CLRF,popGet(aop,offset));
1458               break;
1459             } else
1460               emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1461           }
1462
1463           emitpcode(POC_MOVWF,popGet(aop,offset));
1464
1465
1466         }
1467         break;
1468         
1469     case AOP_REG:
1470       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1471         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1472           /*
1473             if (*s == '@'           ||
1474                 strcmp(s,"r0") == 0 ||
1475                 strcmp(s,"r1") == 0 ||
1476                 strcmp(s,"r2") == 0 ||
1477                 strcmp(s,"r3") == 0 ||
1478                 strcmp(s,"r4") == 0 ||
1479                 strcmp(s,"r5") == 0 ||
1480                 strcmp(s,"r6") == 0 || 
1481                 strcmp(s,"r7") == 0 )
1482                 pic14_emitcode("mov","%s,%s  ; %d",
1483                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1484             else
1485           */
1486
1487           if(strcmp(s,"W")==0 )
1488             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1489
1490           pic14_emitcode("movwf","%s",
1491                    aop->aopu.aop_reg[offset]->name);
1492
1493           if(strcmp(s,zero)==0) {
1494             emitpcode(POC_CLRF,popGet(aop,offset));
1495
1496           } else if(strcmp(s,"W")==0) {
1497             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1498             pcop->type = PO_GPR_REGISTER;
1499
1500             PCOR(pcop)->rIdx = -1;
1501             PCOR(pcop)->r = NULL;
1502
1503             DEBUGpic14_emitcode(";","%d",__LINE__);
1504             pcop->name = Safe_strdup(s);
1505             emitpcode(POC_MOVFW,pcop);
1506             emitpcode(POC_MOVWF,popGet(aop,offset));
1507           } else if(strcmp(s,one)==0) {
1508             emitpcode(POC_CLRF,popGet(aop,offset));
1509             emitpcode(POC_INCF,popGet(aop,offset));
1510           } else {
1511             emitpcode(POC_MOVWF,popGet(aop,offset));
1512           }
1513         }
1514         break;
1515         
1516     case AOP_DPTR:
1517     case AOP_DPTR2:
1518     
1519     if (aop->type == AOP_DPTR2)
1520     {
1521         genSetDPTR(1);
1522     }
1523     
1524         if (aop->code) {
1525             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1526                    "aopPut writting to code space");
1527             exit(0);
1528         }
1529         
1530         while (offset > aop->coff) {
1531             aop->coff++;
1532             pic14_emitcode ("inc","dptr");
1533         }
1534         
1535         while (offset < aop->coff) {
1536             aop->coff-- ;
1537             pic14_emitcode("lcall","__decdptr");
1538         }
1539         
1540         aop->coff = offset;
1541         
1542         /* if not in accumulater */
1543         MOVA(s);        
1544         
1545         pic14_emitcode ("movx","@dptr,a");
1546         
1547     if (aop->type == AOP_DPTR2)
1548     {
1549         genSetDPTR(0);
1550     }
1551         break;
1552         
1553     case AOP_R0:
1554     case AOP_R1:
1555         while (offset > aop->coff) {
1556             aop->coff++;
1557             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1558         }
1559         while (offset < aop->coff) {
1560             aop->coff-- ;
1561             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1562         }
1563         aop->coff = offset;
1564         
1565         if (aop->paged) {
1566             MOVA(s);           
1567             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1568             
1569         } else
1570             if (*s == '@') {
1571                 MOVA(s);
1572                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1573             } else
1574                 if (strcmp(s,"r0") == 0 ||
1575                     strcmp(s,"r1") == 0 ||
1576                     strcmp(s,"r2") == 0 ||
1577                     strcmp(s,"r3") == 0 ||
1578                     strcmp(s,"r4") == 0 ||
1579                     strcmp(s,"r5") == 0 ||
1580                     strcmp(s,"r6") == 0 || 
1581                     strcmp(s,"r7") == 0 ) {
1582                     char buffer[10];
1583                     sprintf(buffer,"a%s",s);
1584                     pic14_emitcode("mov","@%s,%s",
1585                              aop->aopu.aop_ptr->name,buffer);
1586                 } else
1587                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1588         
1589         break;
1590         
1591     case AOP_STK:
1592         if (strcmp(s,"a") == 0)
1593             pic14_emitcode("push","acc");
1594         else
1595             pic14_emitcode("push","%s",s);
1596         
1597         break;
1598         
1599     case AOP_CRY:
1600         /* if bit variable */
1601         if (!aop->aopu.aop_dir) {
1602             pic14_emitcode("clr","a");
1603             pic14_emitcode("rlc","a");
1604         } else {
1605             if (s == zero) 
1606                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1607             else
1608                 if (s == one)
1609                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1610                 else
1611                     if (!strcmp(s,"c"))
1612                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1613                     else {
1614                         lbl = newiTempLabel(NULL);
1615                         
1616                         if (strcmp(s,"a")) {
1617                             MOVA(s);
1618                         }
1619                         pic14_emitcode("clr","c");
1620                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1621                         pic14_emitcode("cpl","c");
1622                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1623                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1624                     }
1625         }
1626         break;
1627         
1628     case AOP_STR:
1629         aop->coff = offset;
1630         if (strcmp(aop->aopu.aop_str[offset],s))
1631             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1632         break;
1633         
1634     case AOP_ACC:
1635         aop->coff = offset;
1636         if (!offset && (strcmp(s,"acc") == 0))
1637             break;
1638         
1639         if (strcmp(aop->aopu.aop_str[offset],s))
1640             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1641         break;
1642
1643     default :
1644         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1645                "aopPut got unsupported aop->type");
1646         exit(0);    
1647     }    
1648
1649 }
1650
1651 /*-----------------------------------------------------------------*/
1652 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1653 /*-----------------------------------------------------------------*/
1654 void mov2w (asmop *aop, int offset)
1655 {
1656
1657   if(!aop)
1658     return;
1659
1660   DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1661
1662   if ( aop->type == AOP_PCODE ||
1663        aop->type == AOP_LIT ||
1664        aop->type == AOP_IMMD )
1665     emitpcode(POC_MOVLW,popGet(aop,offset));
1666   else
1667     emitpcode(POC_MOVFW,popGet(aop,offset));
1668
1669 }
1670
1671 /*-----------------------------------------------------------------*/
1672 /* reAdjustPreg - points a register back to where it should        */
1673 /*-----------------------------------------------------------------*/
1674 static void reAdjustPreg (asmop *aop)
1675 {
1676     int size ;
1677
1678     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1679     aop->coff = 0;
1680     if ((size = aop->size) <= 1)
1681         return ;
1682     size-- ;
1683     switch (aop->type) {
1684         case AOP_R0 :
1685         case AOP_R1 :
1686             while (size--)
1687                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1688             break;          
1689         case AOP_DPTR :
1690         case AOP_DPTR2:
1691             if (aop->type == AOP_DPTR2)
1692             {
1693                 genSetDPTR(1);
1694             } 
1695             while (size--)
1696             {
1697                 pic14_emitcode("lcall","__decdptr");
1698             }
1699                 
1700             if (aop->type == AOP_DPTR2)
1701             {
1702                 genSetDPTR(0);
1703             }                
1704             break;  
1705
1706     }   
1707
1708 }
1709
1710 /*-----------------------------------------------------------------*/
1711 /* genNotFloat - generates not for float operations              */
1712 /*-----------------------------------------------------------------*/
1713 static void genNotFloat (operand *op, operand *res)
1714 {
1715     int size, offset;
1716     char *l;
1717     symbol *tlbl ;
1718
1719     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1720     /* we will put 127 in the first byte of 
1721     the result */
1722     aopPut(AOP(res),"#127",0);
1723     size = AOP_SIZE(op) - 1;
1724     offset = 1;
1725
1726     l = aopGet(op->aop,offset++,FALSE,FALSE);
1727     MOVA(l);    
1728
1729     while(size--) {
1730         pic14_emitcode("orl","a,%s",
1731                  aopGet(op->aop,
1732                         offset++,FALSE,FALSE));
1733     }
1734     tlbl = newiTempLabel(NULL);
1735
1736     tlbl = newiTempLabel(NULL);
1737     aopPut(res->aop,one,1);
1738     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1739     aopPut(res->aop,zero,1);
1740     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1741
1742     size = res->aop->size - 2;
1743     offset = 2;    
1744     /* put zeros in the rest */
1745     while (size--) 
1746         aopPut(res->aop,zero,offset++);
1747 }
1748
1749 #if 0
1750 /*-----------------------------------------------------------------*/
1751 /* opIsGptr: returns non-zero if the passed operand is             */   
1752 /* a generic pointer type.                                         */
1753 /*-----------------------------------------------------------------*/ 
1754 static int opIsGptr(operand *op)
1755 {
1756     sym_link *type = operandType(op);
1757     
1758     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1759     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1760     {
1761         return 1;
1762     }
1763     return 0;        
1764 }
1765 #endif
1766
1767 /*-----------------------------------------------------------------*/
1768 /* pic14_getDataSize - get the operand data size                         */
1769 /*-----------------------------------------------------------------*/
1770 int pic14_getDataSize(operand *op)
1771 {
1772     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1773
1774
1775     return AOP_SIZE(op);
1776
1777     // tsd- in the pic port, the genptr size is 1, so this code here
1778     // fails. ( in the 8051 port, the size was 4).
1779 #if 0
1780     int size;
1781     size = AOP_SIZE(op);
1782     if (size == GPTRSIZE)
1783     {
1784         sym_link *type = operandType(op);
1785         if (IS_GENPTR(type))
1786         {
1787             /* generic pointer; arithmetic operations
1788              * should ignore the high byte (pointer type).
1789              */
1790             size--;
1791     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1792         }
1793     }
1794     return size;
1795 #endif
1796 }
1797
1798 /*-----------------------------------------------------------------*/
1799 /* pic14_outAcc - output Acc                                             */
1800 /*-----------------------------------------------------------------*/
1801 void pic14_outAcc(operand *result)
1802 {
1803   int size,offset;
1804   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1805   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1806
1807
1808   size = pic14_getDataSize(result);
1809   if(size){
1810     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1811     size--;
1812     offset = 1;
1813     /* unsigned or positive */
1814     while(size--)
1815       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1816   }
1817
1818 }
1819
1820 /*-----------------------------------------------------------------*/
1821 /* pic14_outBitC - output a bit C                                        */
1822 /*-----------------------------------------------------------------*/
1823 void pic14_outBitC(operand *result)
1824 {
1825
1826     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1827     /* if the result is bit */
1828     if (AOP_TYPE(result) == AOP_CRY) 
1829         aopPut(AOP(result),"c",0);
1830     else {
1831         pic14_emitcode("clr","a  ; %d", __LINE__);
1832         pic14_emitcode("rlc","a");
1833         pic14_outAcc(result);
1834     }
1835 }
1836
1837 /*-----------------------------------------------------------------*/
1838 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1839 /*-----------------------------------------------------------------*/
1840 void pic14_toBoolean(operand *oper)
1841 {
1842     int size = AOP_SIZE(oper) - 1;
1843     int offset = 1;
1844
1845     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1846
1847     if ( AOP_TYPE(oper) != AOP_ACC) {
1848       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1849     }
1850     while (size--) {
1851       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1852     }
1853 }
1854
1855
1856 /*-----------------------------------------------------------------*/
1857 /* genNot - generate code for ! operation                          */
1858 /*-----------------------------------------------------------------*/
1859 static void genNot (iCode *ic)
1860 {
1861   symbol *tlbl;
1862   sym_link *optype = operandType(IC_LEFT(ic));
1863   int size;
1864
1865   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1866   /* assign asmOps to operand & result */
1867   aopOp (IC_LEFT(ic),ic,FALSE);
1868   aopOp (IC_RESULT(ic),ic,TRUE);
1869
1870   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1871   /* if in bit space then a special case */
1872   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1873     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1874       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1875       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1876     } else {
1877       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1878       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1879       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1880     }
1881     goto release;
1882   }
1883
1884   /* if type float then do float */
1885   if (IS_FLOAT(optype)) {
1886     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1887     goto release;
1888   }
1889
1890   size = AOP_SIZE(IC_RESULT(ic));
1891   if(size == 1) {
1892     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1893     emitpcode(POC_ANDLW,popGetLit(1));
1894     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1895     goto release;
1896   }
1897   pic14_toBoolean(IC_LEFT(ic));
1898
1899   tlbl = newiTempLabel(NULL);
1900   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1901   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1902   pic14_outBitC(IC_RESULT(ic));
1903
1904  release:    
1905   /* release the aops */
1906   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1907   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1908 }
1909
1910
1911 /*-----------------------------------------------------------------*/
1912 /* genCpl - generate code for complement                           */
1913 /*-----------------------------------------------------------------*/
1914 static void genCpl (iCode *ic)
1915 {
1916   operand *left, *result;
1917   int size, offset=0;  
1918
1919
1920   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1921   aopOp((left = IC_LEFT(ic)),ic,FALSE);
1922   aopOp((result=IC_RESULT(ic)),ic,TRUE);
1923
1924   /* if both are in bit space then 
1925      a special case */
1926   if (AOP_TYPE(result) == AOP_CRY &&
1927       AOP_TYPE(left) == AOP_CRY ) { 
1928
1929     pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1930     pic14_emitcode("cpl","c"); 
1931     pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1932     goto release; 
1933   } 
1934
1935   size = AOP_SIZE(result);
1936   while (size--) {
1937
1938     if(AOP_TYPE(left) == AOP_ACC) 
1939       emitpcode(POC_XORLW, popGetLit(0xff));
1940     else
1941       emitpcode(POC_COMFW,popGet(AOP(left),offset));
1942
1943     emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1944
1945   }
1946
1947
1948 release:
1949     /* release the aops */
1950     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1951     freeAsmop(result,NULL,ic,TRUE);
1952 }
1953
1954 /*-----------------------------------------------------------------*/
1955 /* genUminusFloat - unary minus for floating points                */
1956 /*-----------------------------------------------------------------*/
1957 static void genUminusFloat(operand *op,operand *result)
1958 {
1959     int size ,offset =0 ;
1960     char *l;
1961
1962     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1963     /* for this we just need to flip the 
1964     first it then copy the rest in place */
1965     size = AOP_SIZE(op) - 1;
1966     l = aopGet(AOP(op),3,FALSE,FALSE);
1967
1968     MOVA(l);    
1969
1970     pic14_emitcode("cpl","acc.7");
1971     aopPut(AOP(result),"a",3);    
1972
1973     while(size--) {
1974         aopPut(AOP(result),
1975                aopGet(AOP(op),offset,FALSE,FALSE),
1976                offset);
1977         offset++;
1978     }          
1979 }
1980
1981 /*-----------------------------------------------------------------*/
1982 /* genUminus - unary minus code generation                         */
1983 /*-----------------------------------------------------------------*/
1984 static void genUminus (iCode *ic)
1985 {
1986   int size, i;
1987   sym_link *optype, *rtype;
1988
1989
1990   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1991   /* assign asmops */
1992   aopOp(IC_LEFT(ic),ic,FALSE);
1993   aopOp(IC_RESULT(ic),ic,TRUE);
1994
1995   /* if both in bit space then special
1996      case */
1997   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1998       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1999
2000     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
2001     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
2002     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
2003
2004     goto release; 
2005   } 
2006
2007   optype = operandType(IC_LEFT(ic));
2008   rtype = operandType(IC_RESULT(ic));
2009
2010   /* if float then do float stuff */
2011   if (IS_FLOAT(optype)) {
2012     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2013     goto release;
2014   }
2015
2016   /* otherwise subtract from zero by taking the 2's complement */
2017   size = AOP_SIZE(IC_LEFT(ic));
2018
2019   for(i=0; i<size; i++) {
2020     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2021       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
2022     else {
2023       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2024       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2025     }
2026   }
2027
2028   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2029   for(i=1; i<size; i++) {
2030     emitSKPNZ;
2031     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2032   }
2033
2034  release:
2035   /* release the aops */
2036   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2037   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2038 }
2039
2040 /*-----------------------------------------------------------------*/
2041 /* saveRegisters - will look for a call and save the registers     */
2042 /*-----------------------------------------------------------------*/
2043 static void saveRegisters(iCode *lic) 
2044 {
2045     int i;
2046     iCode *ic;
2047     bitVect *rsave;
2048     sym_link *dtype;
2049
2050     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2051     /* look for call */
2052     for (ic = lic ; ic ; ic = ic->next) 
2053         if (ic->op == CALL || ic->op == PCALL)
2054             break;
2055
2056     if (!ic) {
2057         fprintf(stderr,"found parameter push with no function call\n");
2058         return ;
2059     }
2060
2061     /* if the registers have been saved already then
2062     do nothing */
2063     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2064         return ;
2065
2066     /* find the registers in use at this time 
2067     and push them away to safety */
2068     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2069                           ic->rUsed);
2070
2071     ic->regsSaved = 1;
2072     if (options.useXstack) {
2073         if (bitVectBitValue(rsave,R0_IDX))
2074             pic14_emitcode("mov","b,r0");
2075         pic14_emitcode("mov","r0,%s",spname);
2076         for (i = 0 ; i < pic14_nRegs ; i++) {
2077             if (bitVectBitValue(rsave,i)) {
2078                 if (i == R0_IDX)
2079                     pic14_emitcode("mov","a,b");
2080                 else
2081                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2082                 pic14_emitcode("movx","@r0,a");
2083                 pic14_emitcode("inc","r0");
2084             }
2085         }
2086         pic14_emitcode("mov","%s,r0",spname);
2087         if (bitVectBitValue(rsave,R0_IDX))
2088             pic14_emitcode("mov","r0,b");           
2089     }// else
2090     //for (i = 0 ; i < pic14_nRegs ; i++) {
2091     //    if (bitVectBitValue(rsave,i))
2092     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2093     //}
2094
2095     dtype = operandType(IC_LEFT(ic));
2096     if (currFunc && dtype && 
2097         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2098         IFFUNC_ISISR(currFunc->type) &&
2099         !ic->bankSaved) 
2100
2101         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2102
2103 }
2104 /*-----------------------------------------------------------------*/
2105 /* unsaveRegisters - pop the pushed registers                      */
2106 /*-----------------------------------------------------------------*/
2107 static void unsaveRegisters (iCode *ic)
2108 {
2109     int i;
2110     bitVect *rsave;
2111
2112     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2113     /* find the registers in use at this time 
2114     and push them away to safety */
2115     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2116                           ic->rUsed);
2117     
2118     if (options.useXstack) {
2119         pic14_emitcode("mov","r0,%s",spname);   
2120         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2121             if (bitVectBitValue(rsave,i)) {
2122                 pic14_emitcode("dec","r0");
2123                 pic14_emitcode("movx","a,@r0");
2124                 if (i == R0_IDX)
2125                     pic14_emitcode("mov","b,a");
2126                 else
2127                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2128             }       
2129
2130         }
2131         pic14_emitcode("mov","%s,r0",spname);
2132         if (bitVectBitValue(rsave,R0_IDX))
2133             pic14_emitcode("mov","r0,b");
2134     } //else
2135     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2136     //    if (bitVectBitValue(rsave,i))
2137     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2138     //}
2139
2140 }  
2141
2142
2143 /*-----------------------------------------------------------------*/
2144 /* pushSide -                                                      */
2145 /*-----------------------------------------------------------------*/
2146 static void pushSide(operand * oper, int size)
2147 {
2148 #if 0
2149         int offset = 0;
2150     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2151         while (size--) {
2152                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2153                 if (AOP_TYPE(oper) != AOP_REG &&
2154                     AOP_TYPE(oper) != AOP_DIR &&
2155                     strcmp(l,"a") ) {
2156                         pic14_emitcode("mov","a,%s",l);
2157                         pic14_emitcode("push","acc");
2158                 } else
2159                         pic14_emitcode("push","%s",l);
2160         }
2161 #endif
2162 }
2163
2164 /*-----------------------------------------------------------------*/
2165 /* assignResultValue -                                             */
2166 /*-----------------------------------------------------------------*/
2167 static void assignResultValue(operand * oper)
2168 {
2169   int size = AOP_SIZE(oper);
2170
2171   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2172
2173   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2174
2175   if(!GpsuedoStkPtr) {
2176     /* The last byte in the assignment is in W */
2177     size--;
2178     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2179     GpsuedoStkPtr++;
2180   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2181   }
2182
2183   while (size--) {
2184     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2185     GpsuedoStkPtr++;
2186     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2187   }
2188 }
2189
2190
2191 /*-----------------------------------------------------------------*/
2192 /* genIpush - genrate code for pushing this gets a little complex  */
2193 /*-----------------------------------------------------------------*/
2194 static void genIpush (iCode *ic)
2195 {
2196
2197   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2198 #if 0
2199     int size, offset = 0 ;
2200     char *l;
2201
2202
2203     /* if this is not a parm push : ie. it is spill push 
2204     and spill push is always done on the local stack */
2205     if (!ic->parmPush) {
2206
2207         /* and the item is spilt then do nothing */
2208         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2209             return ;
2210
2211         aopOp(IC_LEFT(ic),ic,FALSE);
2212         size = AOP_SIZE(IC_LEFT(ic));
2213         /* push it on the stack */
2214         while(size--) {
2215             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2216             if (*l == '#') {
2217                 MOVA(l);
2218                 l = "acc";
2219             }
2220             pic14_emitcode("push","%s",l);
2221         }
2222         return ;        
2223     }
2224
2225     /* this is a paramter push: in this case we call
2226     the routine to find the call and save those
2227     registers that need to be saved */   
2228     saveRegisters(ic);
2229
2230     /* then do the push */
2231     aopOp(IC_LEFT(ic),ic,FALSE);
2232
2233
2234         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2235     size = AOP_SIZE(IC_LEFT(ic));
2236
2237     while (size--) {
2238         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2239         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2240             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2241             strcmp(l,"a") ) {
2242             pic14_emitcode("mov","a,%s",l);
2243             pic14_emitcode("push","acc");
2244         } else
2245             pic14_emitcode("push","%s",l);
2246     }       
2247
2248     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2249 #endif
2250 }
2251
2252 /*-----------------------------------------------------------------*/
2253 /* genIpop - recover the registers: can happen only for spilling   */
2254 /*-----------------------------------------------------------------*/
2255 static void genIpop (iCode *ic)
2256 {
2257   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2258 #if 0
2259     int size,offset ;
2260
2261
2262     /* if the temp was not pushed then */
2263     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2264         return ;
2265
2266     aopOp(IC_LEFT(ic),ic,FALSE);
2267     size = AOP_SIZE(IC_LEFT(ic));
2268     offset = (size-1);
2269     while (size--) 
2270         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2271                                    FALSE,TRUE));
2272
2273     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2274 #endif
2275 }
2276
2277 /*-----------------------------------------------------------------*/
2278 /* unsaverbank - restores the resgister bank from stack            */
2279 /*-----------------------------------------------------------------*/
2280 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2281 {
2282   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2283 #if 0
2284     int i;
2285     asmop *aop ;
2286     regs *r = NULL;
2287
2288     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2289     if (popPsw) {
2290         if (options.useXstack) {
2291             aop = newAsmop(0);
2292             r = getFreePtr(ic,&aop,FALSE);
2293             
2294             
2295             pic14_emitcode("mov","%s,_spx",r->name);
2296             pic14_emitcode("movx","a,@%s",r->name);
2297             pic14_emitcode("mov","psw,a");
2298             pic14_emitcode("dec","%s",r->name);
2299             
2300         }else
2301             pic14_emitcode ("pop","psw");
2302     }
2303
2304     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2305         if (options.useXstack) {       
2306             pic14_emitcode("movx","a,@%s",r->name);
2307             //pic14_emitcode("mov","(%s+%d),a",
2308             //       regspic14[i].base,8*bank+regspic14[i].offset);
2309             pic14_emitcode("dec","%s",r->name);
2310
2311         } else 
2312           pic14_emitcode("pop",""); //"(%s+%d)",
2313         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2314     }
2315
2316     if (options.useXstack) {
2317
2318         pic14_emitcode("mov","_spx,%s",r->name);
2319         freeAsmop(NULL,aop,ic,TRUE);
2320
2321     }
2322 #endif 
2323 }
2324
2325 /*-----------------------------------------------------------------*/
2326 /* saverbank - saves an entire register bank on the stack          */
2327 /*-----------------------------------------------------------------*/
2328 static void saverbank (int bank, iCode *ic, bool pushPsw)
2329 {
2330   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2331 #if 0
2332     int i;
2333     asmop *aop ;
2334     regs *r = NULL;
2335
2336     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2337     if (options.useXstack) {
2338
2339         aop = newAsmop(0);
2340         r = getFreePtr(ic,&aop,FALSE);  
2341         pic14_emitcode("mov","%s,_spx",r->name);
2342
2343     }
2344
2345     for (i = 0 ; i < pic14_nRegs ;i++) {
2346         if (options.useXstack) {
2347             pic14_emitcode("inc","%s",r->name);
2348             //pic14_emitcode("mov","a,(%s+%d)",
2349             //         regspic14[i].base,8*bank+regspic14[i].offset);
2350             pic14_emitcode("movx","@%s,a",r->name);           
2351         } else 
2352           pic14_emitcode("push","");// "(%s+%d)",
2353                      //regspic14[i].base,8*bank+regspic14[i].offset);
2354     }
2355     
2356     if (pushPsw) {
2357         if (options.useXstack) {
2358             pic14_emitcode("mov","a,psw");
2359             pic14_emitcode("movx","@%s,a",r->name);     
2360             pic14_emitcode("inc","%s",r->name);
2361             pic14_emitcode("mov","_spx,%s",r->name);       
2362             freeAsmop (NULL,aop,ic,TRUE);
2363             
2364         } else
2365             pic14_emitcode("push","psw");
2366         
2367         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2368     }
2369     ic->bankSaved = 1;
2370 #endif
2371 }
2372
2373 /*-----------------------------------------------------------------*/
2374 /* genCall - generates a call statement                            */
2375 /*-----------------------------------------------------------------*/
2376 static void genCall (iCode *ic)
2377 {
2378   sym_link *dtype;   
2379
2380   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2381
2382   /* if caller saves & we have not saved then */
2383   if (!ic->regsSaved)
2384     saveRegisters(ic);
2385
2386   /* if we are calling a function that is not using
2387      the same register bank then we need to save the
2388      destination registers on the stack */
2389   dtype = operandType(IC_LEFT(ic));
2390   if (currFunc && dtype && 
2391       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2392       IFFUNC_ISISR(currFunc->type) &&
2393       !ic->bankSaved) 
2394
2395     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2396
2397   /* if send set is not empty the assign */
2398   if (_G.sendSet) {
2399     iCode *sic;
2400     /* For the Pic port, there is no data stack.
2401      * So parameters passed to functions are stored
2402      * in registers. (The pCode optimizer will get
2403      * rid of most of these :).
2404      */
2405     int psuedoStkPtr=-1; 
2406     int firstTimeThruLoop = 1;
2407
2408     _G.sendSet = reverseSet(_G.sendSet);
2409
2410     /* First figure how many parameters are getting passed */
2411     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2412          sic = setNextItem(_G.sendSet)) {
2413
2414       aopOp(IC_LEFT(sic),sic,FALSE);
2415       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2416       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2417     }
2418
2419     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2420          sic = setNextItem(_G.sendSet)) {
2421       int size, offset = 0;
2422
2423       aopOp(IC_LEFT(sic),sic,FALSE);
2424       size = AOP_SIZE(IC_LEFT(sic));
2425
2426       while (size--) {
2427         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2428                              AopType(AOP_TYPE(IC_LEFT(sic))));
2429
2430         if(!firstTimeThruLoop) {
2431           /* If this is not the first time we've been through the loop
2432            * then we need to save the parameter in a temporary
2433            * register. The last byte of the last parameter is
2434            * passed in W. */
2435           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2436
2437         }
2438         firstTimeThruLoop=0;
2439
2440         //if (strcmp(l,fReturn[offset])) {
2441         mov2w (AOP(IC_LEFT(sic)),  offset);
2442 /*
2443         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2444              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2445           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2446         else
2447           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2448 */
2449         //}
2450         offset++;
2451       }
2452       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2453     }
2454     _G.sendSet = NULL;
2455   }
2456   /* make the call */
2457   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2458                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2459                                       OP_SYMBOL(IC_LEFT(ic))->name));
2460
2461   GpsuedoStkPtr=0;
2462   /* if we need assign a result value */
2463   if ((IS_ITEMP(IC_RESULT(ic)) && 
2464        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2465         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2466       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2467
2468     _G.accInUse++;
2469     aopOp(IC_RESULT(ic),ic,FALSE);
2470     _G.accInUse--;
2471
2472     assignResultValue(IC_RESULT(ic));
2473
2474     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2475                          AopType(AOP_TYPE(IC_RESULT(ic))));
2476                 
2477     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2478   }
2479
2480   /* adjust the stack for parameters if 
2481      required */
2482   if (ic->parmBytes) {
2483     int i;
2484     if (ic->parmBytes > 3) {
2485       pic14_emitcode("mov","a,%s",spname);
2486       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2487       pic14_emitcode("mov","%s,a",spname);
2488     } else 
2489       for ( i = 0 ; i <  ic->parmBytes ;i++)
2490         pic14_emitcode("dec","%s",spname);
2491
2492   }
2493
2494   /* if register bank was saved then pop them */
2495   if (ic->bankSaved)
2496     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2497
2498   /* if we hade saved some registers then unsave them */
2499   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2500     unsaveRegisters (ic);
2501
2502
2503 }
2504
2505 /*-----------------------------------------------------------------*/
2506 /* genPcall - generates a call by pointer statement                */
2507 /*-----------------------------------------------------------------*/
2508 static void genPcall (iCode *ic)
2509 {
2510     sym_link *dtype;
2511     symbol *albl = newiTempLabel(NULL);
2512     symbol *blbl = newiTempLabel(NULL);
2513     PIC_OPCODE poc;
2514     operand *left;
2515
2516     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2517     /* if caller saves & we have not saved then */
2518     if (!ic->regsSaved)
2519         saveRegisters(ic);
2520
2521     /* if we are calling a function that is not using
2522     the same register bank then we need to save the
2523     destination registers on the stack */
2524     dtype = operandType(IC_LEFT(ic));
2525     if (currFunc && dtype && 
2526         IFFUNC_ISISR(currFunc->type) &&
2527         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2528         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2529
2530     left = IC_LEFT(ic);
2531     aopOp(left,ic,FALSE);
2532     DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2533
2534     pushSide(IC_LEFT(ic), FPTRSIZE);
2535
2536     /* if send set is not empty, assign parameters */
2537     if (_G.sendSet) {
2538
2539         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2540         /* no way to pass args - W always gets used to make the call */
2541     }
2542 /* first idea - factor out a common helper function and call it.
2543    But don't know how to get it generated only once in its own block
2544
2545     if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2546             char *rname;
2547             char *buffer;
2548             rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2549             DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2550             buffer = Safe_calloc(1,strlen(rname)+16);
2551             sprintf(buffer, "%s_goto_helper", rname);
2552             addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2553             free(buffer);
2554     }
2555 */
2556     emitpcode(POC_CALL,popGetLabel(albl->key));
2557     emitpcode(POC_GOTO,popGetLabel(blbl->key));
2558     emitpLabel(albl->key);
2559
2560     poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2561     
2562     emitpcode(poc,popGet(AOP(left),1));
2563     emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2564     emitpcode(poc,popGet(AOP(left),0));
2565     emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2566
2567     emitpLabel(blbl->key);
2568
2569     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2570
2571     /* if we need to assign a result value */
2572     if ((IS_ITEMP(IC_RESULT(ic)) &&
2573          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2574           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2575         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2576
2577         _G.accInUse++;
2578         aopOp(IC_RESULT(ic),ic,FALSE);
2579         _G.accInUse--;
2580         
2581         assignResultValue(IC_RESULT(ic));
2582
2583         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2584     }
2585
2586     /* if register bank was saved then unsave them */
2587     if (currFunc && dtype && 
2588         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2589         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2590
2591     /* if we hade saved some registers then
2592     unsave them */
2593     if (ic->regsSaved)
2594         unsaveRegisters (ic);
2595
2596 }
2597
2598 /*-----------------------------------------------------------------*/
2599 /* resultRemat - result  is rematerializable                       */
2600 /*-----------------------------------------------------------------*/
2601 static int resultRemat (iCode *ic)
2602 {
2603   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2604   if (SKIP_IC(ic) || ic->op == IFX)
2605     return 0;
2606
2607   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2608     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2609     if (sym->remat && !POINTER_SET(ic)) 
2610       return 1;
2611   }
2612
2613   return 0;
2614 }
2615
2616 #if defined(__BORLANDC__) || defined(_MSC_VER)
2617 #define STRCASECMP stricmp
2618 #else
2619 #define STRCASECMP strcasecmp
2620 #endif
2621
2622 #if 0
2623 /*-----------------------------------------------------------------*/
2624 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2625 /*-----------------------------------------------------------------*/
2626 static bool inExcludeList(char *s)
2627 {
2628   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2629     int i =0;
2630     
2631     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2632     if (options.excludeRegs[i] &&
2633     STRCASECMP(options.excludeRegs[i],"none") == 0)
2634         return FALSE ;
2635
2636     for ( i = 0 ; options.excludeRegs[i]; i++) {
2637         if (options.excludeRegs[i] &&
2638         STRCASECMP(s,options.excludeRegs[i]) == 0)
2639             return TRUE;
2640     }
2641     return FALSE ;
2642 }
2643 #endif
2644
2645 /*-----------------------------------------------------------------*/
2646 /* genFunction - generated code for function entry                 */
2647 /*-----------------------------------------------------------------*/
2648 static void genFunction (iCode *ic)
2649 {
2650     symbol *sym;
2651     sym_link *ftype;
2652
2653     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2654
2655     labelOffset += (max_key+4);
2656     max_key=0;
2657     GpsuedoStkPtr=0;
2658     _G.nRegsSaved = 0;
2659     /* create the function header */
2660     pic14_emitcode(";","-----------------------------------------");
2661     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2662     pic14_emitcode(";","-----------------------------------------");
2663
2664     pic14_emitcode("","%s:",sym->rname);
2665     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2666
2667     ftype = operandType(IC_LEFT(ic));
2668
2669     /* if critical function then turn interrupts off */
2670     if (IFFUNC_ISCRITICAL(ftype))
2671         pic14_emitcode("clr","ea");
2672
2673     /* here we need to generate the equates for the
2674        register bank if required */
2675 #if 0
2676     if (FUNC_REGBANK(ftype) != rbank) {
2677         int i ;
2678
2679         rbank = FUNC_REGBANK(ftype);
2680         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2681             if (strcmp(regspic14[i].base,"0") == 0)
2682                 pic14_emitcode("","%s = 0x%02x",
2683                          regspic14[i].dname,
2684                          8*rbank+regspic14[i].offset);
2685             else
2686                 pic14_emitcode ("","%s = %s + 0x%02x",
2687                           regspic14[i].dname,
2688                           regspic14[i].base,
2689                           8*rbank+regspic14[i].offset);
2690         }
2691     }
2692 #endif
2693
2694     /* if this is an interrupt service routine then
2695     save acc, b, dpl, dph  */
2696     if (IFFUNC_ISISR(sym->type)) {
2697       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2698       emitpcodeNULLop(POC_NOP);
2699       emitpcodeNULLop(POC_NOP);
2700       emitpcodeNULLop(POC_NOP);
2701       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2702       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2703       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2704       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2705
2706       pBlockConvert2ISR(pb);
2707 #if 0  
2708         if (!inExcludeList("acc"))          
2709             pic14_emitcode ("push","acc");      
2710         if (!inExcludeList("b"))
2711             pic14_emitcode ("push","b");
2712         if (!inExcludeList("dpl"))
2713             pic14_emitcode ("push","dpl");
2714         if (!inExcludeList("dph"))
2715             pic14_emitcode ("push","dph");
2716         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2717         {
2718             pic14_emitcode ("push", "dpx");
2719             /* Make sure we're using standard DPTR */
2720             pic14_emitcode ("push", "dps");
2721             pic14_emitcode ("mov", "dps, #0x00");
2722             if (options.stack10bit)
2723             {   
2724                 /* This ISR could conceivably use DPTR2. Better save it. */
2725                 pic14_emitcode ("push", "dpl1");
2726                 pic14_emitcode ("push", "dph1");
2727                 pic14_emitcode ("push", "dpx1");
2728             }
2729         }
2730         /* if this isr has no bank i.e. is going to
2731            run with bank 0 , then we need to save more
2732            registers :-) */
2733         if (!FUNC_REGBANK(sym->type)) {
2734
2735             /* if this function does not call any other
2736                function then we can be economical and
2737                save only those registers that are used */
2738             if (! IFFUNC_HASFCALL(sym->type)) {
2739                 int i;
2740
2741                 /* if any registers used */
2742                 if (sym->regsUsed) {
2743                     /* save the registers used */
2744                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2745                         if (bitVectBitValue(sym->regsUsed,i) ||
2746                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2747                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2748                     }
2749                 }
2750                 
2751             } else {
2752                 /* this function has  a function call cannot
2753                    determines register usage so we will have the
2754                    entire bank */
2755                 saverbank(0,ic,FALSE);
2756             }       
2757         }
2758 #endif
2759     } else {
2760         /* if callee-save to be used for this function
2761            then save the registers being used in this function */
2762         if (IFFUNC_CALLEESAVES(sym->type)) {
2763             int i;
2764             
2765             /* if any registers used */
2766             if (sym->regsUsed) {
2767                 /* save the registers used */
2768                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2769                     if (bitVectBitValue(sym->regsUsed,i) ||
2770                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2771                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2772                         _G.nRegsSaved++;
2773                     }
2774                 }
2775             }
2776         }
2777     }
2778
2779     /* set the register bank to the desired value */
2780     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2781         pic14_emitcode("push","psw");
2782         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2783     }
2784
2785     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2786
2787         if (options.useXstack) {
2788             pic14_emitcode("mov","r0,%s",spname);
2789             pic14_emitcode("mov","a,_bp");
2790             pic14_emitcode("movx","@r0,a");
2791             pic14_emitcode("inc","%s",spname);
2792         }
2793         else
2794         {
2795             /* set up the stack */
2796             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2797         }
2798         pic14_emitcode ("mov","_bp,%s",spname);
2799     }
2800
2801     /* adjust the stack for the function */
2802     if (sym->stack) {
2803
2804         int i = sym->stack;
2805         if (i > 256 ) 
2806             werror(W_STACK_OVERFLOW,sym->name);
2807
2808         if (i > 3 && sym->recvSize < 4) {              
2809
2810             pic14_emitcode ("mov","a,sp");
2811             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2812             pic14_emitcode ("mov","sp,a");
2813            
2814         }
2815         else
2816             while(i--)
2817                 pic14_emitcode("inc","sp");
2818     }
2819
2820      if (sym->xstack) {
2821
2822         pic14_emitcode ("mov","a,_spx");
2823         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2824         pic14_emitcode ("mov","_spx,a");
2825     }    
2826
2827 }
2828
2829 /*-----------------------------------------------------------------*/
2830 /* genEndFunction - generates epilogue for functions               */
2831 /*-----------------------------------------------------------------*/
2832 static void genEndFunction (iCode *ic)
2833 {
2834     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2835
2836     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2837
2838     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2839     {
2840         pic14_emitcode ("mov","%s,_bp",spname);
2841     }
2842
2843     /* if use external stack but some variables were
2844     added to the local stack then decrement the
2845     local stack */
2846     if (options.useXstack && sym->stack) {      
2847         pic14_emitcode("mov","a,sp");
2848         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2849         pic14_emitcode("mov","sp,a");
2850     }
2851
2852
2853     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2854         if (options.useXstack) {
2855             pic14_emitcode("mov","r0,%s",spname);
2856             pic14_emitcode("movx","a,@r0");
2857             pic14_emitcode("mov","_bp,a");
2858             pic14_emitcode("dec","%s",spname);
2859         }
2860         else
2861         {
2862             pic14_emitcode ("pop","_bp");
2863         }
2864     }
2865
2866     /* restore the register bank  */    
2867     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2868         pic14_emitcode ("pop","psw");
2869
2870     if (IFFUNC_ISISR(sym->type)) {
2871
2872         /* now we need to restore the registers */
2873         /* if this isr has no bank i.e. is going to
2874            run with bank 0 , then we need to save more
2875            registers :-) */
2876         if (!FUNC_REGBANK(sym->type)) {
2877             
2878             /* if this function does not call any other
2879                function then we can be economical and
2880                save only those registers that are used */
2881             if (! IFFUNC_HASFCALL(sym->type)) {
2882                 int i;
2883                 
2884                 /* if any registers used */
2885                 if (sym->regsUsed) {
2886                     /* save the registers used */
2887                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2888                         if (bitVectBitValue(sym->regsUsed,i) ||
2889                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2890                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2891                     }
2892                 }
2893                 
2894             } else {
2895                 /* this function has  a function call cannot
2896                    determines register usage so we will have the
2897                    entire bank */
2898                 unsaverbank(0,ic,FALSE);
2899             }       
2900         }
2901 #if 0
2902         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2903         {
2904             if (options.stack10bit)
2905             {
2906                 pic14_emitcode ("pop", "dpx1");
2907                 pic14_emitcode ("pop", "dph1");
2908                 pic14_emitcode ("pop", "dpl1");
2909             }   
2910             pic14_emitcode ("pop", "dps");
2911             pic14_emitcode ("pop", "dpx");
2912         }
2913         if (!inExcludeList("dph"))
2914             pic14_emitcode ("pop","dph");
2915         if (!inExcludeList("dpl"))
2916             pic14_emitcode ("pop","dpl");
2917         if (!inExcludeList("b"))
2918             pic14_emitcode ("pop","b");
2919         if (!inExcludeList("acc"))
2920             pic14_emitcode ("pop","acc");
2921
2922         if (IFFUNC_ISCRITICAL(sym->type))
2923             pic14_emitcode("setb","ea");
2924 #endif
2925
2926         /* if debug then send end of function */
2927 /*      if (options.debug && currFunc) { */
2928         if (currFunc) {
2929             _G.debugLine = 1;
2930             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2931                      FileBaseName(ic->filename),currFunc->lastLine,
2932                      ic->level,ic->block); 
2933             if (IS_STATIC(currFunc->etype))         
2934                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2935             else
2936                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2937             _G.debugLine = 0;
2938         }
2939         
2940         pic14_emitcode ("reti","");
2941
2942         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2943         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2944         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2945         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2946         emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2947         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2948
2949         emitpcodeNULLop(POC_RETFIE);
2950
2951     }
2952     else {
2953         if (IFFUNC_ISCRITICAL(sym->type))
2954             pic14_emitcode("setb","ea");
2955         
2956         if (IFFUNC_CALLEESAVES(sym->type)) {
2957             int i;
2958             
2959             /* if any registers used */
2960             if (sym->regsUsed) {
2961                 /* save the registers used */
2962                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2963                     if (bitVectBitValue(sym->regsUsed,i) ||
2964                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2965                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2966                 }
2967             }
2968             
2969         }
2970
2971         /* if debug then send end of function */
2972         if (currFunc) {
2973             _G.debugLine = 1;
2974             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2975                      FileBaseName(ic->filename),currFunc->lastLine,
2976                      ic->level,ic->block); 
2977             if (IS_STATIC(currFunc->etype))         
2978                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2979             else
2980                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2981             _G.debugLine = 0;
2982         }
2983
2984         pic14_emitcode ("return","");
2985         emitpcodeNULLop(POC_RETURN);
2986
2987         /* Mark the end of a function */
2988         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2989     }
2990
2991 }
2992
2993 /*-----------------------------------------------------------------*/
2994 /* genRet - generate code for return statement                     */
2995 /*-----------------------------------------------------------------*/
2996 static void genRet (iCode *ic)
2997 {
2998   int size,offset = 0 , pushed = 0;
2999     
3000   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3001   /* if we have no return value then
3002      just generate the "ret" */
3003   if (!IC_LEFT(ic)) 
3004     goto jumpret;       
3005     
3006   /* we have something to return then
3007      move the return value into place */
3008   aopOp(IC_LEFT(ic),ic,FALSE);
3009   size = AOP_SIZE(IC_LEFT(ic));
3010     
3011   while (size--) {
3012     char *l ;
3013     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3014       /* #NOCHANGE */
3015       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3016                  FALSE,TRUE);
3017       pic14_emitcode("push","%s",l);
3018       pushed++;
3019     } else {
3020       l = aopGet(AOP(IC_LEFT(ic)),offset,
3021                  FALSE,FALSE);
3022       if (strcmp(fReturn[offset],l)) {
3023       if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
3024            AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3025           ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3026           ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3027           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3028         }else {
3029           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3030         }
3031         if(size) {
3032           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3033         }
3034         offset++;
3035       }
3036     }
3037   }    
3038
3039   if (pushed) {
3040     while(pushed) {
3041       pushed--;
3042       if (strcmp(fReturn[pushed],"a"))
3043         pic14_emitcode("pop",fReturn[pushed]);
3044       else
3045         pic14_emitcode("pop","acc");
3046     }
3047   }
3048   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3049     
3050  jumpret:
3051   /* generate a jump to the return label
3052      if the next is not the return statement */
3053   if (!(ic->next && ic->next->op == LABEL &&
3054         IC_LABEL(ic->next) == returnLabel)) {
3055         
3056     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3057     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3058   }
3059     
3060 }
3061
3062 /*-----------------------------------------------------------------*/
3063 /* genLabel - generates a label                                    */
3064 /*-----------------------------------------------------------------*/
3065 static void genLabel (iCode *ic)
3066 {
3067     /* special case never generate */
3068     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3069     if (IC_LABEL(ic) == entryLabel)
3070         return ;
3071
3072     emitpLabel(IC_LABEL(ic)->key);
3073     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3074 }
3075
3076 /*-----------------------------------------------------------------*/
3077 /* genGoto - generates a goto                                      */
3078 /*-----------------------------------------------------------------*/
3079 //tsd
3080 static void genGoto (iCode *ic)
3081 {
3082   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3083   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3084 }
3085
3086
3087 /*-----------------------------------------------------------------*/
3088 /* genMultbits :- multiplication of bits                           */
3089 /*-----------------------------------------------------------------*/
3090 static void genMultbits (operand *left, 
3091                          operand *right, 
3092                          operand *result)
3093 {
3094   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3095
3096   if(!pic14_sameRegs(AOP(result),AOP(right)))
3097     emitpcode(POC_BSF,  popGet(AOP(result),0));
3098
3099   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3100   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3101   emitpcode(POC_BCF,  popGet(AOP(result),0));
3102
3103 }
3104
3105
3106 /*-----------------------------------------------------------------*/
3107 /* genMultOneByte : 8 bit multiplication & division                */
3108 /*-----------------------------------------------------------------*/
3109 static void genMultOneByte (operand *left,
3110                             operand *right,
3111                             operand *result)
3112 {
3113   sym_link *opetype = operandType(result);
3114
3115   // symbol *lbl ;
3116   int size,offset;
3117
3118   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3119   DEBUGpic14_AopType(__LINE__,left,right,result);
3120   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3121
3122   /* (if two literals, the value is computed before) */
3123   /* if one literal, literal on the right */
3124   if (AOP_TYPE(left) == AOP_LIT){
3125     operand *t = right;
3126     right = left;
3127     left = t;
3128   }
3129
3130   size = AOP_SIZE(result);
3131   if(size == 1) {
3132
3133     if (AOP_TYPE(right) == AOP_LIT){
3134       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3135                      aopGet(AOP(right),0,FALSE,FALSE), 
3136                      aopGet(AOP(left),0,FALSE,FALSE), 
3137                      aopGet(AOP(result),0,FALSE,FALSE));
3138       pic14_emitcode("call","genMultLit");
3139     } else {
3140       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3141                      aopGet(AOP(right),0,FALSE,FALSE), 
3142                      aopGet(AOP(left),0,FALSE,FALSE), 
3143                      aopGet(AOP(result),0,FALSE,FALSE));
3144       pic14_emitcode("call","genMult8X8_8");
3145
3146     }
3147     genMult8X8_8 (left, right,result);
3148
3149
3150     /* signed or unsigned */
3151     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3152     //l = aopGet(AOP(left),0,FALSE,FALSE);
3153     //MOVA(l);       
3154     //pic14_emitcode("mul","ab");
3155     /* if result size = 1, mul signed = mul unsigned */
3156     //aopPut(AOP(result),"a",0);
3157
3158   } else {  // (size > 1)
3159
3160     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3161                    aopGet(AOP(right),0,FALSE,FALSE), 
3162                    aopGet(AOP(left),0,FALSE,FALSE), 
3163                    aopGet(AOP(result),0,FALSE,FALSE));
3164
3165     if (SPEC_USIGN(opetype)){
3166       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3167       genUMult8X8_16 (left, right, result, NULL);
3168
3169       if (size > 2) {
3170         /* for filling the MSBs */
3171         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3172         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3173       }
3174     }
3175     else{
3176       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3177
3178       pic14_emitcode("mov","a,b");
3179
3180       /* adjust the MSB if left or right neg */
3181
3182       /* if one literal */
3183       if (AOP_TYPE(right) == AOP_LIT){
3184         pic14_emitcode("multiply ","right is a lit");
3185         /* AND literal negative */
3186         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3187           /* adjust MSB (c==0 after mul) */
3188           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3189         }
3190       }
3191       else{
3192         genSMult8X8_16 (left, right, result, NULL);
3193       }
3194
3195       if(size > 2){
3196         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3197         /* get the sign */
3198         pic14_emitcode("rlc","a");
3199         pic14_emitcode("subb","a,acc");
3200       }
3201     }
3202
3203     size -= 2;   
3204     offset = 2;
3205     if (size > 0)
3206       while (size--)
3207         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3208     //aopPut(AOP(result),"a",offset++);
3209   }
3210 }
3211
3212 /*-----------------------------------------------------------------*/
3213 /* genMult - generates code for multiplication                     */
3214 /*-----------------------------------------------------------------*/
3215 static void genMult (iCode *ic)
3216 {
3217     operand *left = IC_LEFT(ic);
3218     operand *right = IC_RIGHT(ic);
3219     operand *result= IC_RESULT(ic);   
3220
3221     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3222     /* assign the amsops */
3223     aopOp (left,ic,FALSE);
3224     aopOp (right,ic,FALSE);
3225     aopOp (result,ic,TRUE);
3226
3227   DEBUGpic14_AopType(__LINE__,left,right,result);
3228
3229     /* special cases first */
3230     /* both are bits */
3231     if (AOP_TYPE(left) == AOP_CRY &&
3232         AOP_TYPE(right)== AOP_CRY) {
3233         genMultbits(left,right,result);
3234         goto release ;
3235     }
3236
3237     /* if both are of size == 1 */
3238     if (AOP_SIZE(left) == 1 &&
3239         AOP_SIZE(right) == 1 ) {
3240         genMultOneByte(left,right,result);
3241         goto release ;
3242     }
3243
3244     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3245
3246     /* should have been converted to function call */
3247     //assert(0) ;
3248
3249 release :
3250     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3251     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3252     freeAsmop(result,NULL,ic,TRUE); 
3253 }
3254
3255 /*-----------------------------------------------------------------*/
3256 /* genDivbits :- division of bits                                  */
3257 /*-----------------------------------------------------------------*/
3258 static void genDivbits (operand *left, 
3259                         operand *right, 
3260                         operand *result)
3261 {
3262
3263     char *l;
3264
3265     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3266     /* the result must be bit */    
3267     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3268     l = aopGet(AOP(left),0,FALSE,FALSE);
3269
3270     MOVA(l);    
3271
3272     pic14_emitcode("div","ab");
3273     pic14_emitcode("rrc","a");
3274     aopPut(AOP(result),"c",0);
3275 }
3276
3277 /*-----------------------------------------------------------------*/
3278 /* genDivOneByte : 8 bit division                                  */
3279 /*-----------------------------------------------------------------*/
3280 static void genDivOneByte (operand *left,
3281                            operand *right,
3282                            operand *result)
3283 {
3284     sym_link *opetype = operandType(result);
3285     char *l ;
3286     symbol *lbl ;
3287     int size,offset;
3288
3289     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3290     size = AOP_SIZE(result) - 1;
3291     offset = 1;
3292     /* signed or unsigned */
3293     if (SPEC_USIGN(opetype)) {
3294         /* unsigned is easy */
3295         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3296         l = aopGet(AOP(left),0,FALSE,FALSE);
3297         MOVA(l);        
3298         pic14_emitcode("div","ab");
3299         aopPut(AOP(result),"a",0);
3300         while (size--)
3301             aopPut(AOP(result),zero,offset++);
3302         return ;
3303     }
3304
3305     /* signed is a little bit more difficult */
3306
3307     /* save the signs of the operands */
3308     l = aopGet(AOP(left),0,FALSE,FALSE);    
3309     MOVA(l);    
3310     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3311     pic14_emitcode("push","acc"); /* save it on the stack */
3312
3313     /* now sign adjust for both left & right */
3314     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3315     MOVA(l);       
3316     lbl = newiTempLabel(NULL);
3317     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3318     pic14_emitcode("cpl","a");   
3319     pic14_emitcode("inc","a");
3320     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3321     pic14_emitcode("mov","b,a");
3322
3323     /* sign adjust left side */
3324     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3325     MOVA(l);
3326
3327     lbl = newiTempLabel(NULL);
3328     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3329     pic14_emitcode("cpl","a");
3330     pic14_emitcode("inc","a");
3331     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3332
3333     /* now the division */
3334     pic14_emitcode("div","ab");
3335     /* we are interested in the lower order
3336     only */
3337     pic14_emitcode("mov","b,a");
3338     lbl = newiTempLabel(NULL);
3339     pic14_emitcode("pop","acc");   
3340     /* if there was an over flow we don't 
3341     adjust the sign of the result */
3342     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3343     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3344     CLRC;
3345     pic14_emitcode("clr","a");
3346     pic14_emitcode("subb","a,b");
3347     pic14_emitcode("mov","b,a");
3348     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3349
3350     /* now we are done */
3351     aopPut(AOP(result),"b",0);
3352     if(size > 0){
3353         pic14_emitcode("mov","c,b.7");
3354         pic14_emitcode("subb","a,acc");   
3355     }
3356     while (size--)
3357         aopPut(AOP(result),"a",offset++);
3358
3359 }
3360
3361 /*-----------------------------------------------------------------*/
3362 /* genDiv - generates code for division                            */
3363 /*-----------------------------------------------------------------*/
3364 static void genDiv (iCode *ic)
3365 {
3366     operand *left = IC_LEFT(ic);
3367     operand *right = IC_RIGHT(ic);
3368     operand *result= IC_RESULT(ic);   
3369
3370     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3371     /* assign the amsops */
3372     aopOp (left,ic,FALSE);
3373     aopOp (right,ic,FALSE);
3374     aopOp (result,ic,TRUE);
3375
3376     /* special cases first */
3377     /* both are bits */
3378     if (AOP_TYPE(left) == AOP_CRY &&
3379         AOP_TYPE(right)== AOP_CRY) {
3380         genDivbits(left,right,result);
3381         goto release ;
3382     }
3383
3384     /* if both are of size == 1 */
3385     if (AOP_SIZE(left) == 1 &&
3386         AOP_SIZE(right) == 1 ) {
3387         genDivOneByte(left,right,result);
3388         goto release ;
3389     }
3390
3391     /* should have been converted to function call */
3392     assert(0);
3393 release :
3394     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3395     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3396     freeAsmop(result,NULL,ic,TRUE); 
3397 }
3398
3399 /*-----------------------------------------------------------------*/
3400 /* genModbits :- modulus of bits                                   */
3401 /*-----------------------------------------------------------------*/
3402 static void genModbits (operand *left, 
3403                         operand *right, 
3404                         operand *result)
3405 {
3406
3407     char *l;
3408
3409     /* the result must be bit */    
3410     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3411     l = aopGet(AOP(left),0,FALSE,FALSE);
3412
3413     MOVA(l);       
3414
3415     pic14_emitcode("div","ab");
3416     pic14_emitcode("mov","a,b");
3417     pic14_emitcode("rrc","a");
3418     aopPut(AOP(result),"c",0);
3419 }
3420
3421 /*-----------------------------------------------------------------*/
3422 /* genModOneByte : 8 bit modulus                                   */
3423 /*-----------------------------------------------------------------*/
3424 static void genModOneByte (operand *left,
3425                            operand *right,
3426                            operand *result)
3427 {
3428     sym_link *opetype = operandType(result);
3429     char *l ;
3430     symbol *lbl ;
3431
3432     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3433     /* signed or unsigned */
3434     if (SPEC_USIGN(opetype)) {
3435         /* unsigned is easy */
3436         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3437         l = aopGet(AOP(left),0,FALSE,FALSE);
3438         MOVA(l);    
3439         pic14_emitcode("div","ab");
3440         aopPut(AOP(result),"b",0);
3441         return ;
3442     }
3443
3444     /* signed is a little bit more difficult */
3445
3446     /* save the signs of the operands */
3447     l = aopGet(AOP(left),0,FALSE,FALSE);    
3448     MOVA(l);
3449
3450     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3451     pic14_emitcode("push","acc"); /* save it on the stack */
3452
3453     /* now sign adjust for both left & right */
3454     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3455     MOVA(l);
3456
3457     lbl = newiTempLabel(NULL);
3458     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3459     pic14_emitcode("cpl","a");   
3460     pic14_emitcode("inc","a");
3461     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3462     pic14_emitcode("mov","b,a"); 
3463
3464     /* sign adjust left side */
3465     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3466     MOVA(l);
3467
3468     lbl = newiTempLabel(NULL);
3469     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3470     pic14_emitcode("cpl","a");   
3471     pic14_emitcode("inc","a");
3472     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3473
3474     /* now the multiplication */
3475     pic14_emitcode("div","ab");
3476     /* we are interested in the lower order
3477     only */
3478     lbl = newiTempLabel(NULL);
3479     pic14_emitcode("pop","acc");   
3480     /* if there was an over flow we don't 
3481     adjust the sign of the result */
3482     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3483     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3484     CLRC ;
3485     pic14_emitcode("clr","a");
3486     pic14_emitcode("subb","a,b");
3487     pic14_emitcode("mov","b,a");
3488     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3489
3490     /* now we are done */
3491     aopPut(AOP(result),"b",0);
3492
3493 }
3494
3495 /*-----------------------------------------------------------------*/
3496 /* genMod - generates code for division                            */
3497 /*-----------------------------------------------------------------*/
3498 static void genMod (iCode *ic)
3499 {
3500     operand *left = IC_LEFT(ic);
3501     operand *right = IC_RIGHT(ic);
3502     operand *result= IC_RESULT(ic);  
3503
3504     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3505     /* assign the amsops */
3506     aopOp (left,ic,FALSE);
3507     aopOp (right,ic,FALSE);
3508     aopOp (result,ic,TRUE);
3509
3510     /* special cases first */
3511     /* both are bits */
3512     if (AOP_TYPE(left) == AOP_CRY &&
3513         AOP_TYPE(right)== AOP_CRY) {
3514         genModbits(left,right,result);
3515         goto release ;
3516     }
3517
3518     /* if both are of size == 1 */
3519     if (AOP_SIZE(left) == 1 &&
3520         AOP_SIZE(right) == 1 ) {
3521         genModOneByte(left,right,result);
3522         goto release ;
3523     }
3524
3525     /* should have been converted to function call */
3526     assert(0);
3527
3528 release :
3529     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3530     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3531     freeAsmop(result,NULL,ic,TRUE); 
3532 }
3533
3534 /*-----------------------------------------------------------------*/
3535 /* genIfxJump :- will create a jump depending on the ifx           */
3536 /*-----------------------------------------------------------------*/
3537 /*
3538   note: May need to add parameter to indicate when a variable is in bit space.
3539 */
3540 static void genIfxJump (iCode *ic, char *jval)
3541 {
3542
3543     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3544     /* if true label then we jump if condition
3545     supplied is true */
3546     if ( IC_TRUE(ic) ) {
3547
3548         if(strcmp(jval,"a") == 0)
3549           emitSKPZ;
3550         else if (strcmp(jval,"c") == 0)
3551           emitSKPC;
3552         else {
3553           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3554           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3555         }
3556
3557         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3558         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3559
3560     }
3561     else {
3562         /* false label is present */
3563         if(strcmp(jval,"a") == 0)
3564           emitSKPNZ;
3565         else if (strcmp(jval,"c") == 0)
3566           emitSKPNC;
3567         else {
3568           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3569           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3570         }
3571
3572         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3573         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3574
3575     }
3576
3577
3578     /* mark the icode as generated */
3579     ic->generated = 1;
3580 }
3581
3582 /*-----------------------------------------------------------------*/
3583 /* genSkip                                                         */
3584 /*-----------------------------------------------------------------*/
3585 static void genSkip(iCode *ifx,int status_bit)
3586 {
3587   if(!ifx)
3588     return;
3589
3590   if ( IC_TRUE(ifx) ) {
3591     switch(status_bit) {
3592     case 'z':
3593       emitSKPNZ;
3594       break;
3595
3596     case 'c':
3597       emitSKPNC;
3598       break;
3599
3600     case 'd':
3601       emitSKPDC;
3602       break;
3603
3604     }
3605
3606     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3607     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3608
3609   } else {
3610
3611     switch(status_bit) {
3612
3613     case 'z':
3614       emitSKPZ;
3615       break;
3616
3617     case 'c':
3618       emitSKPC;
3619       break;
3620
3621     case 'd':
3622       emitSKPDC;
3623       break;
3624     }
3625     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3626     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3627
3628   }
3629
3630 }
3631
3632 /*-----------------------------------------------------------------*/
3633 /* genSkipc                                                        */
3634 /*-----------------------------------------------------------------*/
3635 static void genSkipc(resolvedIfx *rifx)
3636 {
3637   if(!rifx)
3638     return;
3639
3640   if(rifx->condition)
3641     emitSKPC;
3642   else
3643     emitSKPNC;
3644
3645   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3646   rifx->generated = 1;
3647 }
3648
3649 /*-----------------------------------------------------------------*/
3650 /* genSkipz2                                                       */
3651 /*-----------------------------------------------------------------*/
3652 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3653 {
3654   if(!rifx)
3655     return;
3656
3657   if( (rifx->condition ^ invert_condition) & 1)
3658     emitSKPZ;
3659   else
3660     emitSKPNZ;
3661
3662   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3663   rifx->generated = 1;
3664 }
3665
3666 /*-----------------------------------------------------------------*/
3667 /* genSkipz                                                        */
3668 /*-----------------------------------------------------------------*/
3669 static void genSkipz(iCode *ifx, int condition)
3670 {
3671   if(!ifx)
3672     return;
3673
3674   if(condition)
3675     emitSKPNZ;
3676   else
3677     emitSKPZ;
3678
3679   if ( IC_TRUE(ifx) )
3680     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3681   else
3682     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3683
3684   if ( IC_TRUE(ifx) )
3685     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3686   else
3687     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3688
3689 }
3690 /*-----------------------------------------------------------------*/
3691 /* genSkipCond                                                     */
3692 /*-----------------------------------------------------------------*/
3693 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3694 {
3695   if(!rifx)
3696     return;
3697
3698   if(rifx->condition)
3699     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3700   else
3701     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3702
3703
3704   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3705   rifx->generated = 1;
3706 }
3707
3708 #if 0
3709 /*-----------------------------------------------------------------*/
3710 /* genChkZeroes :- greater or less than comparison                 */
3711 /*     For each byte in a literal that is zero, inclusive or the   */
3712 /*     the corresponding byte in the operand with W                */
3713 /*     returns true if any of the bytes are zero                   */
3714 /*-----------------------------------------------------------------*/
3715 static int genChkZeroes(operand *op, int lit,  int size)
3716 {
3717
3718   int i;
3719   int flag =1;
3720
3721   while(size--) {
3722     i = (lit >> (size*8)) & 0xff;
3723
3724     if(i==0) {
3725       if(flag) 
3726         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3727       else
3728         emitpcode(POC_IORFW, popGet(AOP(op),size));
3729       flag = 0;
3730     }
3731   }
3732
3733   return (flag==0);
3734 }
3735 #endif
3736
3737 /*-----------------------------------------------------------------*/
3738 /* genCmp :- greater or less than comparison                       */
3739 /*-----------------------------------------------------------------*/
3740 static void genCmp (operand *left,operand *right,
3741                     operand *result, iCode *ifx, int sign)
3742 {
3743   int size; //, offset = 0 ;
3744   unsigned long lit = 0L,i = 0;
3745   resolvedIfx rFalseIfx;
3746   //  resolvedIfx rTrueIfx;
3747   symbol *truelbl;
3748   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3749 /*
3750   if(ifx) {
3751     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3752     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3753   }
3754 */
3755
3756   resolveIfx(&rFalseIfx,ifx);
3757   truelbl  = newiTempLabel(NULL);
3758   size = max(AOP_SIZE(left),AOP_SIZE(right));
3759
3760   DEBUGpic14_AopType(__LINE__,left,right,result);
3761
3762 #define _swapp
3763
3764   /* if literal is on the right then swap with left */
3765   if ((AOP_TYPE(right) == AOP_LIT)) {
3766     operand *tmp = right ;
3767     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3768     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3769 #ifdef _swapp
3770
3771     lit = (lit - 1) & mask;
3772     right = left;
3773     left = tmp;
3774     rFalseIfx.condition ^= 1;
3775 #endif
3776
3777   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3778     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3779   }
3780
3781
3782   //if(IC_TRUE(ifx) == NULL)
3783   /* if left & right are bit variables */
3784   if (AOP_TYPE(left) == AOP_CRY &&
3785       AOP_TYPE(right) == AOP_CRY ) {
3786     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3787     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3788   } else {
3789     /* subtract right from left if at the
3790        end the carry flag is set then we know that
3791        left is greater than right */
3792
3793     //    {
3794
3795     symbol *lbl  = newiTempLabel(NULL);
3796
3797 #ifndef _swapp
3798     if(AOP_TYPE(right) == AOP_LIT) {
3799
3800       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3801
3802       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3803
3804       /* special cases */
3805
3806       if(lit == 0) {
3807
3808         if(sign != 0) 
3809           genSkipCond(&rFalseIfx,left,size-1,7);
3810         else 
3811           /* no need to compare to 0...*/
3812           /* NOTE: this is a de-generate compare that most certainly 
3813            *       creates some dead code. */
3814           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3815
3816         if(ifx) ifx->generated = 1;
3817         return;
3818
3819       }
3820       size--;
3821
3822       if(size == 0) {
3823         //i = (lit >> (size*8)) & 0xff;
3824         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3825         
3826         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3827
3828         i = ((0-lit) & 0xff);
3829         if(sign) {
3830           if( i == 0x81) { 
3831             /* lit is 0x7f, all signed chars are less than
3832              * this except for 0x7f itself */
3833             emitpcode(POC_XORLW, popGetLit(0x7f));
3834             genSkipz2(&rFalseIfx,0);
3835           } else {
3836             emitpcode(POC_ADDLW, popGetLit(0x80));
3837             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3838             genSkipc(&rFalseIfx);
3839           }
3840
3841         } else {
3842           if(lit == 1) {
3843             genSkipz2(&rFalseIfx,1);
3844           } else {
3845             emitpcode(POC_ADDLW, popGetLit(i));
3846             genSkipc(&rFalseIfx);
3847           }
3848         }
3849
3850         if(ifx) ifx->generated = 1;
3851         return;
3852       }
3853
3854       /* chars are out of the way. now do ints and longs */
3855
3856
3857       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3858         
3859       /* special cases */
3860
3861       if(sign) {
3862
3863         if(lit == 0) {
3864           genSkipCond(&rFalseIfx,left,size,7);
3865           if(ifx) ifx->generated = 1;
3866           return;
3867         }
3868
3869         if(lit <0x100) {
3870           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3871
3872           //rFalseIfx.condition ^= 1;
3873           //genSkipCond(&rFalseIfx,left,size,7);
3874           //rFalseIfx.condition ^= 1;
3875
3876           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3877           if(rFalseIfx.condition)
3878             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3879           else
3880             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3881
3882           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3883           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3884           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3885
3886           while(size > 1)
3887             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3888
3889           if(rFalseIfx.condition) {
3890             emitSKPZ;
3891             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3892
3893           } else {
3894             emitSKPNZ;
3895           }
3896
3897           genSkipc(&rFalseIfx);
3898           emitpLabel(truelbl->key);
3899           if(ifx) ifx->generated = 1;
3900           return;
3901
3902         }
3903
3904         if(size == 1) {
3905
3906           if( (lit & 0xff) == 0) {
3907             /* lower byte is zero */
3908             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3909             i = ((lit >> 8) & 0xff) ^0x80;
3910             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3911             emitpcode(POC_ADDLW, popGetLit( 0x80));
3912             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3913             genSkipc(&rFalseIfx);
3914
3915
3916             if(ifx) ifx->generated = 1;
3917             return;
3918
3919           }
3920         } else {
3921           /* Special cases for signed longs */
3922           if( (lit & 0xffffff) == 0) {
3923             /* lower byte is zero */
3924             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3925             i = ((lit >> 8*3) & 0xff) ^0x80;
3926             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3927             emitpcode(POC_ADDLW, popGetLit( 0x80));
3928             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3929             genSkipc(&rFalseIfx);
3930
3931
3932             if(ifx) ifx->generated = 1;
3933             return;
3934
3935           }
3936
3937         }
3938
3939
3940         if(lit & (0x80 << (size*8))) {
3941           /* lit is negative */
3942           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3943
3944           //genSkipCond(&rFalseIfx,left,size,7);
3945
3946           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3947
3948           if(rFalseIfx.condition)
3949             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3950           else
3951             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3952
3953
3954         } else {
3955           /* lit is positive */
3956           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3957           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3958           if(rFalseIfx.condition)
3959             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3960           else
3961             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3962
3963         }
3964
3965         /*
3966           This works, but is only good for ints.
3967           It also requires a "known zero" register.
3968           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3969           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3970           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3971           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3972           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3973           genSkipc(&rFalseIfx);
3974
3975           emitpLabel(truelbl->key);
3976           if(ifx) ifx->generated = 1;
3977           return;
3978         **/
3979           
3980         /* There are no more special cases, so perform a general compare */
3981   
3982         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3983         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3984
3985         while(size--) {
3986
3987           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3988           emitSKPNZ;
3989           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3990         }
3991         //rFalseIfx.condition ^= 1;
3992         genSkipc(&rFalseIfx);
3993
3994         emitpLabel(truelbl->key);
3995
3996         if(ifx) ifx->generated = 1;
3997         return;
3998
3999
4000       }
4001
4002
4003       /* sign is out of the way. So now do an unsigned compare */
4004       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4005
4006
4007       /* General case - compare to an unsigned literal on the right.*/
4008
4009       i = (lit >> (size*8)) & 0xff;
4010       emitpcode(POC_MOVLW, popGetLit(i));
4011       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4012       while(size--) {
4013         i = (lit >> (size*8)) & 0xff;
4014
4015         if(i) {
4016           emitpcode(POC_MOVLW, popGetLit(i));
4017           emitSKPNZ;
4018           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4019         } else {
4020           /* this byte of the lit is zero, 
4021            *if it's not the last then OR in the variable */
4022           if(size)
4023             emitpcode(POC_IORFW, popGet(AOP(left),size));
4024         }
4025       }
4026
4027
4028       emitpLabel(lbl->key);
4029       //if(emitFinalCheck)
4030       genSkipc(&rFalseIfx);
4031       if(sign)
4032         emitpLabel(truelbl->key);
4033
4034       if(ifx) ifx->generated = 1;
4035       return;
4036
4037
4038     }
4039 #endif  // _swapp
4040
4041     if(AOP_TYPE(left) == AOP_LIT) {
4042       //symbol *lbl = newiTempLabel(NULL);
4043
4044       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4045
4046
4047       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4048
4049       /* Special cases */
4050       if((lit == 0) && (sign == 0)){
4051
4052         size--;
4053         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4054         while(size) 
4055           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4056
4057         genSkipz2(&rFalseIfx,0);
4058         if(ifx) ifx->generated = 1;
4059         return;
4060       }
4061
4062       if(size==1) {
4063         /* Special cases */
4064         lit &= 0xff;
4065         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4066           /* degenerate compare can never be true */
4067           if(rFalseIfx.condition == 0)
4068             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4069
4070           if(ifx) ifx->generated = 1;
4071           return;
4072         }
4073
4074         if(sign) {
4075           /* signed comparisons to a literal byte */
4076
4077           int lp1 = (lit+1) & 0xff;
4078
4079           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4080           switch (lp1) {
4081           case 0:
4082             rFalseIfx.condition ^= 1;
4083             genSkipCond(&rFalseIfx,right,0,7);
4084             break;
4085           case 0x7f:
4086             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4087             emitpcode(POC_XORLW, popGetLit(0x7f));
4088             genSkipz2(&rFalseIfx,1);
4089             break;
4090           default:
4091             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4092             emitpcode(POC_ADDLW, popGetLit(0x80));
4093             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4094             rFalseIfx.condition ^= 1;
4095             genSkipc(&rFalseIfx);
4096             break;
4097           }
4098           if(ifx) ifx->generated = 1;
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             if(ifx) ifx->generated = 1;
4107             break;
4108           case 0x7f:
4109             rFalseIfx.condition ^= 1;
4110             genSkipCond(&rFalseIfx,right,0,7);
4111             if(ifx) ifx->generated = 1;
4112             break;
4113
4114           default:
4115             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4116             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4117             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4118             rFalseIfx.condition ^= 1;
4119             if (AOP_TYPE(result) == AOP_CRY) {
4120               genSkipc(&rFalseIfx);
4121               if(ifx) ifx->generated = 1;
4122             } else {
4123               DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4124               emitpcode(POC_CLRF, popGet(AOP(result),0));
4125               emitpcode(POC_RLF, popGet(AOP(result),0));
4126               emitpcode(POC_MOVLW, popGetLit(0x01));
4127               emitpcode(POC_XORWF, popGet(AOP(result),0));
4128             }         
4129             break;
4130           }
4131         }
4132
4133         //goto check_carry;
4134         return;
4135
4136       } else {
4137
4138         /* Size is greater than 1 */
4139
4140         if(sign) {
4141           int lp1 = lit+1;
4142
4143           size--;
4144
4145           if(lp1 == 0) {
4146             /* this means lit = 0xffffffff, or -1 */
4147
4148
4149             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4150             rFalseIfx.condition ^= 1;
4151             genSkipCond(&rFalseIfx,right,size,7);
4152             if(ifx) ifx->generated = 1;
4153             return;
4154           }
4155
4156           if(lit == 0) {
4157             int s = size;
4158
4159             if(rFalseIfx.condition) {
4160               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4161               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4162             }
4163
4164             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4165             while(size--)
4166               emitpcode(POC_IORFW, popGet(AOP(right),size));
4167
4168
4169             emitSKPZ;
4170             if(rFalseIfx.condition) {
4171               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4172               emitpLabel(truelbl->key);
4173             }else {
4174               rFalseIfx.condition ^= 1;
4175               genSkipCond(&rFalseIfx,right,s,7);
4176             }
4177
4178             if(ifx) ifx->generated = 1;
4179             return;
4180           }
4181
4182           if((size == 1) &&  (0 == (lp1&0xff))) {
4183             /* lower byte of signed word is zero */
4184             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4185             i = ((lp1 >> 8) & 0xff) ^0x80;
4186             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4187             emitpcode(POC_ADDLW, popGetLit( 0x80));
4188             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4189             rFalseIfx.condition ^= 1;
4190             genSkipc(&rFalseIfx);
4191
4192
4193             if(ifx) ifx->generated = 1;
4194             return;
4195           }
4196
4197           if(lit & (0x80 << (size*8))) {
4198             /* Lit is less than zero */
4199             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4200             //rFalseIfx.condition ^= 1;
4201             //genSkipCond(&rFalseIfx,left,size,7);
4202             //rFalseIfx.condition ^= 1;
4203             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4205
4206             if(rFalseIfx.condition)
4207               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4208             else
4209               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4210
4211
4212           } else {
4213             /* Lit is greater than or equal to zero */
4214             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4215             //rFalseIfx.condition ^= 1;
4216             //genSkipCond(&rFalseIfx,right,size,7);
4217             //rFalseIfx.condition ^= 1;
4218
4219             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4220             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4221
4222             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4223             if(rFalseIfx.condition)
4224               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4225             else
4226               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4227
4228           }
4229
4230
4231           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4232           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4233
4234           while(size--) {
4235
4236             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4237             emitSKPNZ;
4238             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4239           }
4240           rFalseIfx.condition ^= 1;
4241           //rFalseIfx.condition = 1;
4242           genSkipc(&rFalseIfx);
4243
4244           emitpLabel(truelbl->key);
4245
4246           if(ifx) ifx->generated = 1;
4247           return;
4248           // end of if (sign)
4249         } else {
4250
4251           /* compare word or long to an unsigned literal on the right.*/
4252
4253
4254           size--;
4255           if(lit < 0xff) {
4256             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4257             switch (lit) {
4258             case 0:
4259               break; /* handled above */
4260 /*
4261             case 0xff:
4262               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4263               while(size--)
4264                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265               genSkipz2(&rFalseIfx,0);
4266               break;
4267 */
4268             default:
4269               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4270               while(--size)
4271                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4272
4273               emitSKPZ;
4274               if(rFalseIfx.condition)
4275                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4276               else
4277                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4278
4279
4280               emitpcode(POC_MOVLW, popGetLit(lit+1));
4281               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4282
4283               rFalseIfx.condition ^= 1;
4284               genSkipc(&rFalseIfx);
4285             }
4286
4287             emitpLabel(truelbl->key);
4288
4289             if(ifx) ifx->generated = 1;
4290             return;
4291           }
4292
4293
4294           lit++;
4295           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4296           i = (lit >> (size*8)) & 0xff;
4297
4298           emitpcode(POC_MOVLW, popGetLit(i));
4299           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4300
4301           while(size--) {
4302             i = (lit >> (size*8)) & 0xff;
4303
4304             if(i) {
4305               emitpcode(POC_MOVLW, popGetLit(i));
4306               emitSKPNZ;
4307               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4308             } else {
4309               /* this byte of the lit is zero, 
4310                *if it's not the last then OR in the variable */
4311               if(size)
4312                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4313             }
4314           }
4315
4316
4317           emitpLabel(lbl->key);
4318
4319           rFalseIfx.condition ^= 1;
4320           genSkipc(&rFalseIfx);
4321         }
4322
4323         if(sign)
4324           emitpLabel(truelbl->key);
4325         if(ifx) ifx->generated = 1;
4326         return;
4327       }
4328     }
4329     /* Compare two variables */
4330
4331     DEBUGpic14_emitcode(";sign","%d",sign);
4332
4333     size--;
4334     if(sign) {
4335       /* Sigh. thus sucks... */
4336       if(size) {
4337         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4338         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4339         emitpcode(POC_MOVLW, popGetLit(0x80));
4340         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4341         emitpcode(POC_XORFW, popGet(AOP(right),size));
4342         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4343       } else {
4344         /* Signed char comparison */
4345         /* Special thanks to Nikolai Golovchenko for this snippet */
4346         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4347         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4348         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4349         emitpcode(POC_XORFW, popGet(AOP(left),0));
4350         emitpcode(POC_XORFW, popGet(AOP(right),0));
4351         emitpcode(POC_ADDLW, popGetLit(0x80));
4352
4353         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4354         genSkipc(&rFalseIfx);
4355           
4356         if(ifx) ifx->generated = 1;
4357         return;
4358       }
4359
4360     } else {
4361
4362       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4363       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4364     }
4365
4366
4367     /* The rest of the bytes of a multi-byte compare */
4368     while (size) {
4369
4370       emitSKPZ;
4371       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4372       size--;
4373
4374       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4375       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4376
4377
4378     }
4379
4380     emitpLabel(lbl->key);
4381
4382     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4383     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4384         (AOP_TYPE(result) == AOP_REG)) {
4385       emitpcode(POC_CLRF, popGet(AOP(result),0));
4386       emitpcode(POC_RLF, popGet(AOP(result),0));
4387     } else {
4388       genSkipc(&rFalseIfx);
4389     }         
4390     //genSkipc(&rFalseIfx);
4391     if(ifx) ifx->generated = 1;
4392
4393     return;
4394
4395   }
4396
4397   // check_carry:
4398   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4399     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4400     pic14_outBitC(result);
4401   } else {
4402     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4403     /* if the result is used in the next
4404        ifx conditional branch then generate
4405        code a little differently */
4406     if (ifx )
4407       genIfxJump (ifx,"c");
4408     else
4409       pic14_outBitC(result);
4410     /* leave the result in acc */
4411   }
4412
4413 }
4414
4415 /*-----------------------------------------------------------------*/
4416 /* genCmpGt :- greater than comparison                             */
4417 /*-----------------------------------------------------------------*/
4418 static void genCmpGt (iCode *ic, iCode *ifx)
4419 {
4420     operand *left, *right, *result;
4421     sym_link *letype , *retype;
4422     int sign ;
4423
4424     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4425     left = IC_LEFT(ic);
4426     right= IC_RIGHT(ic);
4427     result = IC_RESULT(ic);
4428
4429     letype = getSpec(operandType(left));
4430     retype =getSpec(operandType(right));
4431     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4432     /* assign the amsops */
4433     aopOp (left,ic,FALSE);
4434     aopOp (right,ic,FALSE);
4435     aopOp (result,ic,TRUE);
4436
4437     genCmp(right, left, result, ifx, sign);
4438
4439     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441     freeAsmop(result,NULL,ic,TRUE); 
4442 }
4443
4444 /*-----------------------------------------------------------------*/
4445 /* genCmpLt - less than comparisons                                */
4446 /*-----------------------------------------------------------------*/
4447 static void genCmpLt (iCode *ic, iCode *ifx)
4448 {
4449     operand *left, *right, *result;
4450     sym_link *letype , *retype;
4451     int sign ;
4452
4453     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4454     left = IC_LEFT(ic);
4455     right= IC_RIGHT(ic);
4456     result = IC_RESULT(ic);
4457
4458     letype = getSpec(operandType(left));
4459     retype =getSpec(operandType(right));
4460     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4461
4462     /* assign the amsops */
4463     aopOp (left,ic,FALSE);
4464     aopOp (right,ic,FALSE);
4465     aopOp (result,ic,TRUE);
4466
4467     genCmp(left, right, result, ifx, sign);
4468
4469     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4470     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471     freeAsmop(result,NULL,ic,TRUE); 
4472 }
4473
4474 /*-----------------------------------------------------------------*/
4475 /* genc16bit2lit - compare a 16 bit value to a literal             */
4476 /*-----------------------------------------------------------------*/
4477 static void genc16bit2lit(operand *op, int lit, int offset)
4478 {
4479   int i;
4480
4481   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4482   if( (lit&0xff) == 0) 
4483     i=1;
4484   else
4485     i=0;
4486
4487   switch( BYTEofLONG(lit,i)) { 
4488   case 0:
4489     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4490     break;
4491   case 1:
4492     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4493     break;
4494   case 0xff:
4495     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4496     break;
4497   default:
4498     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4499     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4500   }
4501
4502   i ^= 1;
4503
4504   switch( BYTEofLONG(lit,i)) { 
4505   case 0:
4506     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4507     break;
4508   case 1:
4509     emitSKPNZ;
4510     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4511     break;
4512   case 0xff:
4513     emitSKPNZ;
4514     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4515     break;
4516   default:
4517     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4518     emitSKPNZ;
4519     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4520
4521   }
4522
4523 }
4524
4525 /*-----------------------------------------------------------------*/
4526 /* gencjneshort - compare and jump if not equal                    */
4527 /*-----------------------------------------------------------------*/
4528 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4529 {
4530   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4531   int offset = 0;
4532   int res_offset = 0;  /* the result may be a different size then left or right */
4533   int res_size = AOP_SIZE(result);
4534   resolvedIfx rIfx;
4535   symbol *lbl;
4536
4537   unsigned long lit = 0L;
4538   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4539   DEBUGpic14_AopType(__LINE__,left,right,result);
4540   if(result)
4541     DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4542   resolveIfx(&rIfx,ifx);
4543   lbl =  newiTempLabel(NULL);
4544
4545
4546   /* if the left side is a literal or 
4547      if the right is in a pointer register and left 
4548      is not */
4549   if ((AOP_TYPE(left) == AOP_LIT) || 
4550       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4551     operand *t = right;
4552     right = left;
4553     left = t;
4554   }
4555   if(AOP_TYPE(right) == AOP_LIT)
4556     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4557
4558   /* if the right side is a literal then anything goes */
4559   if (AOP_TYPE(right) == AOP_LIT &&
4560       AOP_TYPE(left) != AOP_DIR ) {
4561     switch(size) {
4562     case 2:
4563       genc16bit2lit(left, lit, 0);
4564       emitSKPNZ;
4565       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4566       break;
4567     default:
4568       while (size--) {
4569         if(lit & 0xff) {
4570           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4571           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4572         } else {
4573           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4574         }
4575
4576         emitSKPNZ;
4577         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4578         offset++;
4579         if(res_offset < res_size-1)
4580           res_offset++;
4581         lit >>= 8;
4582       }
4583       break;
4584     }
4585   }
4586
4587   /* if the right side is in a register or in direct space or
4588      if the left is a pointer register & right is not */    
4589   else if (AOP_TYPE(right) == AOP_REG ||
4590            AOP_TYPE(right) == AOP_DIR || 
4591            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4592            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4593     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4594     int lbl_key = lbl->key;
4595
4596     if(result) {
4597       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4598       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4599     }else {
4600       DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4601       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4602               __FUNCTION__,__LINE__);
4603       return;
4604     }
4605
4606 /*     switch(size) { */
4607 /*     case 2: */
4608 /*       genc16bit2lit(left, lit, 0); */
4609 /*       emitSKPNZ; */
4610 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4611 /*       break; */
4612 /*     default: */
4613     while (size--) {
4614       int emit_skip=1;
4615       if((AOP_TYPE(left) == AOP_DIR) && 
4616          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4617
4618         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4620
4621       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4622             
4623         switch (lit & 0xff) {
4624         case 0:
4625           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4626           break;
4627         case 1:
4628           emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4629           emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630           //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4631           emit_skip=0;
4632           break;
4633         case 0xff:
4634           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4635           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4636           //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4637           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4638           emit_skip=0;
4639           break;
4640         default:
4641           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4642           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4643         }
4644         lit >>= 8;
4645
4646       } else {
4647         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4648       }
4649       if(emit_skip) {
4650         if(AOP_TYPE(result) == AOP_CRY) {
4651           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4652           if(rIfx.condition)
4653             emitSKPNZ;
4654           else
4655             emitSKPZ;
4656           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4657         } else {
4658           /* fix me. probably need to check result size too */
4659           //emitpcode(POC_CLRF,popGet(AOP(result),0));
4660           if(rIfx.condition)
4661             emitSKPZ;
4662           else
4663             emitSKPNZ;
4664           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4665           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4666         }
4667         if(ifx)
4668           ifx->generated=1;
4669       }
4670       emit_skip++;
4671       offset++;
4672       if(res_offset < res_size-1)
4673         res_offset++;
4674     }
4675 /*       break; */
4676 /*     } */
4677   } else if(AOP_TYPE(right) == AOP_REG &&
4678             AOP_TYPE(left) != AOP_DIR){
4679
4680     while(size--) {
4681       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4682       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4683       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4684       if(rIfx.condition)
4685         emitSKPNZ;
4686       else
4687         emitSKPZ;
4688       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4689       offset++;
4690       if(res_offset < res_size-1)
4691         res_offset++;
4692     }
4693       
4694   }else{
4695     /* right is a pointer reg need both a & b */
4696     while(size--) {
4697       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4698       if(strcmp(l,"b"))
4699         pic14_emitcode("mov","b,%s",l);
4700       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4701       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4702       offset++;
4703     }
4704   }
4705
4706   emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4707   if(!rIfx.condition)
4708     emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4709
4710   emitpLabel(lbl->key);
4711
4712   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4713
4714   if(ifx)
4715     ifx->generated = 1;
4716 }
4717
4718 #if 0
4719 /*-----------------------------------------------------------------*/
4720 /* gencjne - compare and jump if not equal                         */
4721 /*-----------------------------------------------------------------*/
4722 static void gencjne(operand *left, operand *right, iCode *ifx)
4723 {
4724     symbol *tlbl  = newiTempLabel(NULL);
4725
4726     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4727     gencjneshort(left, right, lbl);
4728
4729     pic14_emitcode("mov","a,%s",one);
4730     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4731     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4732     pic14_emitcode("clr","a");
4733     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4734
4735     emitpLabel(lbl->key);
4736     emitpLabel(tlbl->key);
4737
4738 }
4739 #endif
4740
4741 /*-----------------------------------------------------------------*/
4742 /* genCmpEq - generates code for equal to                          */
4743 /*-----------------------------------------------------------------*/
4744 static void genCmpEq (iCode *ic, iCode *ifx)
4745 {
4746     operand *left, *right, *result;
4747     unsigned long lit = 0L;
4748     int size,offset=0;
4749
4750     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4751
4752     if(ifx)
4753       DEBUGpic14_emitcode ("; ifx is non-null","");
4754     else
4755       DEBUGpic14_emitcode ("; ifx is null","");
4756
4757     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4758     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4759     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4760
4761     size = max(AOP_SIZE(left),AOP_SIZE(right));
4762
4763     DEBUGpic14_AopType(__LINE__,left,right,result);
4764
4765     /* if literal, literal on the right or 
4766     if the right is in a pointer register and left 
4767     is not */
4768     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4769         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4770       operand *tmp = right ;
4771       right = left;
4772       left = tmp;
4773     }
4774
4775
4776     if(ifx && !AOP_SIZE(result)){
4777         symbol *tlbl;
4778         /* if they are both bit variables */
4779         if (AOP_TYPE(left) == AOP_CRY &&
4780             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4781             if(AOP_TYPE(right) == AOP_LIT){
4782                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4783                 if(lit == 0L){
4784                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785                     pic14_emitcode("cpl","c");
4786                 } else if(lit == 1L) {
4787                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4788                 } else {
4789                     pic14_emitcode("clr","c");
4790                 }
4791                 /* AOP_TYPE(right) == AOP_CRY */
4792             } else {
4793                 symbol *lbl = newiTempLabel(NULL);
4794                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4795                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4796                 pic14_emitcode("cpl","c");
4797                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4798             }
4799             /* if true label then we jump if condition
4800             supplied is true */
4801             tlbl = newiTempLabel(NULL);
4802             if ( IC_TRUE(ifx) ) {
4803                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4804                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4805             } else {
4806                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4807                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4808             }
4809             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4810
4811             {
4812               /* left and right are both bit variables, result is carry */
4813               resolvedIfx rIfx;
4814               
4815               resolveIfx(&rIfx,ifx);
4816
4817               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4818               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4819               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4820               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4821               genSkipz2(&rIfx,0);
4822             }
4823         } else {
4824
4825           /* They're not both bit variables. Is the right a literal? */
4826           if(AOP_TYPE(right) == AOP_LIT) {
4827             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4828             
4829             switch(size) {
4830
4831             case 1:
4832               switch(lit & 0xff) {
4833               case 1:
4834                 if ( IC_TRUE(ifx) ) {
4835                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4836                   emitSKPNZ;
4837                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4838                 } else {
4839                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4840                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4841                 }
4842                 break;
4843               case 0xff:
4844                 if ( IC_TRUE(ifx) ) {
4845                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4846                   emitSKPNZ;
4847                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4848                 } else {
4849                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4850                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4851                 }
4852                 break;
4853               default:
4854                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4855                 if(lit)
4856                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4857                 genSkip(ifx,'z');
4858               }
4859
4860
4861               /* end of size == 1 */
4862               break;
4863               
4864             case 2:
4865               genc16bit2lit(left,lit,offset);
4866               genSkip(ifx,'z');
4867               break;
4868               /* end of size == 2 */
4869
4870             default:
4871               /* size is 4 */
4872               if(lit==0) {
4873                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4874                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4875                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4876                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4877
4878               } else {
4879
4880                 /* search for patterns that can be optimized */
4881
4882                 genc16bit2lit(left,lit,0);
4883                 lit >>= 16;
4884                 if(lit) {
4885                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4886                   //genSkip(ifx,'z');
4887                   genc16bit2lit(left,lit,2);
4888                 } else {
4889                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4890                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4891
4892                 }
4893                 
4894               }
4895
4896               genSkip(ifx,'z');
4897             }
4898           
4899             ifx->generated = 1;
4900             goto release ;
4901             
4902
4903           } else if(AOP_TYPE(right) == AOP_CRY ) {
4904             /* we know the left is not a bit, but that the right is */
4905             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4906             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4907                       popGet(AOP(right),offset));
4908             emitpcode(POC_XORLW,popGetLit(1));
4909
4910             /* if the two are equal, then W will be 0 and the Z bit is set
4911              * we could test Z now, or go ahead and check the high order bytes if
4912              * the variable we're comparing is larger than a byte. */
4913
4914             while(--size)
4915               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4916
4917             if ( IC_TRUE(ifx) ) {
4918               emitSKPNZ;
4919               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4920               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4921             } else {
4922               emitSKPZ;
4923               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4924               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4925             }
4926
4927           } else {
4928             /* They're both variables that are larger than bits */
4929             int s = size;
4930
4931             tlbl = newiTempLabel(NULL);
4932
4933             while(size--) {
4934               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4935               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4936
4937               if ( IC_TRUE(ifx) ) {
4938                 if(size) {
4939                   emitSKPZ;
4940                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4941                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4942                 } else {
4943                   emitSKPNZ;
4944                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4945                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4946                 }
4947               } else {
4948                 emitSKPZ;
4949                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4950                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4951               }
4952               offset++;
4953             }
4954             if(s>1 && IC_TRUE(ifx)) {
4955               emitpLabel(tlbl->key);
4956               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4957             }
4958           }
4959         }
4960         /* mark the icode as generated */
4961         ifx->generated = 1;
4962         goto release ;
4963     }
4964
4965     /* if they are both bit variables */
4966     if (AOP_TYPE(left) == AOP_CRY &&
4967         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4968         if(AOP_TYPE(right) == AOP_LIT){
4969             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4970             if(lit == 0L){
4971                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972                 pic14_emitcode("cpl","c");
4973             } else if(lit == 1L) {
4974                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4975             } else {
4976                 pic14_emitcode("clr","c");
4977             }
4978             /* AOP_TYPE(right) == AOP_CRY */
4979         } else {
4980             symbol *lbl = newiTempLabel(NULL);
4981             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4982             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4983             pic14_emitcode("cpl","c");
4984             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4985         }
4986         /* c = 1 if egal */
4987         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4988             pic14_outBitC(result);
4989             goto release ;
4990         }
4991         if (ifx) {
4992             genIfxJump (ifx,"c");
4993             goto release ;
4994         }
4995         /* if the result is used in an arithmetic operation
4996         then put the result in place */
4997         pic14_outBitC(result);
4998     } else {
4999       
5000       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5001       gencjne(left,right,result,ifx);
5002 /*
5003       if(ifx) 
5004         gencjne(left,right,newiTempLabel(NULL));
5005       else {
5006         if(IC_TRUE(ifx)->key)
5007           gencjne(left,right,IC_TRUE(ifx)->key);
5008         else
5009           gencjne(left,right,IC_FALSE(ifx)->key);
5010         ifx->generated = 1;
5011         goto release ;
5012       }
5013       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5014         aopPut(AOP(result),"a",0);
5015         goto release ;
5016       }
5017
5018       if (ifx) {
5019         genIfxJump (ifx,"a");
5020         goto release ;
5021       }
5022 */
5023       /* if the result is used in an arithmetic operation
5024          then put the result in place */
5025 /*
5026       if (AOP_TYPE(result) != AOP_CRY) 
5027         pic14_outAcc(result);
5028 */
5029       /* leave the result in acc */
5030     }
5031
5032 release:
5033     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5034     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035     freeAsmop(result,NULL,ic,TRUE);
5036 }
5037
5038 /*-----------------------------------------------------------------*/
5039 /* ifxForOp - returns the icode containing the ifx for operand     */
5040 /*-----------------------------------------------------------------*/
5041 static iCode *ifxForOp ( operand *op, iCode *ic )
5042 {
5043     /* if true symbol then needs to be assigned */
5044     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5045     if (IS_TRUE_SYMOP(op))
5046         return NULL ;
5047
5048     /* if this has register type condition and
5049     the next instruction is ifx with the same operand
5050     and live to of the operand is upto the ifx only then */
5051     if (ic->next &&
5052         ic->next->op == IFX &&
5053         IC_COND(ic->next)->key == op->key &&
5054         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5055         return ic->next;
5056
5057     if (ic->next &&
5058         ic->next->op == IFX &&
5059         IC_COND(ic->next)->key == op->key) {
5060       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5061       return ic->next;
5062     }
5063
5064     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5065     if (ic->next &&
5066         ic->next->op == IFX)
5067       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5068
5069     if (ic->next &&
5070         ic->next->op == IFX &&
5071         IC_COND(ic->next)->key == op->key) {
5072       DEBUGpic14_emitcode ("; "," key is okay");
5073       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5074                            OP_SYMBOL(op)->liveTo,
5075                            ic->next->seq);
5076     }
5077
5078
5079     return NULL;
5080 }
5081 /*-----------------------------------------------------------------*/
5082 /* genAndOp - for && operation                                     */
5083 /*-----------------------------------------------------------------*/
5084 static void genAndOp (iCode *ic)
5085 {
5086     operand *left,*right, *result;
5087 /*     symbol *tlbl; */
5088
5089     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5090     /* note here that && operations that are in an
5091     if statement are taken away by backPatchLabels
5092     only those used in arthmetic operations remain */
5093     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5094     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5095     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5096
5097     DEBUGpic14_AopType(__LINE__,left,right,result);
5098
5099     emitpcode(POC_MOVFW,popGet(AOP(left),0));
5100     emitpcode(POC_ANDFW,popGet(AOP(right),0));
5101     emitpcode(POC_MOVWF,popGet(AOP(result),0));
5102
5103     /* if both are bit variables */
5104 /*     if (AOP_TYPE(left) == AOP_CRY && */
5105 /*         AOP_TYPE(right) == AOP_CRY ) { */
5106 /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5107 /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5108 /*         pic14_outBitC(result); */
5109 /*     } else { */
5110 /*         tlbl = newiTempLabel(NULL); */
5111 /*         pic14_toBoolean(left);     */
5112 /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5113 /*         pic14_toBoolean(right); */
5114 /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5115 /*         pic14_outBitAcc(result); */
5116 /*     } */
5117
5118     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5119     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5120     freeAsmop(result,NULL,ic,TRUE);
5121 }
5122
5123
5124 /*-----------------------------------------------------------------*/
5125 /* genOrOp - for || operation                                      */
5126 /*-----------------------------------------------------------------*/
5127 /*
5128   tsd pic port -
5129   modified this code, but it doesn't appear to ever get called
5130 */
5131
5132 static void genOrOp (iCode *ic)
5133 {
5134     operand *left,*right, *result;
5135     symbol *tlbl;
5136
5137     /* note here that || operations that are in an
5138     if statement are taken away by backPatchLabels
5139     only those used in arthmetic operations remain */
5140     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5141     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5142     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5143     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5144
5145     DEBUGpic14_AopType(__LINE__,left,right,result);
5146
5147     /* if both are bit variables */
5148     if (AOP_TYPE(left) == AOP_CRY &&
5149         AOP_TYPE(right) == AOP_CRY ) {
5150       pic14_emitcode("clrc","");
5151       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5152                AOP(left)->aopu.aop_dir,
5153                AOP(left)->aopu.aop_dir);
5154       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5155                AOP(right)->aopu.aop_dir,
5156                AOP(right)->aopu.aop_dir);
5157       pic14_emitcode("setc","");
5158
5159     } else {
5160         tlbl = newiTempLabel(NULL);
5161         pic14_toBoolean(left);
5162         emitSKPZ;
5163         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5164         pic14_toBoolean(right);
5165         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5166
5167         pic14_outBitAcc(result);
5168     }
5169
5170     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5171     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5172     freeAsmop(result,NULL,ic,TRUE);            
5173 }
5174
5175 /*-----------------------------------------------------------------*/
5176 /* isLiteralBit - test if lit == 2^n                               */
5177 /*-----------------------------------------------------------------*/
5178 static int isLiteralBit(unsigned long lit)
5179 {
5180     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5181     0x100L,0x200L,0x400L,0x800L,
5182     0x1000L,0x2000L,0x4000L,0x8000L,
5183     0x10000L,0x20000L,0x40000L,0x80000L,
5184     0x100000L,0x200000L,0x400000L,0x800000L,
5185     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5186     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5187     int idx;
5188     
5189     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5190     for(idx = 0; idx < 32; idx++)
5191         if(lit == pw[idx])
5192             return idx+1;
5193     return 0;
5194 }
5195
5196 /*-----------------------------------------------------------------*/
5197 /* continueIfTrue -                                                */
5198 /*-----------------------------------------------------------------*/
5199 static void continueIfTrue (iCode *ic)
5200 {
5201     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5202     if(IC_TRUE(ic))
5203         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5204     ic->generated = 1;
5205 }
5206
5207 /*-----------------------------------------------------------------*/
5208 /* jmpIfTrue -                                                     */
5209 /*-----------------------------------------------------------------*/
5210 static void jumpIfTrue (iCode *ic)
5211 {
5212     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5213     if(!IC_TRUE(ic))
5214         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5215     ic->generated = 1;
5216 }
5217
5218 /*-----------------------------------------------------------------*/
5219 /* jmpTrueOrFalse -                                                */
5220 /*-----------------------------------------------------------------*/
5221 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5222 {
5223     // ugly but optimized by peephole
5224     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5225     if(IC_TRUE(ic)){
5226         symbol *nlbl = newiTempLabel(NULL);
5227         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5228         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5229         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5230         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5231     }
5232     else{
5233         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5234         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5235     }
5236     ic->generated = 1;
5237 }
5238
5239 /*-----------------------------------------------------------------*/
5240 /* genAnd  - code for and                                          */
5241 /*-----------------------------------------------------------------*/
5242 static void genAnd (iCode *ic, iCode *ifx)
5243 {
5244   operand *left, *right, *result;
5245   int size, offset=0;  
5246   unsigned long lit = 0L;
5247   int bytelit = 0;
5248   resolvedIfx rIfx;
5249
5250
5251   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5252   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5253   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5254   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5255
5256   resolveIfx(&rIfx,ifx);
5257
5258   /* if left is a literal & right is not then exchange them */
5259   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5260       AOP_NEEDSACC(left)) {
5261     operand *tmp = right ;
5262     right = left;
5263     left = tmp;
5264   }
5265
5266   /* if result = right then exchange them */
5267   if(pic14_sameRegs(AOP(result),AOP(right))){
5268     operand *tmp = right ;
5269     right = left;
5270     left = tmp;
5271   }
5272
5273   /* if right is bit then exchange them */
5274   if (AOP_TYPE(right) == AOP_CRY &&
5275       AOP_TYPE(left) != AOP_CRY){
5276     operand *tmp = right ;
5277     right = left;
5278     left = tmp;
5279   }
5280   if(AOP_TYPE(right) == AOP_LIT)
5281     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5282
5283   size = AOP_SIZE(result);
5284
5285   DEBUGpic14_AopType(__LINE__,left,right,result);
5286
5287   // if(bit & yy)
5288   // result = bit & yy;
5289   if (AOP_TYPE(left) == AOP_CRY){
5290     // c = bit & literal;
5291     if(AOP_TYPE(right) == AOP_LIT){
5292       if(lit & 1) {
5293         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5294           // no change
5295           goto release;
5296         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5297       } else {
5298         // bit(result) = 0;
5299         if(size && (AOP_TYPE(result) == AOP_CRY)){
5300           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5301           goto release;
5302         }
5303         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5304           jumpIfTrue(ifx);
5305           goto release;
5306         }
5307         pic14_emitcode("clr","c");
5308       }
5309     } else {
5310       if (AOP_TYPE(right) == AOP_CRY){
5311         // c = bit & bit;
5312         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5313         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5314       } else {
5315         // c = bit & val;
5316         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5317         // c = lsb
5318         pic14_emitcode("rrc","a");
5319         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5320       }
5321     }
5322     // bit = c
5323     // val = c
5324     if(size)
5325       pic14_outBitC(result);
5326     // if(bit & ...)
5327     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5328       genIfxJump(ifx, "c");           
5329     goto release ;
5330   }
5331
5332   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5333   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5334   if((AOP_TYPE(right) == AOP_LIT) &&
5335      (AOP_TYPE(result) == AOP_CRY) &&
5336      (AOP_TYPE(left) != AOP_CRY)){
5337     int posbit = isLiteralBit(lit);
5338     /* left &  2^n */
5339     if(posbit){
5340       posbit--;
5341       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5342       // bit = left & 2^n
5343       if(size)
5344         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5345       // if(left &  2^n)
5346       else{
5347         if(ifx){
5348 /*
5349           if(IC_TRUE(ifx)) {
5350             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5351             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5352           } else {
5353             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5354             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5355           }
5356 */
5357           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5358                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5359           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5360           
5361           ifx->generated = 1;
5362         }
5363         goto release;
5364       }
5365     } else {
5366       symbol *tlbl = newiTempLabel(NULL);
5367       int sizel = AOP_SIZE(left);
5368       if(size)
5369         pic14_emitcode("setb","c");
5370       while(sizel--){
5371         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5372           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5373           // byte ==  2^n ?
5374           if((posbit = isLiteralBit(bytelit)) != 0)
5375             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5376           else{
5377             if(bytelit != 0x0FFL)
5378               pic14_emitcode("anl","a,%s",
5379                              aopGet(AOP(right),offset,FALSE,TRUE));
5380             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5381           }
5382         }
5383         offset++;
5384       }
5385       // bit = left & literal
5386       if(size){
5387         pic14_emitcode("clr","c");
5388         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5389       }
5390       // if(left & literal)
5391       else{
5392         if(ifx)
5393           jmpTrueOrFalse(ifx, tlbl);
5394         goto release ;
5395       }
5396     }
5397     pic14_outBitC(result);
5398     goto release ;
5399   }
5400
5401   /* if left is same as result */
5402   if(pic14_sameRegs(AOP(result),AOP(left))){
5403     int know_W = -1;
5404     for(;size--; offset++,lit>>=8) {
5405       if(AOP_TYPE(right) == AOP_LIT){
5406         switch(lit & 0xff) {
5407         case 0x00:
5408           /*  and'ing with 0 has clears the result */
5409           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5410           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5411           break;
5412         case 0xff:
5413           /* and'ing with 0xff is a nop when the result and left are the same */
5414           break;
5415
5416         default:
5417           {
5418             int p = my_powof2( (~lit) & 0xff );
5419             if(p>=0) {
5420               /* only one bit is set in the literal, so use a bcf instruction */
5421               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5422               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5423
5424             } else {
5425               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5426               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5427               if(know_W != (lit&0xff))
5428                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5429               know_W = lit &0xff;
5430               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5431             }
5432           }    
5433         }
5434       } else {
5435         if (AOP_TYPE(left) == AOP_ACC) {
5436           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5437         } else {                    
5438           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5439           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5440
5441         }
5442       }
5443     }
5444
5445   } else {
5446     // left & result in different registers
5447     if(AOP_TYPE(result) == AOP_CRY){
5448       // result = bit
5449       // if(size), result in bit
5450       // if(!size && ifx), conditional oper: if(left & right)
5451       symbol *tlbl = newiTempLabel(NULL);
5452       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5453       if(size)
5454         pic14_emitcode("setb","c");
5455       while(sizer--){
5456         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5457         pic14_emitcode("anl","a,%s",
5458                        aopGet(AOP(left),offset,FALSE,FALSE));
5459         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5460         offset++;
5461       }
5462       if(size){
5463         CLRC;
5464         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5465         pic14_outBitC(result);
5466       } else if(ifx)
5467         jmpTrueOrFalse(ifx, tlbl);
5468     } else {
5469       for(;(size--);offset++) {
5470         // normal case
5471         // result = left & right
5472         if(AOP_TYPE(right) == AOP_LIT){
5473           int t = (lit >> (offset*8)) & 0x0FFL;
5474           switch(t) { 
5475           case 0x00:
5476             pic14_emitcode("clrf","%s",
5477                            aopGet(AOP(result),offset,FALSE,FALSE));
5478             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5479             break;
5480           case 0xff:
5481             if(AOP_TYPE(left) != AOP_ACC) {
5482               pic14_emitcode("movf","%s,w",
5483                              aopGet(AOP(left),offset,FALSE,FALSE));
5484               pic14_emitcode("movwf","%s",
5485                              aopGet(AOP(result),offset,FALSE,FALSE));
5486               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5487             }
5488             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5489             break;
5490           default:
5491             if(AOP_TYPE(left) == AOP_ACC) {
5492               emitpcode(POC_ANDLW, popGetLit(t));
5493             } else {
5494               pic14_emitcode("movlw","0x%x",t);
5495               pic14_emitcode("andwf","%s,w",
5496                              aopGet(AOP(left),offset,FALSE,FALSE));
5497               pic14_emitcode("movwf","%s",
5498                              aopGet(AOP(result),offset,FALSE,FALSE));
5499               
5500               emitpcode(POC_MOVLW, popGetLit(t));
5501               emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5502             }
5503             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5504           }
5505           continue;
5506         }
5507
5508         if (AOP_TYPE(left) == AOP_ACC) {
5509           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5510           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5511         } else {
5512           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5513           pic14_emitcode("andwf","%s,w",
5514                          aopGet(AOP(left),offset,FALSE,FALSE));
5515           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5516           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5517         }
5518         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5519         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5520       }
5521     }
5522   }
5523
5524   release :
5525     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5526   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5527   freeAsmop(result,NULL,ic,TRUE);     
5528 }
5529
5530 /*-----------------------------------------------------------------*/
5531 /* genOr  - code for or                                            */
5532 /*-----------------------------------------------------------------*/
5533 static void genOr (iCode *ic, iCode *ifx)
5534 {
5535     operand *left, *right, *result;
5536     int size, offset=0;
5537     unsigned long lit = 0L;
5538
5539     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5540
5541     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5542     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5543     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5544
5545     DEBUGpic14_AopType(__LINE__,left,right,result);
5546
5547     /* if left is a literal & right is not then exchange them */
5548     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5549         AOP_NEEDSACC(left)) {
5550         operand *tmp = right ;
5551         right = left;
5552         left = tmp;
5553     }
5554
5555     /* if result = right then exchange them */
5556     if(pic14_sameRegs(AOP(result),AOP(right))){
5557         operand *tmp = right ;
5558         right = left;
5559         left = tmp;
5560     }
5561
5562     /* if right is bit then exchange them */
5563     if (AOP_TYPE(right) == AOP_CRY &&
5564         AOP_TYPE(left) != AOP_CRY){
5565         operand *tmp = right ;
5566         right = left;
5567         left = tmp;
5568     }
5569
5570     DEBUGpic14_AopType(__LINE__,left,right,result);
5571
5572     if(AOP_TYPE(right) == AOP_LIT)
5573         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5574
5575     size = AOP_SIZE(result);
5576
5577     // if(bit | yy)
5578     // xx = bit | yy;
5579     if (AOP_TYPE(left) == AOP_CRY){
5580         if(AOP_TYPE(right) == AOP_LIT){
5581             // c = bit & literal;
5582             if(lit){
5583                 // lit != 0 => result = 1
5584                 if(AOP_TYPE(result) == AOP_CRY){
5585                   if(size)
5586                     emitpcode(POC_BSF, popGet(AOP(result),0));
5587                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5588                   //     AOP(result)->aopu.aop_dir,
5589                   //     AOP(result)->aopu.aop_dir);
5590                     else if(ifx)
5591                         continueIfTrue(ifx);
5592                     goto release;
5593                 }
5594             } else {
5595                 // lit == 0 => result = left
5596                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5597                     goto release;
5598                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5599             }
5600         } else {
5601             if (AOP_TYPE(right) == AOP_CRY){
5602               if(pic14_sameRegs(AOP(result),AOP(left))){
5603                 // c = bit | bit;
5604                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5605                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5606                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5607
5608                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5609                          AOP(result)->aopu.aop_dir,
5610                          AOP(result)->aopu.aop_dir);
5611                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5612                          AOP(right)->aopu.aop_dir,
5613                          AOP(right)->aopu.aop_dir);
5614                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5615                          AOP(result)->aopu.aop_dir,
5616                          AOP(result)->aopu.aop_dir);
5617               } else {
5618                 if( AOP_TYPE(result) == AOP_ACC) {
5619                   emitpcode(POC_MOVLW, popGetLit(0));
5620                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5621                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5622                   emitpcode(POC_MOVLW, popGetLit(1));
5623
5624                 } else {
5625
5626                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5627                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5628                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5629                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5630
5631                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5632                                  AOP(result)->aopu.aop_dir,
5633                                  AOP(result)->aopu.aop_dir);
5634                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5635                                  AOP(right)->aopu.aop_dir,
5636                                  AOP(right)->aopu.aop_dir);
5637                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5638                                  AOP(left)->aopu.aop_dir,
5639                                  AOP(left)->aopu.aop_dir);
5640                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5641                                  AOP(result)->aopu.aop_dir,
5642                                  AOP(result)->aopu.aop_dir);
5643                 }
5644               }
5645             } else {
5646                 // c = bit | val;
5647                 symbol *tlbl = newiTempLabel(NULL);
5648                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5649
5650
5651                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5652                 if( AOP_TYPE(right) == AOP_ACC) {
5653                   emitpcode(POC_IORLW, popGetLit(0));
5654                   emitSKPNZ;
5655                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5656                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5657                 }
5658
5659
5660
5661                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5662                     pic14_emitcode(";XXX setb","c");
5663                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5664                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5665                 pic14_toBoolean(right);
5666                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5667                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5668                     jmpTrueOrFalse(ifx, tlbl);
5669                     goto release;
5670                 } else {
5671                     CLRC;
5672                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5673                 }
5674             }
5675         }
5676         // bit = c
5677         // val = c
5678         if(size)
5679             pic14_outBitC(result);
5680         // if(bit | ...)
5681         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5682             genIfxJump(ifx, "c");           
5683         goto release ;
5684     }
5685
5686     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5687     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5688     if((AOP_TYPE(right) == AOP_LIT) &&
5689        (AOP_TYPE(result) == AOP_CRY) &&
5690        (AOP_TYPE(left) != AOP_CRY)){
5691         if(lit){
5692           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5693             // result = 1
5694             if(size)
5695                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5696             else 
5697                 continueIfTrue(ifx);
5698             goto release;
5699         } else {
5700           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5701             // lit = 0, result = boolean(left)
5702             if(size)
5703                 pic14_emitcode(";XXX setb","c");
5704             pic14_toBoolean(right);
5705             if(size){
5706                 symbol *tlbl = newiTempLabel(NULL);
5707                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5708                 CLRC;
5709                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5710             } else {
5711                 genIfxJump (ifx,"a");
5712                 goto release;
5713             }
5714         }
5715         pic14_outBitC(result);
5716         goto release ;
5717     }
5718
5719     /* if left is same as result */
5720     if(pic14_sameRegs(AOP(result),AOP(left))){
5721       int know_W = -1;
5722       for(;size--; offset++,lit>>=8) {
5723         if(AOP_TYPE(right) == AOP_LIT){
5724           if((lit & 0xff) == 0)
5725             /*  or'ing with 0 has no effect */
5726             continue;
5727           else {
5728             int p = my_powof2(lit & 0xff);
5729             if(p>=0) {
5730               /* only one bit is set in the literal, so use a bsf instruction */
5731               emitpcode(POC_BSF,
5732                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5733             } else {
5734               if(know_W != (lit & 0xff))
5735                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5736               know_W = lit & 0xff;
5737               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5738             }
5739                     
5740           }
5741         } else {
5742           if (AOP_TYPE(left) == AOP_ACC) {
5743             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5744             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5745           } else {                  
5746             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5747             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5748
5749             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5750             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5751
5752           }
5753         }
5754       }
5755     } else {
5756         // left & result in different registers
5757         if(AOP_TYPE(result) == AOP_CRY){
5758             // result = bit
5759             // if(size), result in bit
5760             // if(!size && ifx), conditional oper: if(left | right)
5761             symbol *tlbl = newiTempLabel(NULL);
5762             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5763             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5764
5765
5766             if(size)
5767                 pic14_emitcode(";XXX setb","c");
5768             while(sizer--){
5769                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5770                 pic14_emitcode(";XXX orl","a,%s",
5771                          aopGet(AOP(left),offset,FALSE,FALSE));
5772                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5773                 offset++;
5774             }
5775             if(size){
5776                 CLRC;
5777                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5778                 pic14_outBitC(result);
5779             } else if(ifx)
5780                 jmpTrueOrFalse(ifx, tlbl);
5781         } else for(;(size--);offset++){
5782           // normal case
5783           // result = left & right
5784           if(AOP_TYPE(right) == AOP_LIT){
5785             int t = (lit >> (offset*8)) & 0x0FFL;
5786             switch(t) { 
5787             case 0x00:
5788               if (AOP_TYPE(left) != AOP_ACC) {
5789                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5790               }
5791               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5792
5793               break;
5794             default:
5795               if (AOP_TYPE(left) == AOP_ACC) {
5796                 emitpcode(POC_IORLW,  popGetLit(t));
5797               } else {
5798                 emitpcode(POC_MOVLW,  popGetLit(t));
5799                 emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5800               }
5801               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));              
5802             }
5803             continue;
5804           }
5805
5806           // faster than result <- left, anl result,right
5807           // and better if result is SFR
5808           if (AOP_TYPE(left) == AOP_ACC) {
5809             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5810             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5811           } else {
5812             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5813             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5814
5815             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5816             pic14_emitcode("iorwf","%s,w",
5817                      aopGet(AOP(left),offset,FALSE,FALSE));
5818           }
5819           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5820           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5821         }
5822     }
5823
5824 release :
5825     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5827     freeAsmop(result,NULL,ic,TRUE);     
5828 }
5829
5830 /*-----------------------------------------------------------------*/
5831 /* genXor - code for xclusive or                                   */
5832 /*-----------------------------------------------------------------*/
5833 static void genXor (iCode *ic, iCode *ifx)
5834 {
5835   operand *left, *right, *result;
5836   int size, offset=0;
5837   unsigned long lit = 0L;
5838
5839   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5840
5841   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5842   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5843   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5844
5845   /* if left is a literal & right is not ||
5846      if left needs acc & right does not */
5847   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5848       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5849     operand *tmp = right ;
5850     right = left;
5851     left = tmp;
5852   }
5853
5854   /* if result = right then exchange them */
5855   if(pic14_sameRegs(AOP(result),AOP(right))){
5856     operand *tmp = right ;
5857     right = left;
5858     left = tmp;
5859   }
5860
5861   /* if right is bit then exchange them */
5862   if (AOP_TYPE(right) == AOP_CRY &&
5863       AOP_TYPE(left) != AOP_CRY){
5864     operand *tmp = right ;
5865     right = left;
5866     left = tmp;
5867   }
5868   if(AOP_TYPE(right) == AOP_LIT)
5869     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5870
5871   size = AOP_SIZE(result);
5872
5873   // if(bit ^ yy)
5874   // xx = bit ^ yy;
5875   if (AOP_TYPE(left) == AOP_CRY){
5876     if(AOP_TYPE(right) == AOP_LIT){
5877       // c = bit & literal;
5878       if(lit>>1){
5879         // lit>>1  != 0 => result = 1
5880         if(AOP_TYPE(result) == AOP_CRY){
5881           if(size)
5882             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5883             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5884           else if(ifx)
5885             continueIfTrue(ifx);
5886           goto release;
5887         }
5888         pic14_emitcode("setb","c");
5889       } else{
5890         // lit == (0 or 1)
5891         if(lit == 0){
5892           // lit == 0, result = left
5893           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5894             goto release;
5895           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5896         } else{
5897           // lit == 1, result = not(left)
5898           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5899             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5900             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5901             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5902             goto release;
5903           } else {
5904             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5905             pic14_emitcode("cpl","c");
5906           }
5907         }
5908       }
5909
5910     } else {
5911       // right != literal
5912       symbol *tlbl = newiTempLabel(NULL);
5913       if (AOP_TYPE(right) == AOP_CRY){
5914         // c = bit ^ bit;
5915         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5916       }
5917       else{
5918         int sizer = AOP_SIZE(right);
5919         // c = bit ^ val
5920         // if val>>1 != 0, result = 1
5921         pic14_emitcode("setb","c");
5922         while(sizer){
5923           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5924           if(sizer == 1)
5925             // test the msb of the lsb
5926             pic14_emitcode("anl","a,#0xfe");
5927           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5928           sizer--;
5929         }
5930         // val = (0,1)
5931         pic14_emitcode("rrc","a");
5932       }
5933       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5934       pic14_emitcode("cpl","c");
5935       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5936     }
5937     // bit = c
5938     // val = c
5939     if(size)
5940       pic14_outBitC(result);
5941     // if(bit | ...)
5942     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5943       genIfxJump(ifx, "c");           
5944     goto release ;
5945   }
5946
5947   if(pic14_sameRegs(AOP(result),AOP(left))){
5948     /* if left is same as result */
5949     for(;size--; offset++) {
5950       if(AOP_TYPE(right) == AOP_LIT){
5951         int t  = (lit >> (offset*8)) & 0x0FFL;
5952         if(t == 0x00L)
5953           continue;
5954         else
5955           if (IS_AOP_PREG(left)) {
5956             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5957             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5958             aopPut(AOP(result),"a",offset);
5959           } else {
5960             emitpcode(POC_MOVLW, popGetLit(t));
5961             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5962             pic14_emitcode("xrl","%s,%s",
5963                            aopGet(AOP(left),offset,FALSE,TRUE),
5964                            aopGet(AOP(right),offset,FALSE,FALSE));
5965           }
5966       } else {
5967         if (AOP_TYPE(left) == AOP_ACC)
5968           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5969         else {
5970           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5971           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5972 /*
5973           if (IS_AOP_PREG(left)) {
5974             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5975             aopPut(AOP(result),"a",offset);
5976           } else
5977             pic14_emitcode("xrl","%s,a",
5978                            aopGet(AOP(left),offset,FALSE,TRUE));
5979 */
5980         }
5981       }
5982     }
5983   } else {
5984     // left & result in different registers
5985     if(AOP_TYPE(result) == AOP_CRY){
5986       // result = bit
5987       // if(size), result in bit
5988       // if(!size && ifx), conditional oper: if(left ^ right)
5989       symbol *tlbl = newiTempLabel(NULL);
5990       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5991       if(size)
5992         pic14_emitcode("setb","c");
5993       while(sizer--){
5994         if((AOP_TYPE(right) == AOP_LIT) &&
5995            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5996           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5997         } else {
5998           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5999           pic14_emitcode("xrl","a,%s",
6000                          aopGet(AOP(left),offset,FALSE,FALSE));
6001         }
6002         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6003         offset++;
6004       }
6005       if(size){
6006         CLRC;
6007         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6008         pic14_outBitC(result);
6009       } else if(ifx)
6010         jmpTrueOrFalse(ifx, tlbl);
6011     } else for(;(size--);offset++){
6012       // normal case
6013       // result = left & right
6014       if(AOP_TYPE(right) == AOP_LIT){
6015         int t = (lit >> (offset*8)) & 0x0FFL;
6016         switch(t) { 
6017         case 0x00:
6018           if (AOP_TYPE(left) != AOP_ACC) {
6019             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6020           }
6021           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6022           pic14_emitcode("movf","%s,w",
6023                          aopGet(AOP(left),offset,FALSE,FALSE));
6024           pic14_emitcode("movwf","%s",
6025                          aopGet(AOP(result),offset,FALSE,FALSE));
6026           break;
6027         case 0xff:
6028           if (AOP_TYPE(left) == AOP_ACC) {
6029             emitpcode(POC_XORLW, popGetLit(t));
6030           } else {
6031             emitpcode(POC_COMFW,popGet(AOP(left),offset));
6032           }
6033           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6034           break;
6035         default:
6036           if (AOP_TYPE(left) == AOP_ACC) {
6037             emitpcode(POC_XORLW, popGetLit(t));
6038           } else {
6039             emitpcode(POC_MOVLW, popGetLit(t));
6040             emitpcode(POC_XORFW,popGet(AOP(left),offset));
6041           }
6042           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6043           pic14_emitcode("movlw","0x%x",t);
6044           pic14_emitcode("xorwf","%s,w",
6045                          aopGet(AOP(left),offset,FALSE,FALSE));
6046           pic14_emitcode("movwf","%s",
6047                          aopGet(AOP(result),offset,FALSE,FALSE));
6048
6049         }
6050         continue;
6051       }
6052
6053       // faster than result <- left, anl result,right
6054       // and better if result is SFR
6055       if (AOP_TYPE(left) == AOP_ACC) {
6056         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6057         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6058       } else {
6059         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6060         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6061         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6062         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6063       }
6064       if ( AOP_TYPE(result) != AOP_ACC){
6065         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6066         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6067       }
6068     }
6069   }
6070
6071   release :
6072     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6073   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6074   freeAsmop(result,NULL,ic,TRUE);     
6075 }
6076
6077 /*-----------------------------------------------------------------*/
6078 /* genInline - write the inline code out                           */
6079 /*-----------------------------------------------------------------*/
6080 static void genInline (iCode *ic)
6081 {
6082     char *buffer, *bp, *bp1;
6083     
6084     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6085
6086     _G.inLine += (!options.asmpeep);
6087
6088     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6089     strcpy(buffer,IC_INLINE(ic));
6090
6091     /* emit each line as a code */
6092     while (*bp) {
6093         if (*bp == '\n') {
6094             *bp++ = '\0';
6095
6096             if(*bp1)
6097               addpCode2pBlock(pb,AssembleLine(bp1));
6098             bp1 = bp;
6099         } else {
6100             if (*bp == ':') {
6101                 bp++;
6102                 *bp = '\0';
6103                 bp++;
6104                 pic14_emitcode(bp1,"");
6105                 bp1 = bp;
6106             } else
6107                 bp++;
6108         }
6109     }
6110     if ((bp1 != bp) && *bp1)
6111       addpCode2pBlock(pb,AssembleLine(bp1));
6112
6113     Safe_free(buffer);
6114
6115     _G.inLine -= (!options.asmpeep);
6116 }
6117
6118 /*-----------------------------------------------------------------*/
6119 /* genRRC - rotate right with carry                                */
6120 /*-----------------------------------------------------------------*/
6121 static void genRRC (iCode *ic)
6122 {
6123   operand *left , *result ;
6124   int size, offset = 0, same;
6125
6126   /* rotate right with carry */
6127   left = IC_LEFT(ic);
6128   result=IC_RESULT(ic);
6129   aopOp (left,ic,FALSE);
6130   aopOp (result,ic,FALSE);
6131
6132   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6133
6134   same = pic14_sameRegs(AOP(result),AOP(left));
6135
6136   size = AOP_SIZE(result);    
6137
6138   /* get the lsb and put it into the carry */
6139   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6140
6141   offset = 0 ;
6142
6143   while(size--) {
6144
6145     if(same) {
6146       emitpcode(POC_RRF, popGet(AOP(left),offset));
6147     } else {
6148       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6149       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6150     }
6151
6152     offset++;
6153   }
6154
6155   freeAsmop(left,NULL,ic,TRUE);
6156   freeAsmop(result,NULL,ic,TRUE);
6157 }
6158
6159 /*-----------------------------------------------------------------*/
6160 /* genRLC - generate code for rotate left with carry               */
6161 /*-----------------------------------------------------------------*/
6162 static void genRLC (iCode *ic)
6163 {    
6164   operand *left , *result ;
6165   int size, offset = 0;
6166   int same;
6167
6168   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6169   /* rotate right with carry */
6170   left = IC_LEFT(ic);
6171   result=IC_RESULT(ic);
6172   aopOp (left,ic,FALSE);
6173   aopOp (result,ic,FALSE);
6174
6175   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6176
6177   same = pic14_sameRegs(AOP(result),AOP(left));
6178
6179   /* move it to the result */
6180   size = AOP_SIZE(result);    
6181
6182   /* get the msb and put it into the carry */
6183   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6184
6185   offset = 0 ;
6186
6187   while(size--) {
6188
6189     if(same) {
6190       emitpcode(POC_RLF, popGet(AOP(left),offset));
6191     } else {
6192       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6193       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6194     }
6195
6196     offset++;
6197   }
6198
6199
6200   freeAsmop(left,NULL,ic,TRUE);
6201   freeAsmop(result,NULL,ic,TRUE);
6202 }
6203
6204 /*-----------------------------------------------------------------*/
6205 /* genGetHbit - generates code get highest order bit               */
6206 /*-----------------------------------------------------------------*/
6207 static void genGetHbit (iCode *ic)
6208 {
6209     operand *left, *result;
6210     left = IC_LEFT(ic);
6211     result=IC_RESULT(ic);
6212     aopOp (left,ic,FALSE);
6213     aopOp (result,ic,FALSE);
6214
6215     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6216     /* get the highest order byte into a */
6217     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6218     if(AOP_TYPE(result) == AOP_CRY){
6219         pic14_emitcode("rlc","a");
6220         pic14_outBitC(result);
6221     }
6222     else{
6223         pic14_emitcode("rl","a");
6224         pic14_emitcode("anl","a,#0x01");
6225         pic14_outAcc(result);
6226     }
6227
6228
6229     freeAsmop(left,NULL,ic,TRUE);
6230     freeAsmop(result,NULL,ic,TRUE);
6231 }
6232
6233 /*-----------------------------------------------------------------*/
6234 /* AccRol - rotate left accumulator by known count                 */
6235 /*-----------------------------------------------------------------*/
6236 static void AccRol (int shCount)
6237 {
6238     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6239     shCount &= 0x0007;              // shCount : 0..7
6240     switch(shCount){
6241         case 0 :
6242             break;
6243         case 1 :
6244             pic14_emitcode("rl","a");
6245             break;
6246         case 2 :
6247             pic14_emitcode("rl","a");
6248             pic14_emitcode("rl","a");
6249             break;
6250         case 3 :
6251             pic14_emitcode("swap","a");
6252             pic14_emitcode("rr","a");
6253             break;
6254         case 4 :
6255             pic14_emitcode("swap","a");
6256             break;
6257         case 5 :
6258             pic14_emitcode("swap","a");
6259             pic14_emitcode("rl","a");
6260             break;
6261         case 6 :
6262             pic14_emitcode("rr","a");
6263             pic14_emitcode("rr","a");
6264             break;
6265         case 7 :
6266             pic14_emitcode("rr","a");
6267             break;
6268     }
6269 }
6270
6271 /*-----------------------------------------------------------------*/
6272 /* AccLsh - left shift accumulator by known count                  */
6273 /*-----------------------------------------------------------------*/
6274 static void AccLsh (int shCount)
6275 {
6276     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6277     if(shCount != 0){
6278         if(shCount == 1)
6279             pic14_emitcode("add","a,acc");
6280         else 
6281             if(shCount == 2) {
6282             pic14_emitcode("add","a,acc");
6283             pic14_emitcode("add","a,acc");
6284         } else {
6285             /* rotate left accumulator */
6286             AccRol(shCount);
6287             /* and kill the lower order bits */
6288             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6289         }
6290     }
6291 }
6292
6293 /*-----------------------------------------------------------------*/
6294 /* AccRsh - right shift accumulator by known count                 */
6295 /*-----------------------------------------------------------------*/
6296 static void AccRsh (int shCount)
6297 {
6298     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6299     if(shCount != 0){
6300         if(shCount == 1){
6301             CLRC;
6302             pic14_emitcode("rrc","a");
6303         } else {
6304             /* rotate right accumulator */
6305             AccRol(8 - shCount);
6306             /* and kill the higher order bits */
6307             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6308         }
6309     }
6310 }
6311
6312 #if 0
6313 /*-----------------------------------------------------------------*/
6314 /* AccSRsh - signed right shift accumulator by known count                 */
6315 /*-----------------------------------------------------------------*/
6316 static void AccSRsh (int shCount)
6317 {
6318     symbol *tlbl ;
6319     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6320     if(shCount != 0){
6321         if(shCount == 1){
6322             pic14_emitcode("mov","c,acc.7");
6323             pic14_emitcode("rrc","a");
6324         } else if(shCount == 2){
6325             pic14_emitcode("mov","c,acc.7");
6326             pic14_emitcode("rrc","a");
6327             pic14_emitcode("mov","c,acc.7");
6328             pic14_emitcode("rrc","a");
6329         } else {
6330             tlbl = newiTempLabel(NULL);
6331             /* rotate right accumulator */
6332             AccRol(8 - shCount);
6333             /* and kill the higher order bits */
6334             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6335             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6336             pic14_emitcode("orl","a,#0x%02x",
6337                      (unsigned char)~SRMask[shCount]);
6338             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6339         }
6340     }
6341 }
6342 #endif
6343 /*-----------------------------------------------------------------*/
6344 /* shiftR1Left2Result - shift right one byte from left to result   */
6345 /*-----------------------------------------------------------------*/
6346 static void shiftR1Left2ResultSigned (operand *left, int offl,
6347                                 operand *result, int offr,
6348                                 int shCount)
6349 {
6350   int same;
6351
6352   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6353
6354   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6355
6356   switch(shCount) {
6357   case 1:
6358     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6359     if(same) 
6360       emitpcode(POC_RRF, popGet(AOP(result),offr));
6361     else {
6362       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6363       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6364     }
6365
6366     break;
6367   case 2:
6368
6369     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6370     if(same) 
6371       emitpcode(POC_RRF, popGet(AOP(result),offr));
6372     else {
6373       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6374       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6375     }
6376     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6377     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6378
6379     break;
6380
6381   case 3:
6382     if(same)
6383       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6384     else {
6385       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6386       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6387     }
6388
6389     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6390     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6391     emitpcode(POC_ANDLW, popGetLit(0x1f));
6392
6393     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6394     emitpcode(POC_IORLW, popGetLit(0xe0));
6395
6396     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6397     break;
6398
6399   case 4:
6400     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6401     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6402     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6403     emitpcode(POC_IORLW,  popGetLit(0xf0));
6404     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6405     break;
6406   case 5:
6407     if(same) {
6408       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6409     } else {
6410       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6411       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6412     }
6413     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6414     emitpcode(POC_ANDLW,  popGetLit(0x07));
6415     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6416     emitpcode(POC_IORLW,  popGetLit(0xf8));
6417     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6418     break;
6419
6420   case 6:
6421     if(same) {
6422       emitpcode(POC_MOVLW, popGetLit(0x00));
6423       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6424       emitpcode(POC_MOVLW, popGetLit(0xfe));
6425       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6426       emitpcode(POC_IORLW, popGetLit(0x01));
6427       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6428     } else {
6429       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6430       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6431       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6432       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6433       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6434     }
6435     break;
6436
6437   case 7:
6438     if(same) {
6439       emitpcode(POC_MOVLW, popGetLit(0x00));
6440       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6441       emitpcode(POC_MOVLW, popGetLit(0xff));
6442       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6443     } else {
6444       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6445       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6446       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6447     }
6448
6449   default:
6450     break;
6451   }
6452 }
6453
6454 /*-----------------------------------------------------------------*/
6455 /* shiftR1Left2Result - shift right one byte from left to result   */
6456 /*-----------------------------------------------------------------*/
6457 static void shiftR1Left2Result (operand *left, int offl,
6458                                 operand *result, int offr,
6459                                 int shCount, int sign)
6460 {
6461   int same;
6462
6463   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6464
6465   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6466
6467   /* Copy the msb into the carry if signed. */
6468   if(sign) {
6469     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6470     return;
6471   }
6472
6473
6474
6475   switch(shCount) {
6476   case 1:
6477     emitCLRC;
6478     if(same) 
6479       emitpcode(POC_RRF, popGet(AOP(result),offr));
6480     else {
6481       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6482       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483     }
6484     break;
6485   case 2:
6486     emitCLRC;
6487     if(same) {
6488       emitpcode(POC_RRF, popGet(AOP(result),offr));
6489     } else {
6490       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6491       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6492     }
6493     emitCLRC;
6494     emitpcode(POC_RRF, popGet(AOP(result),offr));
6495
6496     break;
6497   case 3:
6498     if(same)
6499       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6500     else {
6501       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6502       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6503     }
6504
6505     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6506     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6507     emitpcode(POC_ANDLW, popGetLit(0x1f));
6508     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6509     break;
6510       
6511   case 4:
6512     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6513     emitpcode(POC_ANDLW, popGetLit(0x0f));
6514     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6515     break;
6516
6517   case 5:
6518     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6519     emitpcode(POC_ANDLW, popGetLit(0x0f));
6520     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6521     emitCLRC;
6522     emitpcode(POC_RRF, popGet(AOP(result),offr));
6523
6524     break;
6525   case 6:
6526
6527     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6528     emitpcode(POC_ANDLW, popGetLit(0x80));
6529     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6530     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6531     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6532     break;
6533
6534   case 7:
6535
6536     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6537     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6538     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6539
6540     break;
6541
6542   default:
6543     break;
6544   }
6545 }
6546
6547 /*-----------------------------------------------------------------*/
6548 /* shiftL1Left2Result - shift left one byte from left to result    */
6549 /*-----------------------------------------------------------------*/
6550 static void shiftL1Left2Result (operand *left, int offl,
6551                                 operand *result, int offr, int shCount)
6552 {
6553   int same;
6554
6555   //    char *l;
6556   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6557
6558   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6559   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6560     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6561     //    MOVA(l);
6562     /* shift left accumulator */
6563     //AccLsh(shCount); // don't comment out just yet...
6564   //    aopPut(AOP(result),"a",offr);
6565
6566   switch(shCount) {
6567   case 1:
6568     /* Shift left 1 bit position */
6569     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6570     if(same) {
6571       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6572     } else {
6573       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6574       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6575     }
6576     break;
6577   case 2:
6578     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6579     emitpcode(POC_ANDLW,popGetLit(0x7e));
6580     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6581     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6582     break;
6583   case 3:
6584     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6585     emitpcode(POC_ANDLW,popGetLit(0x3e));
6586     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6587     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6588     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6589     break;
6590   case 4:
6591     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6592     emitpcode(POC_ANDLW, popGetLit(0xf0));
6593     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6594     break;
6595   case 5:
6596     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6597     emitpcode(POC_ANDLW, popGetLit(0xf0));
6598     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6599     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6600     break;
6601   case 6:
6602     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6603     emitpcode(POC_ANDLW, popGetLit(0x30));
6604     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6605     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6606     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6607     break;
6608   case 7:
6609     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6610     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6611     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6612     break;
6613
6614   default:
6615     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6616   }
6617
6618 }
6619
6620 /*-----------------------------------------------------------------*/
6621 /* movLeft2Result - move byte from left to result                  */
6622 /*-----------------------------------------------------------------*/
6623 static void movLeft2Result (operand *left, int offl,
6624                             operand *result, int offr)
6625 {
6626   char *l;
6627   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6628   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6629     l = aopGet(AOP(left),offl,FALSE,FALSE);
6630
6631     if (*l == '@' && (IS_AOP_PREG(result))) {
6632       pic14_emitcode("mov","a,%s",l);
6633       aopPut(AOP(result),"a",offr);
6634     } else {
6635       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6636       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6637     }
6638   }
6639 }
6640
6641 /*-----------------------------------------------------------------*/
6642 /* shiftL2Left2Result - shift left two bytes from left to result   */
6643 /*-----------------------------------------------------------------*/
6644 static void shiftL2Left2Result (operand *left, int offl,
6645                                 operand *result, int offr, int shCount)
6646 {
6647
6648
6649   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6650
6651   if(pic14_sameRegs(AOP(result), AOP(left))) {
6652     switch(shCount) {
6653     case 0:
6654       break;
6655     case 1:
6656     case 2:
6657     case 3:
6658
6659       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6660       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6661       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6662
6663       while(--shCount) {
6664         emitCLRC;
6665         emitpcode(POC_RLF, popGet(AOP(result),offr));
6666         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6667       }
6668
6669       break;
6670     case 4:
6671     case 5:
6672       emitpcode(POC_MOVLW, popGetLit(0x0f));
6673       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6674       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6675       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6676       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6677       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6678       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6679       if(shCount >=5) {
6680         emitpcode(POC_RLF, popGet(AOP(result),offr));
6681         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6682       }
6683       break;
6684     case 6:
6685       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6686       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6687       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6688       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6689       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6690       emitpcode(POC_ANDLW,popGetLit(0xc0));
6691       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6692       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6693       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6694       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6695       break;
6696     case 7:
6697       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6698       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6699       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6700       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6701       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6702     }
6703
6704   } else {
6705     switch(shCount) {
6706     case 0:
6707       break;
6708     case 1:
6709     case 2:
6710     case 3:
6711       /* note, use a mov/add for the shift since the mov has a
6712          chance of getting optimized out */
6713       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6714       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6715       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6716       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6717       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6718
6719       while(--shCount) {
6720         emitCLRC;
6721         emitpcode(POC_RLF, popGet(AOP(result),offr));
6722         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6723       }
6724       break;
6725
6726     case 4:
6727     case 5:
6728       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6729       emitpcode(POC_ANDLW, popGetLit(0xF0));
6730       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6731       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6732       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6733       emitpcode(POC_ANDLW, popGetLit(0xF0));
6734       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6735       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6736
6737
6738       if(shCount == 5) {
6739         emitpcode(POC_RLF, popGet(AOP(result),offr));
6740         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6741       }
6742       break;
6743     case 6:
6744       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6745       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6747       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6748
6749       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6750       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6751       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6752       emitpcode(POC_ANDLW,popGetLit(0xc0));
6753       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6754       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6755       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6756       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6757       break;
6758     case 7:
6759       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6760       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6761       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6762       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6763       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6764     }
6765   }
6766
6767 }
6768 /*-----------------------------------------------------------------*/
6769 /* shiftR2Left2Result - shift right two bytes from left to result  */
6770 /*-----------------------------------------------------------------*/
6771 static void shiftR2Left2Result (operand *left, int offl,
6772                                 operand *result, int offr,
6773                                 int shCount, int sign)
6774 {
6775   int same=0;
6776
6777   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6778   same = pic14_sameRegs(AOP(result), AOP(left));
6779
6780   if(same && ((offl + MSB16) == offr)){
6781     same=1;
6782     /* don't crash result[offr] */
6783     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6784     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6785   }
6786 /* else {
6787     movLeft2Result(left,offl, result, offr);
6788     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6789   }
6790 */
6791   /* a:x >> shCount (x = lsb(result))*/
6792 /*
6793   if(sign)
6794     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6795   else {
6796     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6797 */
6798   switch(shCount) {
6799   case 0:
6800     break;
6801   case 1:
6802   case 2:
6803   case 3:
6804     if(sign)
6805       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6806     else
6807       emitCLRC;
6808
6809     if(same) {
6810       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6811       emitpcode(POC_RRF,popGet(AOP(result),offr));
6812     } else {
6813       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6814       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6815       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6816       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6817     }
6818
6819     while(--shCount) {
6820       if(sign)
6821         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6822       else
6823         emitCLRC;
6824       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6825       emitpcode(POC_RRF,popGet(AOP(result),offr));
6826     }
6827     break;
6828   case 4:
6829   case 5:
6830     if(same) {
6831
6832       emitpcode(POC_MOVLW, popGetLit(0xf0));
6833       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6834       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6835
6836       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6837       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6838       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6839       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6840     } else {
6841       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6842       emitpcode(POC_ANDLW, popGetLit(0x0f));
6843       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6844
6845       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6846       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6847       emitpcode(POC_ANDLW, popGetLit(0xf0));
6848       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6849       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6850     }
6851
6852     if(shCount >=5) {
6853       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6854       emitpcode(POC_RRF, popGet(AOP(result),offr));
6855     }
6856
6857     if(sign) {
6858       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6859       emitpcode(POC_BTFSC, 
6860                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6861       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6862     }
6863
6864     break;
6865
6866   case 6:
6867     if(same) {
6868
6869       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6870       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6871
6872       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6873       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6874       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6875       emitpcode(POC_ANDLW,popGetLit(0x03));
6876       if(sign) {
6877         emitpcode(POC_BTFSC, 
6878                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6879         emitpcode(POC_IORLW,popGetLit(0xfc));
6880       }
6881       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6882       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6883       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6884       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6885     } else {
6886       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6887       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6888       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6889       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6890       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6891       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6892       emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6893       emitpcode(POC_ANDLW,popGetLit(0x03));
6894       if(sign) {
6895         emitpcode(POC_BTFSC, 
6896                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6897         emitpcode(POC_IORLW,popGetLit(0xfc));
6898       }
6899       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6900       //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6901
6902         
6903     }
6904
6905     break;
6906   case 7:
6907     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6908     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6909     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6910     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6911     if(sign) {
6912       emitSKPNC;
6913       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6914     } else 
6915       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6916   }
6917 }
6918
6919
6920 /*-----------------------------------------------------------------*/
6921 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftLLeftOrResult (operand *left, int offl,
6924                                 operand *result, int offr, int shCount)
6925 {
6926     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6927     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6928     /* shift left accumulator */
6929     AccLsh(shCount);
6930     /* or with result */
6931     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6932     /* back to result */
6933     aopPut(AOP(result),"a",offr);
6934 }
6935
6936 /*-----------------------------------------------------------------*/
6937 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6938 /*-----------------------------------------------------------------*/
6939 static void shiftRLeftOrResult (operand *left, int offl,
6940                                 operand *result, int offr, int shCount)
6941 {
6942     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6943     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6944     /* shift right accumulator */
6945     AccRsh(shCount);
6946     /* or with result */
6947     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6948     /* back to result */
6949     aopPut(AOP(result),"a",offr);
6950 }
6951
6952 /*-----------------------------------------------------------------*/
6953 /* genlshOne - left shift a one byte quantity by known count       */
6954 /*-----------------------------------------------------------------*/
6955 static void genlshOne (operand *result, operand *left, int shCount)
6956 {       
6957     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6958     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6959 }
6960
6961 /*-----------------------------------------------------------------*/
6962 /* genlshTwo - left shift two bytes by known amount != 0           */
6963 /*-----------------------------------------------------------------*/
6964 static void genlshTwo (operand *result,operand *left, int shCount)
6965 {
6966     int size;
6967     
6968     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6969     size = pic14_getDataSize(result);
6970
6971     /* if shCount >= 8 */
6972     if (shCount >= 8) {
6973         shCount -= 8 ;
6974
6975         if (size > 1){
6976             if (shCount)
6977                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6978             else 
6979                 movLeft2Result(left, LSB, result, MSB16);
6980         }
6981         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6982     }
6983
6984     /*  1 <= shCount <= 7 */
6985     else {  
6986         if(size == 1)
6987             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6988         else 
6989             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6990     }
6991 }
6992
6993 /*-----------------------------------------------------------------*/
6994 /* shiftLLong - shift left one long from left to result            */
6995 /* offl = LSB or MSB16                                             */
6996 /*-----------------------------------------------------------------*/
6997 static void shiftLLong (operand *left, operand *result, int offr )
6998 {
6999     char *l;
7000     int size = AOP_SIZE(result);
7001
7002     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7003     if(size >= LSB+offr){
7004         l = aopGet(AOP(left),LSB,FALSE,FALSE);
7005         MOVA(l);
7006         pic14_emitcode("add","a,acc");
7007         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7008             size >= MSB16+offr && offr != LSB )
7009             pic14_emitcode("xch","a,%s",
7010                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7011         else        
7012             aopPut(AOP(result),"a",LSB+offr);
7013     }
7014
7015     if(size >= MSB16+offr){
7016         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7017             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7018             MOVA(l);
7019         }
7020         pic14_emitcode("rlc","a");
7021         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7022             size >= MSB24+offr && offr != LSB)
7023             pic14_emitcode("xch","a,%s",
7024                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7025         else        
7026             aopPut(AOP(result),"a",MSB16+offr);
7027     }
7028
7029     if(size >= MSB24+offr){
7030         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7031             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7032             MOVA(l);
7033         }
7034         pic14_emitcode("rlc","a");
7035         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7036             size >= MSB32+offr && offr != LSB )
7037             pic14_emitcode("xch","a,%s",
7038                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7039         else        
7040             aopPut(AOP(result),"a",MSB24+offr);
7041     }
7042
7043     if(size > MSB32+offr){
7044         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7045             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7046             MOVA(l);    
7047         }
7048         pic14_emitcode("rlc","a");
7049         aopPut(AOP(result),"a",MSB32+offr);
7050     }
7051     if(offr != LSB)
7052         aopPut(AOP(result),zero,LSB);       
7053 }
7054
7055 /*-----------------------------------------------------------------*/
7056 /* genlshFour - shift four byte by a known amount != 0             */
7057 /*-----------------------------------------------------------------*/
7058 static void genlshFour (operand *result, operand *left, int shCount)
7059 {
7060     int size;
7061
7062     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7063     size = AOP_SIZE(result);
7064
7065     /* if shifting more that 3 bytes */
7066     if (shCount >= 24 ) {
7067         shCount -= 24;
7068         if (shCount)
7069             /* lowest order of left goes to the highest
7070             order of the destination */
7071             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7072         else
7073             movLeft2Result(left, LSB, result, MSB32);
7074         aopPut(AOP(result),zero,LSB);
7075         aopPut(AOP(result),zero,MSB16);
7076         aopPut(AOP(result),zero,MSB32);
7077         return;
7078     }
7079
7080     /* more than two bytes */
7081     else if ( shCount >= 16 ) {
7082         /* lower order two bytes goes to higher order two bytes */
7083         shCount -= 16;
7084         /* if some more remaining */
7085         if (shCount)
7086             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7087         else {
7088             movLeft2Result(left, MSB16, result, MSB32);
7089             movLeft2Result(left, LSB, result, MSB24);
7090         }
7091         aopPut(AOP(result),zero,MSB16);
7092         aopPut(AOP(result),zero,LSB);
7093         return;
7094     }    
7095
7096     /* if more than 1 byte */
7097     else if ( shCount >= 8 ) {
7098         /* lower order three bytes goes to higher order  three bytes */
7099         shCount -= 8;
7100         if(size == 2){
7101             if(shCount)
7102                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7103             else
7104                 movLeft2Result(left, LSB, result, MSB16);
7105         }
7106         else{   /* size = 4 */
7107             if(shCount == 0){
7108                 movLeft2Result(left, MSB24, result, MSB32);
7109                 movLeft2Result(left, MSB16, result, MSB24);
7110                 movLeft2Result(left, LSB, result, MSB16);
7111                 aopPut(AOP(result),zero,LSB);
7112             }
7113             else if(shCount == 1)
7114                 shiftLLong(left, result, MSB16);
7115             else{
7116                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7117                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7118                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7119                 aopPut(AOP(result),zero,LSB);
7120             }
7121         }
7122     }
7123
7124     /* 1 <= shCount <= 7 */
7125     else if(shCount <= 2){
7126         shiftLLong(left, result, LSB);
7127         if(shCount == 2)
7128             shiftLLong(result, result, LSB);
7129     }
7130     /* 3 <= shCount <= 7, optimize */
7131     else{
7132         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7133         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7134         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7135     }
7136 }
7137
7138 /*-----------------------------------------------------------------*/
7139 /* genLeftShiftLiteral - left shifting by known count              */
7140 /*-----------------------------------------------------------------*/
7141 static void genLeftShiftLiteral (operand *left,
7142                                  operand *right,
7143                                  operand *result,
7144                                  iCode *ic)
7145 {    
7146     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7147     int size;
7148
7149     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7150     freeAsmop(right,NULL,ic,TRUE);
7151
7152     aopOp(left,ic,FALSE);
7153     aopOp(result,ic,FALSE);
7154
7155     size = getSize(operandType(result));
7156
7157 #if VIEW_SIZE
7158     pic14_emitcode("; shift left ","result %d, left %d",size,
7159              AOP_SIZE(left));
7160 #endif
7161
7162     /* I suppose that the left size >= result size */
7163     if(shCount == 0){
7164         while(size--){
7165             movLeft2Result(left, size, result, size);
7166         }
7167     }
7168
7169     else if(shCount >= (size * 8))
7170         while(size--)
7171             aopPut(AOP(result),zero,size);
7172     else{
7173         switch (size) {
7174             case 1:
7175                 genlshOne (result,left,shCount);
7176                 break;
7177
7178             case 2:
7179             case 3:
7180                 genlshTwo (result,left,shCount);
7181                 break;
7182
7183             case 4:
7184                 genlshFour (result,left,shCount);
7185                 break;
7186         }
7187     }
7188     freeAsmop(left,NULL,ic,TRUE);
7189     freeAsmop(result,NULL,ic,TRUE);
7190 }
7191
7192 /*-----------------------------------------------------------------*
7193  * genMultiAsm - repeat assembly instruction for size of register.
7194  * if endian == 1, then the high byte (i.e base address + size of 
7195  * register) is used first else the low byte is used first;
7196  *-----------------------------------------------------------------*/
7197 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7198 {
7199
7200   int offset = 0;
7201
7202   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7203
7204   if(!reg)
7205     return;
7206
7207   if(!endian) {
7208     endian = 1;
7209   } else {
7210     endian = -1;
7211     offset = size-1;
7212   }
7213
7214   while(size--) {
7215     emitpcode(poc,    popGet(AOP(reg),offset));
7216     offset += endian;
7217   }
7218
7219 }
7220 /*-----------------------------------------------------------------*/
7221 /* genLeftShift - generates code for left shifting                 */
7222 /*-----------------------------------------------------------------*/
7223 static void genLeftShift (iCode *ic)
7224 {
7225   operand *left,*right, *result;
7226   int size, offset;
7227   char *l;
7228   symbol *tlbl , *tlbl1;
7229   pCodeOp *pctemp;
7230
7231   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7232
7233   right = IC_RIGHT(ic);
7234   left  = IC_LEFT(ic);
7235   result = IC_RESULT(ic);
7236
7237   aopOp(right,ic,FALSE);
7238
7239   /* if the shift count is known then do it 
7240      as efficiently as possible */
7241   if (AOP_TYPE(right) == AOP_LIT) {
7242     genLeftShiftLiteral (left,right,result,ic);
7243     return ;
7244   }
7245
7246   /* shift count is unknown then we have to form 
7247      a loop get the loop count in B : Note: we take
7248      only the lower order byte since shifting
7249      more that 32 bits make no sense anyway, ( the
7250      largest size of an object can be only 32 bits ) */  
7251
7252     
7253   aopOp(left,ic,FALSE);
7254   aopOp(result,ic,FALSE);
7255
7256   /* now move the left to the result if they are not the
7257      same */
7258   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7259       AOP_SIZE(result) > 1) {
7260
7261     size = AOP_SIZE(result);
7262     offset=0;
7263     while (size--) {
7264       l = aopGet(AOP(left),offset,FALSE,TRUE);
7265       if (*l == '@' && (IS_AOP_PREG(result))) {
7266
7267         pic14_emitcode("mov","a,%s",l);
7268         aopPut(AOP(result),"a",offset);
7269       } else {
7270         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7271         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7272         //aopPut(AOP(result),l,offset);
7273       }
7274       offset++;
7275     }
7276   }
7277
7278   size = AOP_SIZE(result);
7279
7280   /* if it is only one byte then */
7281   if (size == 1) {
7282     if(optimized_for_speed) {
7283       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7284       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7285       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7286       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7287       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7288       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7289       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7290       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7291       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7292       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7293       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7294       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7295     } else {
7296
7297       tlbl = newiTempLabel(NULL);
7298       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7299         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7300         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7301       }
7302
7303       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7304       emitpcode(POC_RRF,    popGet(AOP(result),0));
7305       emitpLabel(tlbl->key);
7306       emitpcode(POC_RLF,    popGet(AOP(result),0));
7307       emitpcode(POC_ADDLW,  popGetLit(1));
7308       emitSKPC;
7309       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7310     }
7311     goto release ;
7312   }
7313     
7314   if (pic14_sameRegs(AOP(left),AOP(result))) {
7315
7316     tlbl = newiTempLabel(NULL);
7317     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7318     genMultiAsm(POC_RRF, result, size,1);
7319     emitpLabel(tlbl->key);
7320     genMultiAsm(POC_RLF, result, size,0);
7321     emitpcode(POC_ADDLW,  popGetLit(1));
7322     emitSKPC;
7323     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7324     goto release;
7325   }
7326
7327   //tlbl = newiTempLabel(NULL);
7328   //offset = 0 ;   
7329   //tlbl1 = newiTempLabel(NULL);
7330
7331   //reAdjustPreg(AOP(result));    
7332     
7333   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7334   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7335   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7336   //MOVA(l);
7337   //pic14_emitcode("add","a,acc");         
7338   //aopPut(AOP(result),"a",offset++);
7339   //while (--size) {
7340   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7341   //  MOVA(l);
7342   //  pic14_emitcode("rlc","a");         
7343   //  aopPut(AOP(result),"a",offset++);
7344   //}
7345   //reAdjustPreg(AOP(result));
7346
7347   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7348   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7349
7350
7351   tlbl = newiTempLabel(NULL);
7352   tlbl1= newiTempLabel(NULL);
7353
7354   size = AOP_SIZE(result);
7355   offset = 1;
7356
7357   pctemp = popGetTempReg();  /* grab a temporary working register. */
7358
7359   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7360
7361   /* offset should be 0, 1 or 3 */
7362   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7363   emitSKPNZ;
7364   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7365
7366   emitpcode(POC_MOVWF, pctemp);
7367
7368
7369   emitpLabel(tlbl->key);
7370
7371   emitCLRC;
7372   emitpcode(POC_RLF,  popGet(AOP(result),0));
7373   while(--size)
7374     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7375
7376   emitpcode(POC_DECFSZ,  pctemp);
7377   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7378   emitpLabel(tlbl1->key);
7379
7380   popReleaseTempReg(pctemp);
7381
7382
7383  release:
7384   freeAsmop (right,NULL,ic,TRUE);
7385   freeAsmop(left,NULL,ic,TRUE);
7386   freeAsmop(result,NULL,ic,TRUE);
7387 }
7388
7389 /*-----------------------------------------------------------------*/
7390 /* genrshOne - right shift a one byte quantity by known count      */
7391 /*-----------------------------------------------------------------*/
7392 static void genrshOne (operand *result, operand *left,
7393                        int shCount, int sign)
7394 {
7395     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7396     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7397 }
7398
7399 /*-----------------------------------------------------------------*/
7400 /* genrshTwo - right shift two bytes by known amount != 0          */
7401 /*-----------------------------------------------------------------*/
7402 static void genrshTwo (operand *result,operand *left,
7403                        int shCount, int sign)
7404 {
7405   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7406   /* if shCount >= 8 */
7407   if (shCount >= 8) {
7408     shCount -= 8 ;
7409     if (shCount)
7410       shiftR1Left2Result(left, MSB16, result, LSB,
7411                          shCount, sign);
7412     else
7413       movLeft2Result(left, MSB16, result, LSB);
7414
7415     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7416
7417     if(sign) {
7418       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7419       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7420     }
7421   }
7422
7423   /*  1 <= shCount <= 7 */
7424   else
7425     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7426 }
7427
7428 /*-----------------------------------------------------------------*/
7429 /* shiftRLong - shift right one long from left to result           */
7430 /* offl = LSB or MSB16                                             */
7431 /*-----------------------------------------------------------------*/
7432 static void shiftRLong (operand *left, int offl,
7433                         operand *result, int sign)
7434 {
7435     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7436     if(!sign)
7437         pic14_emitcode("clr","c");
7438     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7439     if(sign)
7440         pic14_emitcode("mov","c,acc.7");
7441     pic14_emitcode("rrc","a");
7442     aopPut(AOP(result),"a",MSB32-offl);
7443     if(offl == MSB16)
7444         /* add sign of "a" */
7445         addSign(result, MSB32, sign);
7446
7447     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7448     pic14_emitcode("rrc","a");
7449     aopPut(AOP(result),"a",MSB24-offl);
7450
7451     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7452     pic14_emitcode("rrc","a");
7453     aopPut(AOP(result),"a",MSB16-offl);
7454
7455     if(offl == LSB){
7456         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7457         pic14_emitcode("rrc","a");
7458         aopPut(AOP(result),"a",LSB);
7459     }
7460 }
7461
7462 /*-----------------------------------------------------------------*/
7463 /* genrshFour - shift four byte by a known amount != 0             */
7464 /*-----------------------------------------------------------------*/
7465 static void genrshFour (operand *result, operand *left,
7466                         int shCount, int sign)
7467 {
7468   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7469   /* if shifting more that 3 bytes */
7470   if(shCount >= 24 ) {
7471     shCount -= 24;
7472     if(shCount)
7473       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7474     else
7475       movLeft2Result(left, MSB32, result, LSB);
7476
7477     addSign(result, MSB16, sign);
7478   }
7479   else if(shCount >= 16){
7480     shCount -= 16;
7481     if(shCount)
7482       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7483     else{
7484       movLeft2Result(left, MSB24, result, LSB);
7485       movLeft2Result(left, MSB32, result, MSB16);
7486     }
7487     addSign(result, MSB24, sign);
7488   }
7489   else if(shCount >= 8){
7490     shCount -= 8;
7491     if(shCount == 1)
7492       shiftRLong(left, MSB16, result, sign);
7493     else if(shCount == 0){
7494       movLeft2Result(left, MSB16, result, LSB);
7495       movLeft2Result(left, MSB24, result, MSB16);
7496       movLeft2Result(left, MSB32, result, MSB24);
7497       addSign(result, MSB32, sign);
7498     }
7499     else{
7500       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7501       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7502       /* the last shift is signed */
7503       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7504       addSign(result, MSB32, sign);
7505     }
7506   }
7507   else{   /* 1 <= shCount <= 7 */
7508     if(shCount <= 2){
7509       shiftRLong(left, LSB, result, sign);
7510       if(shCount == 2)
7511         shiftRLong(result, LSB, result, sign);
7512     }
7513     else{
7514       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7515       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7516       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7517     }
7518   }
7519 }
7520
7521 /*-----------------------------------------------------------------*/
7522 /* genRightShiftLiteral - right shifting by known count            */
7523 /*-----------------------------------------------------------------*/
7524 static void genRightShiftLiteral (operand *left,
7525                                   operand *right,
7526                                   operand *result,
7527                                   iCode *ic,
7528                                   int sign)
7529 {    
7530   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7531   int lsize,res_size;
7532
7533   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7534   freeAsmop(right,NULL,ic,TRUE);
7535
7536   aopOp(left,ic,FALSE);
7537   aopOp(result,ic,FALSE);
7538
7539 #if VIEW_SIZE
7540   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7541                  AOP_SIZE(left));
7542 #endif
7543
7544   lsize = pic14_getDataSize(left);
7545   res_size = pic14_getDataSize(result);
7546   /* test the LEFT size !!! */
7547
7548   /* I suppose that the left size >= result size */
7549   if(shCount == 0){
7550     while(res_size--)
7551       movLeft2Result(left, lsize, result, res_size);
7552   }
7553
7554   else if(shCount >= (lsize * 8)){
7555
7556     if(res_size == 1) {
7557       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7558       if(sign) {
7559         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7560         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7561       }
7562     } else {
7563
7564       if(sign) {
7565         emitpcode(POC_MOVLW, popGetLit(0));
7566         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7567         emitpcode(POC_MOVLW, popGetLit(0xff));
7568         while(res_size--)
7569           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7570
7571       } else {
7572
7573         while(res_size--)
7574           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7575       }
7576     }
7577   } else {
7578
7579     switch (res_size) {
7580     case 1:
7581       genrshOne (result,left,shCount,sign);
7582       break;
7583
7584     case 2:
7585       genrshTwo (result,left,shCount,sign);
7586       break;
7587
7588     case 4:
7589       genrshFour (result,left,shCount,sign);
7590       break;
7591     default :
7592       break;
7593     }
7594
7595   }
7596
7597   freeAsmop(left,NULL,ic,TRUE);
7598   freeAsmop(result,NULL,ic,TRUE);
7599 }
7600
7601 /*-----------------------------------------------------------------*/
7602 /* genSignedRightShift - right shift of signed number              */
7603 /*-----------------------------------------------------------------*/
7604 static void genSignedRightShift (iCode *ic)
7605 {
7606   operand *right, *left, *result;
7607   int size, offset;
7608   //  char *l;
7609   symbol *tlbl, *tlbl1 ;
7610   pCodeOp *pctemp;
7611
7612   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7613
7614   /* we do it the hard way put the shift count in b
7615      and loop thru preserving the sign */
7616   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7617
7618   right = IC_RIGHT(ic);
7619   left  = IC_LEFT(ic);
7620   result = IC_RESULT(ic);
7621
7622   aopOp(right,ic,FALSE);  
7623   aopOp(left,ic,FALSE);
7624   aopOp(result,ic,FALSE);
7625
7626
7627   if ( AOP_TYPE(right) == AOP_LIT) {
7628     genRightShiftLiteral (left,right,result,ic,1);
7629     return ;
7630   }
7631   /* shift count is unknown then we have to form 
7632      a loop get the loop count in B : Note: we take
7633      only the lower order byte since shifting
7634      more that 32 bits make no sense anyway, ( the
7635      largest size of an object can be only 32 bits ) */  
7636
7637   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7638   //pic14_emitcode("inc","b");
7639   //freeAsmop (right,NULL,ic,TRUE);
7640   //aopOp(left,ic,FALSE);
7641   //aopOp(result,ic,FALSE);
7642
7643   /* now move the left to the result if they are not the
7644      same */
7645   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7646       AOP_SIZE(result) > 1) {
7647
7648     size = AOP_SIZE(result);
7649     offset=0;
7650     while (size--) { 
7651       /*
7652         l = aopGet(AOP(left),offset,FALSE,TRUE);
7653         if (*l == '@' && IS_AOP_PREG(result)) {
7654
7655         pic14_emitcode("mov","a,%s",l);
7656         aopPut(AOP(result),"a",offset);
7657         } else
7658         aopPut(AOP(result),l,offset);
7659       */
7660       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7661       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7662
7663       offset++;
7664     }
7665   }
7666
7667   /* mov the highest order bit to OVR */    
7668   tlbl = newiTempLabel(NULL);
7669   tlbl1= newiTempLabel(NULL);
7670
7671   size = AOP_SIZE(result);
7672   offset = size - 1;
7673
7674   pctemp = popGetTempReg();  /* grab a temporary working register. */
7675
7676   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7677
7678   /* offset should be 0, 1 or 3 */
7679   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7680   emitSKPNZ;
7681   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7682
7683   emitpcode(POC_MOVWF, pctemp);
7684
7685
7686   emitpLabel(tlbl->key);
7687
7688   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7689   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7690
7691   while(--size) {
7692     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7693   }
7694
7695   emitpcode(POC_DECFSZ,  pctemp);
7696   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7697   emitpLabel(tlbl1->key);
7698
7699   popReleaseTempReg(pctemp);
7700 #if 0
7701   size = AOP_SIZE(result);
7702   offset = size - 1;
7703   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7704   pic14_emitcode("rlc","a");
7705   pic14_emitcode("mov","ov,c");
7706   /* if it is only one byte then */
7707   if (size == 1) {
7708     l = aopGet(AOP(left),0,FALSE,FALSE);
7709     MOVA(l);
7710     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7711     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7712     pic14_emitcode("mov","c,ov");
7713     pic14_emitcode("rrc","a");
7714     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7715     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7716     aopPut(AOP(result),"a",0);
7717     goto release ;
7718   }
7719
7720   reAdjustPreg(AOP(result));
7721   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7722   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7723   pic14_emitcode("mov","c,ov");
7724   while (size--) {
7725     l = aopGet(AOP(result),offset,FALSE,FALSE);
7726     MOVA(l);
7727     pic14_emitcode("rrc","a");         
7728     aopPut(AOP(result),"a",offset--);
7729   }
7730   reAdjustPreg(AOP(result));
7731   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7732   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7733
7734  release:
7735 #endif
7736
7737   freeAsmop(left,NULL,ic,TRUE);
7738   freeAsmop(result,NULL,ic,TRUE);
7739   freeAsmop(right,NULL,ic,TRUE);
7740 }
7741
7742 /*-----------------------------------------------------------------*/
7743 /* genRightShift - generate code for right shifting                */
7744 /*-----------------------------------------------------------------*/
7745 static void genRightShift (iCode *ic)
7746 {
7747     operand *right, *left, *result;
7748     sym_link *retype ;
7749     int size, offset;
7750     char *l;
7751     symbol *tlbl, *tlbl1 ;
7752
7753     /* if signed then we do it the hard way preserve the
7754     sign bit moving it inwards */
7755     retype = getSpec(operandType(IC_RESULT(ic)));
7756     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7757
7758     if (!SPEC_USIGN(retype)) {
7759         genSignedRightShift (ic);
7760         return ;
7761     }
7762
7763     /* signed & unsigned types are treated the same : i.e. the
7764     signed is NOT propagated inwards : quoting from the
7765     ANSI - standard : "for E1 >> E2, is equivalent to division
7766     by 2**E2 if unsigned or if it has a non-negative value,
7767     otherwise the result is implementation defined ", MY definition
7768     is that the sign does not get propagated */
7769
7770     right = IC_RIGHT(ic);
7771     left  = IC_LEFT(ic);
7772     result = IC_RESULT(ic);
7773
7774     aopOp(right,ic,FALSE);
7775
7776     /* if the shift count is known then do it 
7777     as efficiently as possible */
7778     if (AOP_TYPE(right) == AOP_LIT) {
7779         genRightShiftLiteral (left,right,result,ic, 0);
7780         return ;
7781     }
7782
7783     /* shift count is unknown then we have to form 
7784     a loop get the loop count in B : Note: we take
7785     only the lower order byte since shifting
7786     more that 32 bits make no sense anyway, ( the
7787     largest size of an object can be only 32 bits ) */  
7788
7789     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7790     pic14_emitcode("inc","b");
7791     aopOp(left,ic,FALSE);
7792     aopOp(result,ic,FALSE);
7793
7794     /* now move the left to the result if they are not the
7795     same */
7796     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7797         AOP_SIZE(result) > 1) {
7798
7799         size = AOP_SIZE(result);
7800         offset=0;
7801         while (size--) {
7802             l = aopGet(AOP(left),offset,FALSE,TRUE);
7803             if (*l == '@' && IS_AOP_PREG(result)) {
7804
7805                 pic14_emitcode("mov","a,%s",l);
7806                 aopPut(AOP(result),"a",offset);
7807             } else
7808                 aopPut(AOP(result),l,offset);
7809             offset++;
7810         }
7811     }
7812
7813     tlbl = newiTempLabel(NULL);
7814     tlbl1= newiTempLabel(NULL);
7815     size = AOP_SIZE(result);
7816     offset = size - 1;
7817
7818     /* if it is only one byte then */
7819     if (size == 1) {
7820
7821       tlbl = newiTempLabel(NULL);
7822       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7823         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7824         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7825       }
7826
7827       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7828       emitpcode(POC_RLF,    popGet(AOP(result),0));
7829       emitpLabel(tlbl->key);
7830       emitpcode(POC_RRF,    popGet(AOP(result),0));
7831       emitpcode(POC_ADDLW,  popGetLit(1));
7832       emitSKPC;
7833       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7834
7835       goto release ;
7836     }
7837
7838     reAdjustPreg(AOP(result));
7839     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7840     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7841     CLRC;
7842     while (size--) {
7843         l = aopGet(AOP(result),offset,FALSE,FALSE);
7844         MOVA(l);
7845         pic14_emitcode("rrc","a");         
7846         aopPut(AOP(result),"a",offset--);
7847     }
7848     reAdjustPreg(AOP(result));
7849
7850     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7851     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7852
7853 release:
7854     freeAsmop(left,NULL,ic,TRUE);
7855     freeAsmop (right,NULL,ic,TRUE);
7856     freeAsmop(result,NULL,ic,TRUE);
7857 }
7858
7859 /*-----------------------------------------------------------------*/
7860 /* genUnpackBits - generates code for unpacking bits               */
7861 /*-----------------------------------------------------------------*/
7862 static void genUnpackBits (operand *result, char *rname, int ptype)
7863 {    
7864     int shCnt ;
7865     int rlen = 0 ;
7866     sym_link *etype;
7867     int offset = 0 ;
7868
7869     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7870     etype = getSpec(operandType(result));
7871
7872     /* read the first byte  */
7873     switch (ptype) {
7874
7875     case POINTER:
7876     case IPOINTER:
7877         pic14_emitcode("mov","a,@%s",rname);
7878         break;
7879         
7880     case PPOINTER:
7881         pic14_emitcode("movx","a,@%s",rname);
7882         break;
7883         
7884     case FPOINTER:
7885         pic14_emitcode("movx","a,@dptr");
7886         break;
7887
7888     case CPOINTER:
7889         pic14_emitcode("clr","a");
7890         pic14_emitcode("movc","a","@a+dptr");
7891         break;
7892
7893     case GPOINTER:
7894         pic14_emitcode("lcall","__gptrget");
7895         break;
7896     }
7897
7898     /* if we have bitdisplacement then it fits   */
7899     /* into this byte completely or if length is */
7900     /* less than a byte                          */
7901     if ((shCnt = SPEC_BSTR(etype)) || 
7902         (SPEC_BLEN(etype) <= 8))  {
7903
7904         /* shift right acc */
7905         AccRsh(shCnt);
7906
7907         pic14_emitcode("anl","a,#0x%02x",
7908                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7909         aopPut(AOP(result),"a",offset);
7910         return ;
7911     }
7912
7913     /* bit field did not fit in a byte  */
7914     rlen = SPEC_BLEN(etype) - 8;
7915     aopPut(AOP(result),"a",offset++);
7916
7917     while (1)  {
7918
7919         switch (ptype) {
7920         case POINTER:
7921         case IPOINTER:
7922             pic14_emitcode("inc","%s",rname);
7923             pic14_emitcode("mov","a,@%s",rname);
7924             break;
7925             
7926         case PPOINTER:
7927             pic14_emitcode("inc","%s",rname);
7928             pic14_emitcode("movx","a,@%s",rname);
7929             break;
7930
7931         case FPOINTER:
7932             pic14_emitcode("inc","dptr");
7933             pic14_emitcode("movx","a,@dptr");
7934             break;
7935             
7936         case CPOINTER:
7937             pic14_emitcode("clr","a");
7938             pic14_emitcode("inc","dptr");
7939             pic14_emitcode("movc","a","@a+dptr");
7940             break;
7941             
7942         case GPOINTER:
7943             pic14_emitcode("inc","dptr");
7944             pic14_emitcode("lcall","__gptrget");
7945             break;
7946         }
7947
7948         rlen -= 8;            
7949         /* if we are done */
7950         if ( rlen <= 0 )
7951             break ;
7952         
7953         aopPut(AOP(result),"a",offset++);
7954                               
7955     }
7956     
7957     if (rlen) {
7958         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7959         aopPut(AOP(result),"a",offset);        
7960     }
7961     
7962     return ;
7963 }
7964
7965 #if 0
7966 /*-----------------------------------------------------------------*/
7967 /* genDataPointerGet - generates code when ptr offset is known     */
7968 /*-----------------------------------------------------------------*/
7969 static void genDataPointerGet (operand *left, 
7970                                operand *result, 
7971                                iCode *ic)
7972 {
7973   int size , offset = 0;
7974
7975
7976   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7977
7978
7979   /* optimization - most of the time, left and result are the same
7980    * address, but different types. for the pic code, we could omit
7981    * the following
7982    */
7983
7984   aopOp(result,ic,TRUE);
7985
7986   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7987
7988   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7989
7990   size = AOP_SIZE(result);
7991
7992   while (size--) {
7993     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7994     offset++;
7995   }
7996
7997   freeAsmop(left,NULL,ic,TRUE);
7998   freeAsmop(result,NULL,ic,TRUE);
7999 }
8000 #endif
8001 /*-----------------------------------------------------------------*/
8002 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
8003 /*-----------------------------------------------------------------*/
8004 static void genNearPointerGet (operand *left, 
8005                                operand *result, 
8006                                iCode *ic)
8007 {
8008     asmop *aop = NULL;
8009     //regs *preg = NULL ;
8010     char *rname ;
8011     sym_link *rtype, *retype;
8012     sym_link *ltype = operandType(left);    
8013     //char buffer[80];
8014
8015     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8016
8017     rtype = operandType(result);
8018     retype= getSpec(rtype);
8019     
8020     aopOp(left,ic,FALSE);
8021     
8022     /* if left is rematerialisable and
8023        result is not bit variable type and
8024        the left is pointer to data space i.e
8025        lower 128 bytes of space */
8026     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8027         !IS_BITVAR(retype)         &&
8028         DCL_TYPE(ltype) == POINTER) {
8029       //genDataPointerGet (left,result,ic);
8030         return ;
8031     }
8032     
8033     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8034
8035         /* if the value is already in a pointer register
8036        then don't need anything more */
8037     if (!AOP_INPREG(AOP(left))) {
8038         /* otherwise get a free pointer register */
8039     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8040 /*
8041         aop = newAsmop(0);
8042         preg = getFreePtr(ic,&aop,FALSE);
8043         pic14_emitcode("mov","%s,%s",
8044                 preg->name,
8045                 aopGet(AOP(left),0,FALSE,TRUE));
8046         rname = preg->name ;
8047 */
8048     rname ="BAD";
8049     } else
8050         rname = aopGet(AOP(left),0,FALSE,FALSE);
8051     
8052     aopOp (result,ic,FALSE);
8053     
8054       /* if bitfield then unpack the bits */
8055     if (IS_BITVAR(retype)) 
8056         genUnpackBits (result,rname,POINTER);
8057     else {
8058         /* we have can just get the values */
8059       int size = AOP_SIZE(result);
8060       int offset = 0 ;  
8061         
8062       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8063
8064       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8065       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8066       while(size--) {
8067         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8068         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8069         if(size)
8070           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8071       }
8072 /*
8073         while (size--) {
8074             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8075
8076                 pic14_emitcode("mov","a,@%s",rname);
8077                 aopPut(AOP(result),"a",offset);
8078             } else {
8079                 sprintf(buffer,"@%s",rname);
8080                 aopPut(AOP(result),buffer,offset);
8081             }
8082             offset++ ;
8083             if (size)
8084                 pic14_emitcode("inc","%s",rname);
8085         }
8086 */
8087     }
8088
8089     /* now some housekeeping stuff */
8090     if (aop) {
8091         /* we had to allocate for this iCode */
8092     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8093         freeAsmop(NULL,aop,ic,TRUE);
8094     } else { 
8095         /* we did not allocate which means left
8096            already in a pointer register, then
8097            if size > 0 && this could be used again
8098            we have to point it back to where it 
8099            belongs */
8100     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8101         if (AOP_SIZE(result) > 1 &&
8102             !OP_SYMBOL(left)->remat &&
8103             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8104               ic->depth )) {
8105             int size = AOP_SIZE(result) - 1;
8106             while (size--)
8107                 pic14_emitcode("dec","%s",rname);
8108         }
8109     }
8110
8111     /* done */
8112     freeAsmop(left,NULL,ic,TRUE);
8113     freeAsmop(result,NULL,ic,TRUE);
8114      
8115 }
8116
8117 /*-----------------------------------------------------------------*/
8118 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8119 /*-----------------------------------------------------------------*/
8120 static void genPagedPointerGet (operand *left, 
8121                                operand *result, 
8122                                iCode *ic)
8123 {
8124     asmop *aop = NULL;
8125     regs *preg = NULL ;
8126     char *rname ;
8127     sym_link *rtype, *retype;    
8128
8129     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8130
8131     rtype = operandType(result);
8132     retype= getSpec(rtype);
8133     
8134     aopOp(left,ic,FALSE);
8135
8136   /* if the value is already in a pointer register
8137        then don't need anything more */
8138     if (!AOP_INPREG(AOP(left))) {
8139         /* otherwise get a free pointer register */
8140         aop = newAsmop(0);
8141         preg = getFreePtr(ic,&aop,FALSE);
8142         pic14_emitcode("mov","%s,%s",
8143                 preg->name,
8144                 aopGet(AOP(left),0,FALSE,TRUE));
8145         rname = preg->name ;
8146     } else
8147         rname = aopGet(AOP(left),0,FALSE,FALSE);
8148     
8149     freeAsmop(left,NULL,ic,TRUE);
8150     aopOp (result,ic,FALSE);
8151
8152     /* if bitfield then unpack the bits */
8153     if (IS_BITVAR(retype)) 
8154         genUnpackBits (result,rname,PPOINTER);
8155     else {
8156         /* we have can just get the values */
8157         int size = AOP_SIZE(result);
8158         int offset = 0 ;        
8159         
8160         while (size--) {
8161             
8162             pic14_emitcode("movx","a,@%s",rname);
8163             aopPut(AOP(result),"a",offset);
8164             
8165             offset++ ;
8166             
8167             if (size)
8168                 pic14_emitcode("inc","%s",rname);
8169         }
8170     }
8171
8172     /* now some housekeeping stuff */
8173     if (aop) {
8174         /* we had to allocate for this iCode */
8175         freeAsmop(NULL,aop,ic,TRUE);
8176     } else { 
8177         /* we did not allocate which means left
8178            already in a pointer register, then
8179            if size > 0 && this could be used again
8180            we have to point it back to where it 
8181            belongs */
8182         if (AOP_SIZE(result) > 1 &&
8183             !OP_SYMBOL(left)->remat &&
8184             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8185               ic->depth )) {
8186             int size = AOP_SIZE(result) - 1;
8187             while (size--)
8188                 pic14_emitcode("dec","%s",rname);
8189         }
8190     }
8191
8192     /* done */
8193     freeAsmop(result,NULL,ic,TRUE);
8194     
8195         
8196 }
8197
8198 /*-----------------------------------------------------------------*/
8199 /* genFarPointerGet - gget value from far space                    */
8200 /*-----------------------------------------------------------------*/
8201 static void genFarPointerGet (operand *left,
8202                               operand *result, iCode *ic)
8203 {
8204     int size, offset ;
8205     sym_link *retype = getSpec(operandType(result));
8206
8207     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8208
8209     aopOp(left,ic,FALSE);
8210
8211     /* if the operand is already in dptr 
8212     then we do nothing else we move the value to dptr */
8213     if (AOP_TYPE(left) != AOP_STR) {
8214         /* if this is remateriazable */
8215         if (AOP_TYPE(left) == AOP_IMMD)
8216             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8217         else { /* we need to get it byte by byte */
8218             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8219             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8220             if (options.model == MODEL_FLAT24)
8221             {
8222                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8223             }
8224         }
8225     }
8226     /* so dptr know contains the address */
8227     freeAsmop(left,NULL,ic,TRUE);
8228     aopOp(result,ic,FALSE);
8229
8230     /* if bit then unpack */
8231     if (IS_BITVAR(retype)) 
8232         genUnpackBits(result,"dptr",FPOINTER);
8233     else {
8234         size = AOP_SIZE(result);
8235         offset = 0 ;
8236
8237         while (size--) {
8238             pic14_emitcode("movx","a,@dptr");
8239             aopPut(AOP(result),"a",offset++);
8240             if (size)
8241                 pic14_emitcode("inc","dptr");
8242         }
8243     }
8244
8245     freeAsmop(result,NULL,ic,TRUE);
8246 }
8247 #if 0
8248 /*-----------------------------------------------------------------*/
8249 /* genCodePointerGet - get value from code space                  */
8250 /*-----------------------------------------------------------------*/
8251 static void genCodePointerGet (operand *left,
8252                                 operand *result, iCode *ic)
8253 {
8254     int size, offset ;
8255     sym_link *retype = getSpec(operandType(result));
8256
8257     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8258
8259     aopOp(left,ic,FALSE);
8260
8261     /* if the operand is already in dptr 
8262     then we do nothing else we move the value to dptr */
8263     if (AOP_TYPE(left) != AOP_STR) {
8264         /* if this is remateriazable */
8265         if (AOP_TYPE(left) == AOP_IMMD)
8266             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8267         else { /* we need to get it byte by byte */
8268             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8269             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8270             if (options.model == MODEL_FLAT24)
8271             {
8272                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8273             }
8274         }
8275     }
8276     /* so dptr know contains the address */
8277     freeAsmop(left,NULL,ic,TRUE);
8278     aopOp(result,ic,FALSE);
8279
8280     /* if bit then unpack */
8281     if (IS_BITVAR(retype)) 
8282         genUnpackBits(result,"dptr",CPOINTER);
8283     else {
8284         size = AOP_SIZE(result);
8285         offset = 0 ;
8286
8287         while (size--) {
8288             pic14_emitcode("clr","a");
8289             pic14_emitcode("movc","a,@a+dptr");
8290             aopPut(AOP(result),"a",offset++);
8291             if (size)
8292                 pic14_emitcode("inc","dptr");
8293         }
8294     }
8295
8296     freeAsmop(result,NULL,ic,TRUE);
8297 }
8298 #endif
8299 /*-----------------------------------------------------------------*/
8300 /* genGenPointerGet - gget value from generic pointer space        */
8301 /*-----------------------------------------------------------------*/
8302 static void genGenPointerGet (operand *left,
8303                               operand *result, iCode *ic)
8304 {
8305   int size, offset ;
8306   sym_link *retype = getSpec(operandType(result));
8307
8308   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8309   aopOp(left,ic,FALSE);
8310   aopOp(result,ic,FALSE);
8311
8312
8313   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8314
8315   /* if the operand is already in dptr 
8316      then we do nothing else we move the value to dptr */
8317   //  if (AOP_TYPE(left) != AOP_STR) {
8318     /* if this is remateriazable */
8319     if (AOP_TYPE(left) == AOP_IMMD) {
8320       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8321       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8322     }
8323     else { /* we need to get it byte by byte */
8324
8325       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8326       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8327
8328       size = AOP_SIZE(result);
8329       offset = 0 ;
8330
8331       while(size--) {
8332         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8333         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8334         if(size)
8335           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8336       }
8337       goto release;
8338     }
8339     //}
8340   /* so dptr know contains the address */
8341
8342   /* if bit then unpack */
8343   //if (IS_BITVAR(retype)) 
8344   //  genUnpackBits(result,"dptr",GPOINTER);
8345
8346  release:
8347   freeAsmop(left,NULL,ic,TRUE);
8348   freeAsmop(result,NULL,ic,TRUE);
8349
8350 }
8351
8352 /*-----------------------------------------------------------------*/
8353 /* genConstPointerGet - get value from const generic pointer space */
8354 /*-----------------------------------------------------------------*/
8355 static void genConstPointerGet (operand *left,
8356                                 operand *result, iCode *ic)
8357 {
8358   //sym_link *retype = getSpec(operandType(result));
8359   symbol *albl = newiTempLabel(NULL);
8360   symbol *blbl = newiTempLabel(NULL);
8361   PIC_OPCODE poc;
8362
8363   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8364   aopOp(left,ic,FALSE);
8365   aopOp(result,ic,FALSE);
8366
8367
8368   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8369
8370   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8371
8372   emitpcode(POC_CALL,popGetLabel(albl->key));
8373   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8374   emitpLabel(albl->key);
8375
8376   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8377     
8378   emitpcode(poc,popGet(AOP(left),1));
8379   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8380   emitpcode(poc,popGet(AOP(left),0));
8381   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8382
8383   emitpLabel(blbl->key);
8384
8385   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8386
8387
8388   freeAsmop(left,NULL,ic,TRUE);
8389   freeAsmop(result,NULL,ic,TRUE);
8390
8391 }
8392 /*-----------------------------------------------------------------*/
8393 /* genPointerGet - generate code for pointer get                   */
8394 /*-----------------------------------------------------------------*/
8395 static void genPointerGet (iCode *ic)
8396 {
8397     operand *left, *result ;
8398     sym_link *type, *etype;
8399     int p_type;
8400
8401     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8402
8403     left = IC_LEFT(ic);
8404     result = IC_RESULT(ic) ;
8405
8406     /* depending on the type of pointer we need to
8407     move it to the correct pointer register */
8408     type = operandType(left);
8409     etype = getSpec(type);
8410
8411     if (IS_PTR_CONST(type))
8412       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8413
8414     /* if left is of type of pointer then it is simple */
8415     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8416         p_type = DCL_TYPE(type);
8417     else {
8418         /* we have to go by the storage class */
8419         p_type = PTR_TYPE(SPEC_OCLS(etype));
8420
8421         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8422
8423         if (SPEC_OCLS(etype)->codesp ) {
8424           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8425           //p_type = CPOINTER ; 
8426         }
8427         else
8428             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8429               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8430                /*p_type = FPOINTER ;*/ 
8431             else
8432                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8433                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8434 /*                  p_type = PPOINTER; */
8435                 else
8436                     if (SPEC_OCLS(etype) == idata )
8437                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8438 /*                      p_type = IPOINTER; */
8439                     else
8440                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8441 /*                      p_type = POINTER ; */
8442     }
8443
8444     /* now that we have the pointer type we assign
8445     the pointer values */
8446     switch (p_type) {
8447
8448     case POINTER:       
8449     case IPOINTER:
8450         genNearPointerGet (left,result,ic);
8451         break;
8452
8453     case PPOINTER:
8454         genPagedPointerGet(left,result,ic);
8455         break;
8456
8457     case FPOINTER:
8458         genFarPointerGet (left,result,ic);
8459         break;
8460
8461     case CPOINTER:
8462         genConstPointerGet (left,result,ic);
8463         //pic14_emitcodePointerGet (left,result,ic);
8464         break;
8465
8466     case GPOINTER:
8467       if (IS_PTR_CONST(type))
8468         genConstPointerGet (left,result,ic);
8469       else
8470         genGenPointerGet (left,result,ic);
8471       break;
8472     }
8473
8474 }
8475
8476 /*-----------------------------------------------------------------*/
8477 /* genPackBits - generates code for packed bit storage             */
8478 /*-----------------------------------------------------------------*/
8479 static void genPackBits (sym_link    *etype ,
8480                          operand *right ,
8481                          char *rname, int p_type)
8482 {
8483     int shCount = 0 ;
8484     int offset = 0  ;
8485     int rLen = 0 ;
8486     int blen, bstr ;   
8487     char *l ;
8488
8489     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8490     blen = SPEC_BLEN(etype);
8491     bstr = SPEC_BSTR(etype);
8492
8493     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8494     MOVA(l);   
8495
8496     /* if the bit lenth is less than or    */
8497     /* it exactly fits a byte then         */
8498     if (SPEC_BLEN(etype) <= 8 )  {
8499         shCount = SPEC_BSTR(etype) ;
8500
8501         /* shift left acc */
8502         AccLsh(shCount);
8503
8504         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8505
8506
8507             switch (p_type) {
8508                 case POINTER:
8509                     pic14_emitcode ("mov","b,a");
8510                     pic14_emitcode("mov","a,@%s",rname);
8511                     break;
8512
8513                 case FPOINTER:
8514                     pic14_emitcode ("mov","b,a");
8515                     pic14_emitcode("movx","a,@dptr");
8516                     break;
8517
8518                 case GPOINTER:
8519                     pic14_emitcode ("push","b");
8520                     pic14_emitcode ("push","acc");
8521                     pic14_emitcode ("lcall","__gptrget");
8522                     pic14_emitcode ("pop","b");
8523                     break;
8524             }
8525
8526             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8527                       ((unsigned char)(0xFF << (blen+bstr)) | 
8528                        (unsigned char)(0xFF >> (8-bstr)) ) );
8529             pic14_emitcode ("orl","a,b");
8530             if (p_type == GPOINTER)
8531                 pic14_emitcode("pop","b");
8532         }
8533     }
8534
8535     switch (p_type) {
8536         case POINTER:
8537             pic14_emitcode("mov","@%s,a",rname);
8538             break;
8539
8540         case FPOINTER:
8541             pic14_emitcode("movx","@dptr,a");
8542             break;
8543
8544         case GPOINTER:
8545             DEBUGpic14_emitcode(";lcall","__gptrput");
8546             break;
8547     }
8548
8549     /* if we r done */
8550     if ( SPEC_BLEN(etype) <= 8 )
8551         return ;
8552
8553     pic14_emitcode("inc","%s",rname);
8554     rLen = SPEC_BLEN(etype) ;     
8555
8556     /* now generate for lengths greater than one byte */
8557     while (1) {
8558
8559         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8560
8561         rLen -= 8 ;
8562         if (rLen <= 0 )
8563             break ;
8564
8565         switch (p_type) {
8566             case POINTER:
8567                 if (*l == '@') {
8568                     MOVA(l);
8569                     pic14_emitcode("mov","@%s,a",rname);
8570                 } else
8571                     pic14_emitcode("mov","@%s,%s",rname,l);
8572                 break;
8573
8574             case FPOINTER:
8575                 MOVA(l);
8576                 pic14_emitcode("movx","@dptr,a");
8577                 break;
8578
8579             case GPOINTER:
8580                 MOVA(l);
8581                 DEBUGpic14_emitcode(";lcall","__gptrput");
8582                 break;  
8583         }   
8584         pic14_emitcode ("inc","%s",rname);
8585     }
8586
8587     MOVA(l);
8588
8589     /* last last was not complete */
8590     if (rLen)   {
8591         /* save the byte & read byte */
8592         switch (p_type) {
8593             case POINTER:
8594                 pic14_emitcode ("mov","b,a");
8595                 pic14_emitcode("mov","a,@%s",rname);
8596                 break;
8597
8598             case FPOINTER:
8599                 pic14_emitcode ("mov","b,a");
8600                 pic14_emitcode("movx","a,@dptr");
8601                 break;
8602
8603             case GPOINTER:
8604                 pic14_emitcode ("push","b");
8605                 pic14_emitcode ("push","acc");
8606                 pic14_emitcode ("lcall","__gptrget");
8607                 pic14_emitcode ("pop","b");
8608                 break;
8609         }
8610
8611         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8612         pic14_emitcode ("orl","a,b");
8613     }
8614
8615     if (p_type == GPOINTER)
8616         pic14_emitcode("pop","b");
8617
8618     switch (p_type) {
8619
8620     case POINTER:
8621         pic14_emitcode("mov","@%s,a",rname);
8622         break;
8623         
8624     case FPOINTER:
8625         pic14_emitcode("movx","@dptr,a");
8626         break;
8627         
8628     case GPOINTER:
8629         DEBUGpic14_emitcode(";lcall","__gptrput");
8630         break;                  
8631     }
8632 }
8633 /*-----------------------------------------------------------------*/
8634 /* genDataPointerSet - remat pointer to data space                 */
8635 /*-----------------------------------------------------------------*/
8636 static void genDataPointerSet(operand *right,
8637                               operand *result,
8638                               iCode *ic)
8639 {
8640     int size, offset = 0 ;
8641     char *l, buffer[256];
8642
8643     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8644     aopOp(right,ic,FALSE);
8645     
8646     l = aopGet(AOP(result),0,FALSE,TRUE);
8647     size = AOP_SIZE(right);
8648 /*
8649     if ( AOP_TYPE(result) == AOP_PCODE) {
8650       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8651               AOP(result)->aopu.pcop->name,
8652               PCOI(AOP(result)->aopu.pcop)->offset);
8653     }
8654 */
8655
8656     // tsd, was l+1 - the underline `_' prefix was being stripped
8657     while (size--) {
8658       if (offset) {
8659         sprintf(buffer,"(%s + %d)",l,offset);
8660         fprintf(stderr,"oops  %s\n",buffer);
8661       } else
8662         sprintf(buffer,"%s",l);
8663
8664         if (AOP_TYPE(right) == AOP_LIT) {
8665           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8666           lit = lit >> (8*offset);
8667           if(lit&0xff) {
8668             pic14_emitcode("movlw","%d",lit);
8669             pic14_emitcode("movwf","%s",buffer);
8670
8671             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8672             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8673             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8674
8675           } else {
8676             pic14_emitcode("clrf","%s",buffer);
8677             //emitpcode(POC_CLRF, popRegFromString(buffer));
8678             emitpcode(POC_CLRF, popGet(AOP(result),0));
8679           }
8680         }else {
8681           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8682           pic14_emitcode("movwf","%s",buffer);
8683
8684           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8685           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8686           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8687
8688         }
8689
8690         offset++;
8691     }
8692
8693     freeAsmop(right,NULL,ic,TRUE);
8694     freeAsmop(result,NULL,ic,TRUE);
8695 }
8696
8697 /*-----------------------------------------------------------------*/
8698 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8699 /*-----------------------------------------------------------------*/
8700 static void genNearPointerSet (operand *right,
8701                                operand *result, 
8702                                iCode *ic)
8703 {
8704   asmop *aop = NULL;
8705   char *l;
8706   sym_link *retype;
8707   sym_link *ptype = operandType(result);
8708
8709     
8710   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8711   retype= getSpec(operandType(right));
8712
8713   aopOp(result,ic,FALSE);
8714
8715     
8716   /* if the result is rematerializable &
8717      in data space & not a bit variable */
8718   //if (AOP_TYPE(result) == AOP_IMMD &&
8719   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8720       DCL_TYPE(ptype) == POINTER   &&
8721       !IS_BITVAR(retype)) {
8722     genDataPointerSet (right,result,ic);
8723     freeAsmop(result,NULL,ic,TRUE);
8724     return;
8725   }
8726
8727   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8728   aopOp(right,ic,FALSE);
8729   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8730
8731   /* if the value is already in a pointer register
8732      then don't need anything more */
8733   if (!AOP_INPREG(AOP(result))) {
8734     /* otherwise get a free pointer register */
8735     //aop = newAsmop(0);
8736     //preg = getFreePtr(ic,&aop,FALSE);
8737     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8738     //pic14_emitcode("mov","%s,%s",
8739     //         preg->name,
8740     //         aopGet(AOP(result),0,FALSE,TRUE));
8741     //rname = preg->name ;
8742     //pic14_emitcode("movwf","fsr");
8743     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8744     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8745     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8746     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8747     goto release;
8748
8749   }// else
8750   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8751
8752
8753   /* if bitfield then unpack the bits */
8754   if (IS_BITVAR(retype)) {
8755     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8756            "The programmer is obviously confused");
8757     //genPackBits (retype,right,rname,POINTER);
8758     exit(1);
8759   }
8760   else {
8761     /* we have can just get the values */
8762     int size = AOP_SIZE(right);
8763     int offset = 0 ;    
8764
8765     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8766     while (size--) {
8767       l = aopGet(AOP(right),offset,FALSE,TRUE);
8768       if (*l == '@' ) {
8769         //MOVA(l);
8770         //pic14_emitcode("mov","@%s,a",rname);
8771         pic14_emitcode("movf","indf,w ;1");
8772       } else {
8773
8774         if (AOP_TYPE(right) == AOP_LIT) {
8775           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8776           if(lit) {
8777             pic14_emitcode("movlw","%s",l);
8778             pic14_emitcode("movwf","indf ;2");
8779           } else 
8780             pic14_emitcode("clrf","indf");
8781         }else {
8782           pic14_emitcode("movf","%s,w",l);
8783           pic14_emitcode("movwf","indf ;2");
8784         }
8785         //pic14_emitcode("mov","@%s,%s",rname,l);
8786       }
8787       if (size)
8788         pic14_emitcode("incf","fsr,f ;3");
8789       //pic14_emitcode("inc","%s",rname);
8790       offset++;
8791     }
8792   }
8793
8794   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8795   /* now some housekeeping stuff */
8796   if (aop) {
8797     /* we had to allocate for this iCode */
8798     freeAsmop(NULL,aop,ic,TRUE);
8799   } else { 
8800     /* we did not allocate which means left
8801        already in a pointer register, then
8802        if size > 0 && this could be used again
8803        we have to point it back to where it 
8804        belongs */
8805     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8806     if (AOP_SIZE(right) > 1 &&
8807         !OP_SYMBOL(result)->remat &&
8808         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8809           ic->depth )) {
8810       int size = AOP_SIZE(right) - 1;
8811       while (size--)
8812         pic14_emitcode("decf","fsr,f");
8813       //pic14_emitcode("dec","%s",rname);
8814     }
8815   }
8816
8817   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8818   /* done */
8819  release:
8820   freeAsmop(right,NULL,ic,TRUE);
8821   freeAsmop(result,NULL,ic,TRUE);
8822 }
8823
8824 /*-----------------------------------------------------------------*/
8825 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8826 /*-----------------------------------------------------------------*/
8827 static void genPagedPointerSet (operand *right,
8828                                operand *result, 
8829                                iCode *ic)
8830 {
8831     asmop *aop = NULL;
8832     regs *preg = NULL ;
8833     char *rname , *l;
8834     sym_link *retype;
8835        
8836     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8837
8838     retype= getSpec(operandType(right));
8839     
8840     aopOp(result,ic,FALSE);
8841     
8842     /* if the value is already in a pointer register
8843        then don't need anything more */
8844     if (!AOP_INPREG(AOP(result))) {
8845         /* otherwise get a free pointer register */
8846         aop = newAsmop(0);
8847         preg = getFreePtr(ic,&aop,FALSE);
8848         pic14_emitcode("mov","%s,%s",
8849                 preg->name,
8850                 aopGet(AOP(result),0,FALSE,TRUE));
8851         rname = preg->name ;
8852     } else
8853         rname = aopGet(AOP(result),0,FALSE,FALSE);
8854     
8855     freeAsmop(result,NULL,ic,TRUE);
8856     aopOp (right,ic,FALSE);
8857
8858     /* if bitfield then unpack the bits */
8859     if (IS_BITVAR(retype)) 
8860         genPackBits (retype,right,rname,PPOINTER);
8861     else {
8862         /* we have can just get the values */
8863         int size = AOP_SIZE(right);
8864         int offset = 0 ;        
8865         
8866         while (size--) {
8867             l = aopGet(AOP(right),offset,FALSE,TRUE);
8868             
8869             MOVA(l);
8870             pic14_emitcode("movx","@%s,a",rname);
8871
8872             if (size)
8873                 pic14_emitcode("inc","%s",rname);
8874
8875             offset++;
8876         }
8877     }
8878     
8879     /* now some housekeeping stuff */
8880     if (aop) {
8881         /* we had to allocate for this iCode */
8882         freeAsmop(NULL,aop,ic,TRUE);
8883     } else { 
8884         /* we did not allocate which means left
8885            already in a pointer register, then
8886            if size > 0 && this could be used again
8887            we have to point it back to where it 
8888            belongs */
8889         if (AOP_SIZE(right) > 1 &&
8890             !OP_SYMBOL(result)->remat &&
8891             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8892               ic->depth )) {
8893             int size = AOP_SIZE(right) - 1;
8894             while (size--)
8895                 pic14_emitcode("dec","%s",rname);
8896         }
8897     }
8898
8899     /* done */
8900     freeAsmop(right,NULL,ic,TRUE);
8901     
8902         
8903 }
8904
8905 /*-----------------------------------------------------------------*/
8906 /* genFarPointerSet - set value from far space                     */
8907 /*-----------------------------------------------------------------*/
8908 static void genFarPointerSet (operand *right,
8909                               operand *result, iCode *ic)
8910 {
8911     int size, offset ;
8912     sym_link *retype = getSpec(operandType(right));
8913
8914     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8915     aopOp(result,ic,FALSE);
8916
8917     /* if the operand is already in dptr 
8918     then we do nothing else we move the value to dptr */
8919     if (AOP_TYPE(result) != AOP_STR) {
8920         /* if this is remateriazable */
8921         if (AOP_TYPE(result) == AOP_IMMD)
8922             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8923         else { /* we need to get it byte by byte */
8924             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8925             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8926             if (options.model == MODEL_FLAT24)
8927             {
8928                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8929             }
8930         }
8931     }
8932     /* so dptr know contains the address */
8933     freeAsmop(result,NULL,ic,TRUE);
8934     aopOp(right,ic,FALSE);
8935
8936     /* if bit then unpack */
8937     if (IS_BITVAR(retype)) 
8938         genPackBits(retype,right,"dptr",FPOINTER);
8939     else {
8940         size = AOP_SIZE(right);
8941         offset = 0 ;
8942
8943         while (size--) {
8944             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8945             MOVA(l);
8946             pic14_emitcode("movx","@dptr,a");
8947             if (size)
8948                 pic14_emitcode("inc","dptr");
8949         }
8950     }
8951
8952     freeAsmop(right,NULL,ic,TRUE);
8953 }
8954
8955 /*-----------------------------------------------------------------*/
8956 /* genGenPointerSet - set value from generic pointer space         */
8957 /*-----------------------------------------------------------------*/
8958 static void genGenPointerSet (operand *right,
8959                               operand *result, iCode *ic)
8960 {
8961   int size, offset ;
8962   sym_link *retype = getSpec(operandType(right));
8963
8964   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8965
8966   aopOp(result,ic,FALSE);
8967   aopOp(right,ic,FALSE);
8968   size = AOP_SIZE(right);
8969
8970   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8971
8972   /* if the operand is already in dptr 
8973      then we do nothing else we move the value to dptr */
8974   if (AOP_TYPE(result) != AOP_STR) {
8975     /* if this is remateriazable */
8976     if (AOP_TYPE(result) == AOP_IMMD) {
8977       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8978       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8979     }
8980     else { /* we need to get it byte by byte */
8981       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8982       size = AOP_SIZE(right);
8983       offset = 0 ;
8984
8985       /* hack hack! see if this the FSR. If so don't load W */
8986       if(AOP_TYPE(right) != AOP_ACC) {
8987
8988
8989         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8990         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8991
8992         if(AOP_SIZE(result) > 1) {
8993           emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8994           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8995           emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8996
8997         }
8998
8999         //if(size==2)
9000         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
9001         //if(size==4) {
9002         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
9003         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9004         //}
9005
9006         while(size--) {
9007           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9008           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9009           
9010           if(size)
9011             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9012         }
9013
9014
9015         goto release;
9016       } 
9017
9018       if(aopIdx(AOP(result),0) != 4) {
9019
9020         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9021         goto release;
9022       }
9023
9024       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9025       goto release;
9026
9027     }
9028   }
9029   /* so dptr know contains the address */
9030
9031
9032   /* if bit then unpack */
9033   if (IS_BITVAR(retype)) 
9034     genPackBits(retype,right,"dptr",GPOINTER);
9035   else {
9036     size = AOP_SIZE(right);
9037     offset = 0 ;
9038
9039   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9040
9041     while (size--) {
9042
9043       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9044       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9045
9046       if (AOP_TYPE(right) == AOP_LIT) 
9047         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9048       else
9049         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9050
9051       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9052
9053       offset++;
9054     }
9055   }
9056
9057  release:
9058   freeAsmop(right,NULL,ic,TRUE);
9059   freeAsmop(result,NULL,ic,TRUE);
9060 }
9061
9062 /*-----------------------------------------------------------------*/
9063 /* genPointerSet - stores the value into a pointer location        */
9064 /*-----------------------------------------------------------------*/
9065 static void genPointerSet (iCode *ic)
9066 {    
9067     operand *right, *result ;
9068     sym_link *type, *etype;
9069     int p_type;
9070
9071     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9072
9073     right = IC_RIGHT(ic);
9074     result = IC_RESULT(ic) ;
9075
9076     /* depending on the type of pointer we need to
9077     move it to the correct pointer register */
9078     type = operandType(result);
9079     etype = getSpec(type);
9080     /* if left is of type of pointer then it is simple */
9081     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9082         p_type = DCL_TYPE(type);
9083     }
9084     else {
9085         /* we have to go by the storage class */
9086         p_type = PTR_TYPE(SPEC_OCLS(etype));
9087
9088 /*      if (SPEC_OCLS(etype)->codesp ) { */
9089 /*          p_type = CPOINTER ;  */
9090 /*      } */
9091 /*      else */
9092 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9093 /*              p_type = FPOINTER ; */
9094 /*          else */
9095 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9096 /*                  p_type = PPOINTER ; */
9097 /*              else */
9098 /*                  if (SPEC_OCLS(etype) == idata ) */
9099 /*                      p_type = IPOINTER ; */
9100 /*                  else */
9101 /*                      p_type = POINTER ; */
9102     }
9103
9104     /* now that we have the pointer type we assign
9105     the pointer values */
9106     switch (p_type) {
9107
9108     case POINTER:
9109     case IPOINTER:
9110         genNearPointerSet (right,result,ic);
9111         break;
9112
9113     case PPOINTER:
9114         genPagedPointerSet (right,result,ic);
9115         break;
9116
9117     case FPOINTER:
9118         genFarPointerSet (right,result,ic);
9119         break;
9120
9121     case GPOINTER:
9122         genGenPointerSet (right,result,ic);
9123         break;
9124
9125     default:
9126       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9127               "genPointerSet: illegal pointer type");
9128     }
9129 }
9130
9131 /*-----------------------------------------------------------------*/
9132 /* genIfx - generate code for Ifx statement                        */
9133 /*-----------------------------------------------------------------*/
9134 static void genIfx (iCode *ic, iCode *popIc)
9135 {
9136   operand *cond = IC_COND(ic);
9137   int isbit =0;
9138
9139   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9140
9141   aopOp(cond,ic,FALSE);
9142
9143   /* get the value into acc */
9144   if (AOP_TYPE(cond) != AOP_CRY)
9145     pic14_toBoolean(cond);
9146   else
9147     isbit = 1;
9148   /* the result is now in the accumulator */
9149   freeAsmop(cond,NULL,ic,TRUE);
9150
9151   /* if there was something to be popped then do it */
9152   if (popIc)
9153     genIpop(popIc);
9154
9155   /* if the condition is  a bit variable */
9156   if (isbit && IS_ITEMP(cond) && 
9157       SPIL_LOC(cond)) {
9158     genIfxJump(ic,SPIL_LOC(cond)->rname);
9159     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9160   }
9161   else {
9162     if (isbit && !IS_ITEMP(cond))
9163       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9164     else
9165       genIfxJump(ic,"a");
9166   }
9167   ic->generated = 1;
9168
9169 }
9170
9171 /*-----------------------------------------------------------------*/
9172 /* genAddrOf - generates code for address of                       */
9173 /*-----------------------------------------------------------------*/
9174 static void genAddrOf (iCode *ic)
9175 {
9176   operand *right, *result, *left;
9177   int size, offset ;
9178
9179   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9180
9181
9182   //aopOp(IC_RESULT(ic),ic,FALSE);
9183
9184   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9185   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9186   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9187
9188   DEBUGpic14_AopType(__LINE__,left,right,result);
9189
9190   size = AOP_SIZE(IC_RESULT(ic));
9191   offset = 0;
9192
9193   while (size--) {
9194     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9195     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9196     offset++;
9197   }
9198
9199   freeAsmop(left,NULL,ic,FALSE);
9200   freeAsmop(result,NULL,ic,TRUE);
9201
9202 }
9203
9204 #if 0
9205 /*-----------------------------------------------------------------*/
9206 /* genFarFarAssign - assignment when both are in far space         */
9207 /*-----------------------------------------------------------------*/
9208 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9209 {
9210     int size = AOP_SIZE(right);
9211     int offset = 0;
9212     char *l ;
9213     /* first push the right side on to the stack */
9214     while (size--) {
9215         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9216         MOVA(l);
9217         pic14_emitcode ("push","acc");
9218     }
9219     
9220     freeAsmop(right,NULL,ic,FALSE);
9221     /* now assign DPTR to result */
9222     aopOp(result,ic,FALSE);
9223     size = AOP_SIZE(result);
9224     while (size--) {
9225         pic14_emitcode ("pop","acc");
9226         aopPut(AOP(result),"a",--offset);
9227     }
9228     freeAsmop(result,NULL,ic,FALSE);
9229         
9230 }
9231 #endif
9232
9233 /*-----------------------------------------------------------------*/
9234 /* genAssign - generate code for assignment                        */
9235 /*-----------------------------------------------------------------*/
9236 static void genAssign (iCode *ic)
9237 {
9238   operand *result, *right;
9239   int size, offset,know_W;
9240   unsigned long lit = 0L;
9241
9242   result = IC_RESULT(ic);
9243   right  = IC_RIGHT(ic) ;
9244
9245   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9246
9247   /* if they are the same */
9248   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9249     return ;
9250
9251   aopOp(right,ic,FALSE);
9252   aopOp(result,ic,TRUE);
9253
9254   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9255
9256   /* if they are the same registers */
9257   if (pic14_sameRegs(AOP(right),AOP(result)))
9258     goto release;
9259
9260   /* if the result is a bit */
9261   if (AOP_TYPE(result) == AOP_CRY) {
9262
9263     /* if the right size is a literal then
9264        we know what the value is */
9265     if (AOP_TYPE(right) == AOP_LIT) {
9266           
9267       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9268                   popGet(AOP(result),0));
9269
9270       if (((int) operandLitValue(right))) 
9271         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9272                        AOP(result)->aopu.aop_dir,
9273                        AOP(result)->aopu.aop_dir);
9274       else
9275         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9276                        AOP(result)->aopu.aop_dir,
9277                        AOP(result)->aopu.aop_dir);
9278       goto release;
9279     }
9280
9281     /* the right is also a bit variable */
9282     if (AOP_TYPE(right) == AOP_CRY) {
9283       emitpcode(POC_BCF,    popGet(AOP(result),0));
9284       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9285       emitpcode(POC_BSF,    popGet(AOP(result),0));
9286
9287       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9288                      AOP(result)->aopu.aop_dir,
9289                      AOP(result)->aopu.aop_dir);
9290       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9291                      AOP(right)->aopu.aop_dir,
9292                      AOP(right)->aopu.aop_dir);
9293       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9294                      AOP(result)->aopu.aop_dir,
9295                      AOP(result)->aopu.aop_dir);
9296       goto release ;
9297     }
9298
9299     /* we need to or */
9300     emitpcode(POC_BCF,    popGet(AOP(result),0));
9301     pic14_toBoolean(right);
9302     emitSKPZ;
9303     emitpcode(POC_BSF,    popGet(AOP(result),0));
9304     //aopPut(AOP(result),"a",0);
9305     goto release ;
9306   }
9307
9308   /* bit variables done */
9309   /* general case */
9310   size = AOP_SIZE(result);
9311   offset = 0 ;
9312   if(AOP_TYPE(right) == AOP_LIT)
9313     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9314
9315   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9316   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9317     if(aopIdx(AOP(result),0) == 4) {
9318   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9319       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9320       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9321       goto release;
9322     } else
9323       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9324   }
9325
9326   know_W=-1;
9327   while (size--) {
9328   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9329     if(AOP_TYPE(right) == AOP_LIT) {
9330       if(lit&0xff) {
9331         if(know_W != (lit&0xff))
9332           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9333         know_W = lit&0xff;
9334         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9335       } else
9336         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9337
9338       lit >>= 8;
9339
9340     } else if (AOP_TYPE(right) == AOP_CRY) {
9341       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9342       if(offset == 0) {
9343         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9344         emitpcode(POC_INCF, popGet(AOP(result),0));
9345       }
9346     } else {
9347       mov2w (AOP(right), offset);
9348       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9349     }
9350             
9351     offset++;
9352   }
9353
9354     
9355  release:
9356   freeAsmop (right,NULL,ic,FALSE);
9357   freeAsmop (result,NULL,ic,TRUE);
9358 }   
9359
9360 /*-----------------------------------------------------------------*/
9361 /* genJumpTab - genrates code for jump table                       */
9362 /*-----------------------------------------------------------------*/
9363 static void genJumpTab (iCode *ic)
9364 {
9365     symbol *jtab;
9366     char *l;
9367
9368     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9369
9370     aopOp(IC_JTCOND(ic),ic,FALSE);
9371     /* get the condition into accumulator */
9372     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9373     MOVA(l);
9374     /* multiply by three */
9375     pic14_emitcode("add","a,acc");
9376     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9377
9378     jtab = newiTempLabel(NULL);
9379     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9380     pic14_emitcode("jmp","@a+dptr");
9381     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9382
9383     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9384     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9385     emitSKPNC;
9386     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9387     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9388     emitpLabel(jtab->key);
9389
9390     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9391
9392     /* now generate the jump labels */
9393     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9394          jtab = setNextItem(IC_JTLABELS(ic))) {
9395         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9396         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9397         
9398     }
9399
9400 }
9401
9402 /*-----------------------------------------------------------------*/
9403 /* genMixedOperation - gen code for operators between mixed types  */
9404 /*-----------------------------------------------------------------*/
9405 /*
9406   TSD - Written for the PIC port - but this unfortunately is buggy.
9407   This routine is good in that it is able to efficiently promote 
9408   types to different (larger) sizes. Unfortunately, the temporary
9409   variables that are optimized out by this routine are sometimes
9410   used in other places. So until I know how to really parse the 
9411   iCode tree, I'm going to not be using this routine :(.
9412 */
9413 static int genMixedOperation (iCode *ic)
9414 {
9415 #if 0
9416   operand *result = IC_RESULT(ic);
9417   sym_link *ctype = operandType(IC_LEFT(ic));
9418   operand *right = IC_RIGHT(ic);
9419   int ret = 0;
9420   int big,small;
9421   int offset;
9422
9423   iCode *nextic;
9424   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9425
9426   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9427
9428   nextic = ic->next;
9429   if(!nextic)
9430     return 0;
9431
9432   nextright = IC_RIGHT(nextic);
9433   nextleft  = IC_LEFT(nextic);
9434   nextresult = IC_RESULT(nextic);
9435
9436   aopOp(right,ic,FALSE);
9437   aopOp(result,ic,FALSE);
9438   aopOp(nextright,  nextic, FALSE);
9439   aopOp(nextleft,   nextic, FALSE);
9440   aopOp(nextresult, nextic, FALSE);
9441
9442   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9443
9444     operand *t = right;
9445     right = nextright;
9446     nextright = t; 
9447
9448     pic14_emitcode(";remove right +","");
9449
9450   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9451 /*
9452     operand *t = right;
9453     right = nextleft;
9454     nextleft = t; 
9455 */
9456     pic14_emitcode(";remove left +","");
9457   } else
9458     return 0;
9459
9460   big = AOP_SIZE(nextleft);
9461   small = AOP_SIZE(nextright);
9462
9463   switch(nextic->op) {
9464
9465   case '+':
9466     pic14_emitcode(";optimize a +","");
9467     /* if unsigned or not an integral type */
9468     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9469       pic14_emitcode(";add a bit to something","");
9470     } else {
9471
9472       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9473
9474       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9475         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9476         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9477       } else
9478         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9479
9480       offset = 0;
9481       while(--big) {
9482
9483         offset++;
9484
9485         if(--small) {
9486           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9487             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9488             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9489           }
9490
9491           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9492           emitSKPNC;
9493           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9494                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9495                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9496           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9497           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9498
9499         } else {
9500           pic14_emitcode("rlf","known_zero,w");
9501
9502           /*
9503             if right is signed
9504               btfsc  right,7
9505                addlw ff
9506           */
9507           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9508             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9509             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9510           } else {
9511             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9512           }
9513         }
9514       }
9515       ret = 1;
9516     }
9517   }
9518   ret = 1;
9519
9520 release:
9521   freeAsmop(right,NULL,ic,TRUE);
9522   freeAsmop(result,NULL,ic,TRUE);
9523   freeAsmop(nextright,NULL,ic,TRUE);
9524   freeAsmop(nextleft,NULL,ic,TRUE);
9525   if(ret)
9526     nextic->generated = 1;
9527
9528   return ret;
9529 #else
9530   return 0;
9531 #endif
9532 }
9533 /*-----------------------------------------------------------------*/
9534 /* genCast - gen code for casting                                  */
9535 /*-----------------------------------------------------------------*/
9536 static void genCast (iCode *ic)
9537 {
9538     operand *result = IC_RESULT(ic);
9539     sym_link *ctype = operandType(IC_LEFT(ic));
9540     sym_link *rtype = operandType(IC_RIGHT(ic));
9541     operand *right = IC_RIGHT(ic);
9542     int size, offset ;
9543
9544     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9545     /* if they are equivalent then do nothing */
9546     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9547         return ;
9548
9549     aopOp(right,ic,FALSE) ;
9550     aopOp(result,ic,FALSE);
9551
9552     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9553
9554     /* if the result is a bit */
9555     if (AOP_TYPE(result) == AOP_CRY) {
9556         /* if the right size is a literal then
9557         we know what the value is */
9558       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9559         if (AOP_TYPE(right) == AOP_LIT) {
9560
9561           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9562                       popGet(AOP(result),0));
9563
9564             if (((int) operandLitValue(right))) 
9565               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9566                        AOP(result)->aopu.aop_dir,
9567                        AOP(result)->aopu.aop_dir);
9568             else
9569               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9570                        AOP(result)->aopu.aop_dir,
9571                        AOP(result)->aopu.aop_dir);
9572
9573             goto release;
9574         }
9575
9576         /* the right is also a bit variable */
9577         if (AOP_TYPE(right) == AOP_CRY) {
9578
9579           emitCLRC;
9580           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9581
9582           pic14_emitcode("clrc","");
9583           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9584                    AOP(right)->aopu.aop_dir,
9585                    AOP(right)->aopu.aop_dir);
9586             aopPut(AOP(result),"c",0);
9587             goto release ;
9588         }
9589
9590         /* we need to or */
9591         if (AOP_TYPE(right) == AOP_REG) {
9592           emitpcode(POC_BCF,    popGet(AOP(result),0));
9593           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9594           emitpcode(POC_BSF,    popGet(AOP(result),0));
9595         }
9596         pic14_toBoolean(right);
9597         aopPut(AOP(result),"a",0);
9598         goto release ;
9599     }
9600
9601     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9602       int offset = 1;
9603       size = AOP_SIZE(result);
9604
9605       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9606
9607       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9608       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9609       emitpcode(POC_INCF,   popGet(AOP(result),0));
9610
9611       while (size--)
9612         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9613
9614       goto release;
9615     }
9616
9617     /* if they are the same size : or less */
9618     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9619
9620         /* if they are in the same place */
9621       if (pic14_sameRegs(AOP(right),AOP(result)))
9622         goto release;
9623
9624       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9625       if (IS_PTR_CONST(rtype))
9626         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9627       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9628         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9629
9630       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9631         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9632         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9633         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9634         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9635         if(AOP_SIZE(result) <2)
9636           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9637
9638       } else {
9639
9640         /* if they in different places then copy */
9641         size = AOP_SIZE(result);
9642         offset = 0 ;
9643         while (size--) {
9644           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9645           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9646
9647           //aopPut(AOP(result),
9648           // aopGet(AOP(right),offset,FALSE,FALSE),
9649           // offset);
9650
9651           offset++;
9652         }
9653       }
9654       goto release;
9655     }
9656
9657
9658     /* if the result is of type pointer */
9659     if (IS_PTR(ctype)) {
9660
9661         int p_type;
9662         sym_link *type = operandType(right);
9663         sym_link *etype = getSpec(type);
9664       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9665
9666         /* pointer to generic pointer */
9667         if (IS_GENPTR(ctype)) {
9668             char *l = zero;
9669             
9670             if (IS_PTR(type)) 
9671                 p_type = DCL_TYPE(type);
9672             else {
9673                 /* we have to go by the storage class */
9674                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9675
9676 /*              if (SPEC_OCLS(etype)->codesp )  */
9677 /*                  p_type = CPOINTER ;  */
9678 /*              else */
9679 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9680 /*                      p_type = FPOINTER ; */
9681 /*                  else */
9682 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9683 /*                          p_type = PPOINTER; */
9684 /*                      else */
9685 /*                          if (SPEC_OCLS(etype) == idata ) */
9686 /*                              p_type = IPOINTER ; */
9687 /*                          else */
9688 /*                              p_type = POINTER ; */
9689             }
9690                 
9691             /* the first two bytes are known */
9692       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9693             size = GPTRSIZE - 1; 
9694             offset = 0 ;
9695             while (size--) {
9696               if(offset < AOP_SIZE(right)) {
9697       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9698                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9699                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9700                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9701                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9702                 } else { 
9703                   aopPut(AOP(result),
9704                          aopGet(AOP(right),offset,FALSE,FALSE),
9705                          offset);
9706                 }
9707               } else 
9708                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9709               offset++;
9710             }
9711             /* the last byte depending on type */
9712             switch (p_type) {
9713             case IPOINTER:
9714             case POINTER:
9715                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9716                 break;
9717             case FPOINTER:
9718               pic14_emitcode(";BUG!? ","%d",__LINE__);
9719                 l = one;
9720                 break;
9721             case CPOINTER:
9722               pic14_emitcode(";BUG!? ","%d",__LINE__);
9723                 l = "#0x02";
9724                 break;                          
9725             case PPOINTER:
9726               pic14_emitcode(";BUG!? ","%d",__LINE__);
9727                 l = "#0x03";
9728                 break;
9729                 
9730             default:
9731                 /* this should never happen */
9732                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9733                        "got unknown pointer type");
9734                 exit(1);
9735             }
9736             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9737             goto release ;
9738         }
9739         
9740         /* just copy the pointers */
9741         size = AOP_SIZE(result);
9742         offset = 0 ;
9743         while (size--) {
9744             aopPut(AOP(result),
9745                    aopGet(AOP(right),offset,FALSE,FALSE),
9746                    offset);
9747             offset++;
9748         }
9749         goto release ;
9750     }
9751     
9752
9753
9754     /* so we now know that the size of destination is greater
9755     than the size of the source.
9756     Now, if the next iCode is an operator then we might be
9757     able to optimize the operation without performing a cast.
9758     */
9759     if(genMixedOperation(ic))
9760       goto release;
9761
9762     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9763     
9764     /* we move to result for the size of source */
9765     size = AOP_SIZE(right);
9766     offset = 0 ;
9767     while (size--) {
9768       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9769       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9770       offset++;
9771     }
9772
9773     /* now depending on the sign of the destination */
9774     size = AOP_SIZE(result) - AOP_SIZE(right);
9775     /* if unsigned or not an integral type */
9776     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9777       while (size--)
9778         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9779     } else {
9780       /* we need to extend the sign :{ */
9781
9782       if(size == 1) {
9783         /* Save one instruction of casting char to int */
9784         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9785         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9786         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9787       } else {
9788         emitpcodeNULLop(POC_CLRW);
9789
9790         if(offset)
9791           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9792         else
9793           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9794         
9795         emitpcode(POC_MOVLW,   popGetLit(0xff));
9796
9797         while (size--)
9798           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9799       }
9800     }
9801
9802 release:
9803     freeAsmop(right,NULL,ic,TRUE);
9804     freeAsmop(result,NULL,ic,TRUE);
9805
9806 }
9807
9808 /*-----------------------------------------------------------------*/
9809 /* genDjnz - generate decrement & jump if not zero instrucion      */
9810 /*-----------------------------------------------------------------*/
9811 static int genDjnz (iCode *ic, iCode *ifx)
9812 {
9813     symbol *lbl, *lbl1;
9814     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9815
9816     if (!ifx)
9817         return 0;
9818     
9819     /* if the if condition has a false label
9820        then we cannot save */
9821     if (IC_FALSE(ifx))
9822         return 0;
9823
9824     /* if the minus is not of the form 
9825        a = a - 1 */
9826     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9827         !IS_OP_LITERAL(IC_RIGHT(ic)))
9828         return 0;
9829
9830     if (operandLitValue(IC_RIGHT(ic)) != 1)
9831         return 0;
9832
9833     /* if the size of this greater than one then no
9834        saving */
9835     if (getSize(operandType(IC_RESULT(ic))) > 1)
9836         return 0;
9837
9838     /* otherwise we can save BIG */
9839     lbl = newiTempLabel(NULL);
9840     lbl1= newiTempLabel(NULL);
9841
9842     aopOp(IC_RESULT(ic),ic,FALSE);
9843     
9844     if (IS_AOP_PREG(IC_RESULT(ic))) {
9845         pic14_emitcode("dec","%s",
9846                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9847         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9848         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9849     } else {    
9850
9851
9852       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9853       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9854
9855       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9856       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9857
9858     }
9859 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9860 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9861 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9862 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9863
9864     
9865     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9866     ifx->generated = 1;
9867     return 1;
9868 }
9869
9870 /*-----------------------------------------------------------------*/
9871 /* genReceive - generate code for a receive iCode                  */
9872 /*-----------------------------------------------------------------*/
9873 static void genReceive (iCode *ic)
9874 {    
9875   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9876
9877   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9878       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9879         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9880
9881     int size = getSize(operandType(IC_RESULT(ic)));
9882     int offset =  fReturnSizePic - size;
9883     while (size--) {
9884       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9885                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9886       offset++;
9887     }
9888     aopOp(IC_RESULT(ic),ic,FALSE);  
9889     size = AOP_SIZE(IC_RESULT(ic));
9890     offset = 0;
9891     while (size--) {
9892       pic14_emitcode ("pop","acc");
9893       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9894     }
9895         
9896   } else {
9897     _G.accInUse++;
9898     aopOp(IC_RESULT(ic),ic,FALSE);  
9899     _G.accInUse--;
9900     assignResultValue(IC_RESULT(ic));   
9901   }
9902
9903   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9904 }
9905
9906 /*-----------------------------------------------------------------*/
9907 /* genpic14Code - generate code for pic14 based controllers        */
9908 /*-----------------------------------------------------------------*/
9909 /*
9910  * At this point, ralloc.c has gone through the iCode and attempted
9911  * to optimize in a way suitable for a PIC. Now we've got to generate
9912  * PIC instructions that correspond to the iCode.
9913  *
9914  * Once the instructions are generated, we'll pass through both the
9915  * peep hole optimizer and the pCode optimizer.
9916  *-----------------------------------------------------------------*/
9917
9918 void genpic14Code (iCode *lic)
9919 {
9920     iCode *ic;
9921     int cln = 0;
9922
9923     lineHead = lineCurr = NULL;
9924
9925     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9926     addpBlock(pb);
9927
9928     /* if debug information required */
9929     if (options.debug && currFunc) { 
9930       if (currFunc) {
9931         debugFile->writeFunction(currFunc);
9932         _G.debugLine = 1;
9933         if (IS_STATIC(currFunc->etype)) {
9934           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9935           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9936         } else {
9937           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9938           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9939         }
9940         _G.debugLine = 0;
9941       }
9942     }
9943
9944
9945     for (ic = lic ; ic ; ic = ic->next ) {
9946
9947       DEBUGpic14_emitcode(";ic","");
9948         if ( cln != ic->lineno ) {
9949             if ( options.debug ) {
9950                 _G.debugLine = 1;
9951                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9952                          FileBaseName(ic->filename),ic->lineno,
9953                          ic->level,ic->block);
9954                 _G.debugLine = 0;
9955             }
9956             /*
9957               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9958               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9959               printCLine(ic->filename, ic->lineno));
9960             */
9961             if (!options.noCcodeInAsm) {
9962               addpCode2pBlock(pb,
9963                               newpCodeCSource(ic->lineno, 
9964                                               ic->filename, 
9965                                               printCLine(ic->filename, ic->lineno)));
9966             }
9967
9968             cln = ic->lineno ;
9969         }
9970
9971         // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9972
9973         /* if the result is marked as
9974            spilt and rematerializable or code for
9975            this has already been generated then
9976            do nothing */
9977         if (resultRemat(ic) || ic->generated ) 
9978             continue ;
9979         
9980         /* depending on the operation */
9981         switch (ic->op) {
9982         case '!' :
9983             genNot(ic);
9984             break;
9985             
9986         case '~' :
9987             genCpl(ic);
9988             break;
9989             
9990         case UNARYMINUS:
9991             genUminus (ic);
9992             break;
9993             
9994         case IPUSH:
9995             genIpush (ic);
9996             break;
9997             
9998         case IPOP:
9999             /* IPOP happens only when trying to restore a 
10000                spilt live range, if there is an ifx statement
10001                following this pop then the if statement might
10002                be using some of the registers being popped which
10003                would destory the contents of the register so
10004                we need to check for this condition and handle it */
10005             if (ic->next            && 
10006                 ic->next->op == IFX &&
10007                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
10008                 genIfx (ic->next,ic);
10009             else
10010                 genIpop (ic);
10011             break; 
10012             
10013         case CALL:
10014             genCall (ic);
10015             break;
10016             
10017         case PCALL:
10018             genPcall (ic);
10019             break;
10020             
10021         case FUNCTION:
10022             genFunction (ic);
10023             break;
10024             
10025         case ENDFUNCTION:
10026             genEndFunction (ic);
10027             break;
10028             
10029         case RETURN:
10030             genRet (ic);
10031             break;
10032             
10033         case LABEL:
10034             genLabel (ic);
10035             break;
10036             
10037         case GOTO:
10038             genGoto (ic);
10039             break;
10040             
10041         case '+' :
10042             genPlus (ic) ;
10043             break;
10044             
10045         case '-' :
10046             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10047                 genMinus (ic);
10048             break;
10049             
10050         case '*' :
10051             genMult (ic);
10052             break;
10053             
10054         case '/' :
10055             genDiv (ic) ;
10056             break;
10057             
10058         case '%' :
10059             genMod (ic);
10060             break;
10061             
10062         case '>' :
10063             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10064             break;
10065             
10066         case '<' :
10067             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10068             break;
10069             
10070         case LE_OP:
10071         case GE_OP:
10072         case NE_OP:
10073             
10074             /* note these two are xlated by algebraic equivalence
10075                during parsing SDCC.y */
10076             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10077                    "got '>=' or '<=' shouldn't have come here");
10078             break;      
10079             
10080         case EQ_OP:
10081             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10082             break;          
10083             
10084         case AND_OP:
10085             genAndOp (ic);
10086             break;
10087             
10088         case OR_OP:
10089             genOrOp (ic);
10090             break;
10091             
10092         case '^' :
10093             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10094             break;
10095             
10096         case '|' :
10097                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10098             break;
10099             
10100         case BITWISEAND:
10101             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10102             break;
10103             
10104         case INLINEASM:
10105             genInline (ic);
10106             break;
10107             
10108         case RRC:
10109             genRRC (ic);
10110             break;
10111             
10112         case RLC:
10113             genRLC (ic);
10114             break;
10115             
10116         case GETHBIT:
10117             genGetHbit (ic);
10118             break;
10119             
10120         case LEFT_OP:
10121             genLeftShift (ic);
10122             break;
10123             
10124         case RIGHT_OP:
10125             genRightShift (ic);
10126             break;
10127             
10128         case GET_VALUE_AT_ADDRESS:
10129             genPointerGet(ic);
10130             break;
10131             
10132         case '=' :
10133             if (POINTER_SET(ic))
10134                 genPointerSet(ic);
10135             else
10136                 genAssign(ic);
10137             break;
10138             
10139         case IFX:
10140             genIfx (ic,NULL);
10141             break;
10142             
10143         case ADDRESS_OF:
10144             genAddrOf (ic);
10145             break;
10146             
10147         case JUMPTABLE:
10148             genJumpTab (ic);
10149             break;
10150             
10151         case CAST:
10152             genCast (ic);
10153             break;
10154             
10155         case RECEIVE:
10156             genReceive(ic);
10157             break;
10158             
10159         case SEND:
10160             addSet(&_G.sendSet,ic);
10161             break;
10162
10163         default :
10164             ic = ic;
10165         }
10166     }
10167     
10168
10169     /* now we are ready to call the 
10170        peep hole optimizer */
10171     if (!options.nopeep) {
10172       peepHole (&lineHead);
10173     }
10174     /* now do the actual printing */
10175     printLine (lineHead,codeOutFile);
10176
10177 #ifdef PCODE_DEBUG
10178     DFPRINTF((stderr,"printing pBlock\n\n"));
10179     printpBlock(stdout,pb);
10180 #endif
10181
10182     return;
10183 }