Steve Tell fixed a nested for-loop bug in the PIC Port
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #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);
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         sym->aop = aop = newAsmop(AOP_IMMD);    
527         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
528         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
529         strcpy(aop->aopu.aop_immd,sym->rname);
530         aop->size = FPTRSIZE; 
531         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
532         return aop;
533     }
534
535
536     /* only remaining is far space */
537     /* in which case DPTR gets the address */
538     sym->aop = aop = newAsmop(AOP_PCODE);
539
540     aop->aopu.pcop = popGetImmd(sym->rname,0,0);
541     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542     PCOI(aop->aopu.pcop)->index = 0;
543
544     DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
545                         __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
546
547     allocDirReg (IC_LEFT(ic));
548
549     aop->size = FPTRSIZE; 
550 /*
551     DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552     sym->aop = aop = newAsmop(AOP_DPTR);
553     pic14_emitcode ("mov","dptr,#%s", sym->rname);
554     aop->size = getSize(sym->type);
555
556     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
557 */
558
559     /* if it is in code space */
560     if (IN_CODESPACE(space))
561         aop->code = 1;
562
563     return aop;     
564 }
565
566 /*-----------------------------------------------------------------*/
567 /* aopForRemat - rematerialzes an object                           */
568 /*-----------------------------------------------------------------*/
569 static asmop *aopForRemat (operand *op) // x symbol *sym)
570 {
571   symbol *sym = OP_SYMBOL(op);
572   iCode *ic = NULL;
573   asmop *aop = newAsmop(AOP_PCODE);
574   int val = 0;
575   int offset = 0;
576
577   ic = sym->rematiCode;
578
579   DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
580   if(IS_OP_POINTER(op)) {
581     DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
582   }
583   for (;;) {
584     if (ic->op == '+') {
585       val += (int) operandLitValue(IC_RIGHT(ic));
586     } else if (ic->op == '-') {
587       val -= (int) operandLitValue(IC_RIGHT(ic));
588     } else
589       break;
590         
591     ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
592   }
593
594   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
595   aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
596   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
597   PCOI(aop->aopu.pcop)->index = val;
598
599   DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
600                       __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
601                       val, IS_PTR_CONST(operandType(op)));
602
603   //    DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
604
605   allocDirReg (IC_LEFT(ic));
606
607   return aop;        
608 }
609
610 int aopIdx (asmop *aop, int offset)
611 {
612   if(!aop)
613     return -1;
614
615   if(aop->type !=  AOP_REG)
616     return -2;
617         
618   return aop->aopu.aop_reg[offset]->rIdx;
619
620 }
621 /*-----------------------------------------------------------------*/
622 /* regsInCommon - two operands have some registers in common       */
623 /*-----------------------------------------------------------------*/
624 static bool regsInCommon (operand *op1, operand *op2)
625 {
626     symbol *sym1, *sym2;
627     int i;
628
629     /* if they have registers in common */
630     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
631         return FALSE ;
632
633     sym1 = OP_SYMBOL(op1);
634     sym2 = OP_SYMBOL(op2);
635
636     if (sym1->nRegs == 0 || sym2->nRegs == 0)
637         return FALSE ;
638
639     for (i = 0 ; i < sym1->nRegs ; i++) {
640         int j;
641         if (!sym1->regs[i])
642             continue ;
643
644         for (j = 0 ; j < sym2->nRegs ;j++ ) {
645             if (!sym2->regs[j])
646                 continue ;
647
648             if (sym2->regs[j] == sym1->regs[i])
649                 return TRUE ;
650         }
651     }
652
653     return FALSE ;
654 }
655
656 /*-----------------------------------------------------------------*/
657 /* operandsEqu - equivalent                                        */
658 /*-----------------------------------------------------------------*/
659 static bool operandsEqu ( operand *op1, operand *op2)
660 {
661     symbol *sym1, *sym2;
662
663     /* if they not symbols */
664     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
665         return FALSE;
666
667     sym1 = OP_SYMBOL(op1);
668     sym2 = OP_SYMBOL(op2);
669
670     /* if both are itemps & one is spilt
671        and the other is not then false */
672     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
673         sym1->isspilt != sym2->isspilt )
674         return FALSE ;
675
676     /* if they are the same */
677     if (sym1 == sym2)
678         return TRUE ;
679
680     if (strcmp(sym1->rname,sym2->rname) == 0)
681         return TRUE;
682
683
684     /* if left is a tmp & right is not */
685     if (IS_ITEMP(op1)  && 
686         !IS_ITEMP(op2) &&
687         sym1->isspilt  &&
688         (sym1->usl.spillLoc == sym2))
689         return TRUE;
690
691     if (IS_ITEMP(op2)  && 
692         !IS_ITEMP(op1) &&
693         sym2->isspilt  &&
694         sym1->level > 0 &&
695         (sym2->usl.spillLoc == sym1))
696         return TRUE ;
697
698     return FALSE ;
699 }
700
701 /*-----------------------------------------------------------------*/
702 /* pic14_sameRegs - two asmops have the same registers                   */
703 /*-----------------------------------------------------------------*/
704 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
705 {
706     int i;
707
708     if (aop1 == aop2)
709         return TRUE ;
710
711     if (aop1->type != AOP_REG ||
712         aop2->type != AOP_REG )
713         return FALSE ;
714
715     if (aop1->size != aop2->size )
716         return FALSE ;
717
718     for (i = 0 ; i < aop1->size ; i++ )
719         if (aop1->aopu.aop_reg[i] !=
720             aop2->aopu.aop_reg[i] )
721             return FALSE ;
722
723     return TRUE ;
724 }
725
726 /*-----------------------------------------------------------------*/
727 /* aopOp - allocates an asmop for an operand  :                    */
728 /*-----------------------------------------------------------------*/
729 void aopOp (operand *op, iCode *ic, bool result)
730 {
731     asmop *aop;
732     symbol *sym;
733     int i;
734
735     if (!op)
736         return ;
737
738     //    DEBUGpic14_emitcode(";","%d",__LINE__);
739     /* if this a literal */
740     if (IS_OP_LITERAL(op)) {
741         op->aop = aop = newAsmop(AOP_LIT);
742         aop->aopu.aop_lit = op->operand.valOperand;
743         aop->size = getSize(operandType(op));
744         return;
745     }
746
747     {
748       sym_link *type = operandType(op);
749       if(IS_PTR_CONST(type))
750         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
751     }
752
753     /* if already has a asmop then continue */
754     if (op->aop)
755         return ;
756
757     /* if the underlying symbol has a aop */
758     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
759       DEBUGpic14_emitcode(";","%d",__LINE__);
760         op->aop = OP_SYMBOL(op)->aop;
761         return;
762     }
763
764     /* if this is a true symbol */
765     if (IS_TRUE_SYMOP(op)) {    
766       //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
767       op->aop = aopForSym(ic,OP_SYMBOL(op),result);
768       return ;
769     }
770
771     /* this is a temporary : this has
772     only four choices :
773     a) register
774     b) spillocation
775     c) rematerialize 
776     d) conditional   
777     e) can be a return use only */
778
779     sym = OP_SYMBOL(op);
780
781
782     /* if the type is a conditional */
783     if (sym->regType == REG_CND) {
784         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
785         aop->size = 0;
786         return;
787     }
788
789     /* if it is spilt then two situations
790     a) is rematerialize 
791     b) has a spill location */
792     if (sym->isspilt || sym->nRegs == 0) {
793
794       DEBUGpic14_emitcode(";","%d",__LINE__);
795         /* rematerialize it NOW */
796         if (sym->remat) {
797
798             sym->aop = op->aop = aop =
799                                       aopForRemat (op);
800             aop->size = getSize(sym->type);
801             //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
802             return;
803         }
804
805         if (sym->accuse) {
806             int i;
807             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
808             aop->size = getSize(sym->type);
809             for ( i = 0 ; i < 2 ; i++ )
810                 aop->aopu.aop_str[i] = accUse[i];
811             DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
812             return;  
813         }
814
815         if (sym->ruonly ) {
816           /*
817           sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
818           aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
819           //allocDirReg (IC_LEFT(ic));
820           aop->size = getSize(sym->type);
821           */
822
823           unsigned i;
824
825           aop = op->aop = sym->aop = newAsmop(AOP_STR);
826           aop->size = getSize(sym->type);
827           for ( i = 0 ; i < fReturnSizePic ; i++ )
828             aop->aopu.aop_str[i] = fReturn[i];
829
830           DEBUGpic14_emitcode(";","%d",__LINE__);
831           return;
832         }
833
834         /* else spill location  */
835         if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
836             /* force a new aop if sizes differ */
837             sym->usl.spillLoc->aop = NULL;
838         }
839         DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
840                             __FUNCTION__,__LINE__,
841                             sym->usl.spillLoc->rname,
842                             sym->rname, sym->usl.spillLoc->offset);
843
844         sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
845         //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
846         aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
847                                           getSize(sym->type), 
848                                           sym->usl.spillLoc->offset);
849         aop->size = getSize(sym->type);
850
851         return;
852     }
853
854     {
855       sym_link *type = operandType(op);
856       if(IS_PTR_CONST(type)) 
857         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
858     }
859
860     /* must be in a register */
861     DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
862     sym->aop = op->aop = aop = newAsmop(AOP_REG);
863     aop->size = sym->nRegs;
864     for ( i = 0 ; i < sym->nRegs ;i++)
865         aop->aopu.aop_reg[i] = sym->regs[i];
866 }
867
868 /*-----------------------------------------------------------------*/
869 /* freeAsmop - free up the asmop given to an operand               */
870 /*----------------------------------------------------------------*/
871 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
872 {   
873     asmop *aop ;
874
875     if (!op)
876         aop = aaop;
877     else 
878         aop = op->aop;
879
880     if (!aop)
881         return ;
882
883     if (aop->freed)
884         goto dealloc; 
885
886     aop->freed = 1;
887
888     /* depending on the asmop type only three cases need work AOP_RO
889        , AOP_R1 && AOP_STK */
890 #if 0
891     switch (aop->type) {
892         case AOP_R0 :
893             if (_G.r0Pushed ) {
894                 if (pop) {
895                     pic14_emitcode ("pop","ar0");     
896                     _G.r0Pushed--;
897                 }
898             }
899             bitVectUnSetBit(ic->rUsed,R0_IDX);
900             break;
901
902         case AOP_R1 :
903             if (_G.r1Pushed ) {
904                 if (pop) {
905                     pic14_emitcode ("pop","ar1");
906                     _G.r1Pushed--;
907                 }
908             }
909             bitVectUnSetBit(ic->rUsed,R1_IDX);          
910             break;
911
912         case AOP_STK :
913         {
914             int sz = aop->size;    
915             int stk = aop->aopu.aop_stk + aop->size;
916             bitVectUnSetBit(ic->rUsed,R0_IDX);
917             bitVectUnSetBit(ic->rUsed,R1_IDX);          
918
919             getFreePtr(ic,&aop,FALSE);
920             
921             if (options.stack10bit)
922             {
923                 /* I'm not sure what to do here yet... */
924                 /* #STUB */
925                 fprintf(stderr, 
926                         "*** Warning: probably generating bad code for "
927                         "10 bit stack mode.\n");
928             }
929             
930             if (stk) {
931                 pic14_emitcode ("mov","a,_bp");
932                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
933                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
934             } else {
935                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
936             }
937
938             while (sz--) {
939                 pic14_emitcode("pop","acc");
940                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
941                 if (!sz) break;
942                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
943             }
944             op->aop = aop;
945             freeAsmop(op,NULL,ic,TRUE);
946             if (_G.r0Pushed) {
947                 pic14_emitcode("pop","ar0");
948                 _G.r0Pushed--;
949             }
950
951             if (_G.r1Pushed) {
952                 pic14_emitcode("pop","ar1");
953                 _G.r1Pushed--;
954             }       
955         }
956     }
957 #endif
958
959 dealloc:
960     /* all other cases just dealloc */
961     if (op ) {
962         op->aop = NULL;
963         if (IS_SYMOP(op)) {
964             OP_SYMBOL(op)->aop = NULL;    
965             /* if the symbol has a spill */
966             if (SPIL_LOC(op))
967                 SPIL_LOC(op)->aop = NULL;
968         }
969     }
970 }
971
972 /*-----------------------------------------------------------------*/
973 /* aopGet - for fetching value of the aop                          */
974 /*-----------------------------------------------------------------*/
975 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
976 {
977     char *s = buffer ;
978     char *rs;
979
980     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
981     /* offset is greater than
982     size then zero */
983     if (offset > (aop->size - 1) &&
984         aop->type != AOP_LIT)
985         return zero;
986
987     /* depending on type */
988     switch (aop->type) {
989         
990     case AOP_R0:
991     case AOP_R1:
992         DEBUGpic14_emitcode(";","%d",__LINE__);
993         /* if we need to increment it */       
994         while (offset > aop->coff) {        
995             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
996             aop->coff++;
997         }
998         
999         while (offset < aop->coff) {
1000             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1001             aop->coff--;
1002         }
1003         
1004         aop->coff = offset ;
1005         if (aop->paged) {
1006             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1007             return (dname ? "acc" : "a");
1008         }       
1009         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1010         rs = Safe_calloc(1,strlen(s)+1);
1011         strcpy(rs,s);   
1012         return rs;
1013         
1014     case AOP_DPTR:
1015     case AOP_DPTR2:
1016         DEBUGpic14_emitcode(";","%d",__LINE__);
1017     if (aop->type == AOP_DPTR2)
1018     {
1019         genSetDPTR(1);
1020     }
1021     
1022         while (offset > aop->coff) {
1023             pic14_emitcode ("inc","dptr");
1024             aop->coff++;
1025         }
1026         
1027         while (offset < aop->coff) {        
1028             pic14_emitcode("lcall","__decdptr");
1029             aop->coff--;
1030         }
1031         
1032         aop->coff = offset;
1033         if (aop->code) {
1034             pic14_emitcode("clr","a");
1035             pic14_emitcode("movc","a,@a+dptr");
1036         }
1037     else {
1038             pic14_emitcode("movx","a,@dptr");
1039     }
1040             
1041     if (aop->type == AOP_DPTR2)
1042     {
1043         genSetDPTR(0);
1044     }
1045             
1046     return (dname ? "acc" : "a");
1047         
1048         
1049     case AOP_IMMD:
1050         if (bit16) 
1051             sprintf (s,"%s",aop->aopu.aop_immd);
1052         else
1053             if (offset) 
1054                 sprintf(s,"(%s >> %d)",
1055                         aop->aopu.aop_immd,
1056                         offset*8);
1057             else
1058                 sprintf(s,"%s",
1059                         aop->aopu.aop_immd);
1060         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1061         rs = Safe_calloc(1,strlen(s)+1);
1062         strcpy(rs,s);   
1063         return rs;
1064         
1065     case AOP_DIR:
1066       if (offset) {
1067         sprintf(s,"(%s + %d)",
1068                 aop->aopu.aop_dir,
1069                 offset);
1070         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1071       } else
1072             sprintf(s,"%s",aop->aopu.aop_dir);
1073         rs = Safe_calloc(1,strlen(s)+1);
1074         strcpy(rs,s);   
1075         return rs;
1076         
1077     case AOP_REG:
1078       //if (dname) 
1079       //    return aop->aopu.aop_reg[offset]->dname;
1080       //else
1081             return aop->aopu.aop_reg[offset]->name;
1082         
1083     case AOP_CRY:
1084       //pic14_emitcode(";","%d",__LINE__);
1085       return aop->aopu.aop_dir;
1086         
1087     case AOP_ACC:
1088         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1089         return "AOP_accumulator_bug";
1090
1091     case AOP_LIT:
1092         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1093         rs = Safe_calloc(1,strlen(s)+1);
1094         strcpy(rs,s);   
1095         return rs;
1096         
1097     case AOP_STR:
1098         aop->coff = offset ;
1099         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1100             dname)
1101             return "acc";
1102         DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1103         
1104         return aop->aopu.aop_str[offset];
1105         
1106     case AOP_PCODE:
1107       {
1108         pCodeOp *pcop = aop->aopu.pcop;
1109         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1110         if(pcop->name) {
1111           DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1112           //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1113           sprintf(s,"%s", pcop->name);
1114         } else
1115           sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1116
1117       }
1118       rs = Safe_calloc(1,strlen(s)+1);
1119       strcpy(rs,s);   
1120       return rs;
1121
1122     }
1123
1124     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1125            "aopget got unsupported aop->type");
1126     exit(0);
1127 }
1128
1129
1130 /*-----------------------------------------------------------------*/
1131 /* popGetTempReg - create a new temporary pCodeOp                  */
1132 /*-----------------------------------------------------------------*/
1133 pCodeOp *popGetTempReg(void)
1134 {
1135
1136   pCodeOp *pcop;
1137
1138   pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1139   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1140     PCOR(pcop)->r->wasUsed=1;
1141     PCOR(pcop)->r->isFree=0;
1142   }
1143
1144   return pcop;
1145 }
1146
1147 /*-----------------------------------------------------------------*/
1148 /* popGetTempReg - create a new temporary pCodeOp                  */
1149 /*-----------------------------------------------------------------*/
1150 void popReleaseTempReg(pCodeOp *pcop)
1151 {
1152
1153   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1154     PCOR(pcop)->r->isFree = 1;
1155
1156 }
1157 /*-----------------------------------------------------------------*/
1158 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1159 /*-----------------------------------------------------------------*/
1160 pCodeOp *popGetLabel(unsigned int key)
1161 {
1162
1163   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1164
1165   if(key>max_key)
1166     max_key = key;
1167
1168   return newpCodeOpLabel(NULL,key+100+labelOffset);
1169 }
1170
1171 /*-----------------------------------------------------------------*/
1172 /* popCopyReg - copy a pcode operator                              */
1173 /*-----------------------------------------------------------------*/
1174 pCodeOp *popCopyReg(pCodeOpReg *pc)
1175 {
1176   pCodeOpReg *pcor;
1177
1178   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1179   pcor->pcop.type = pc->pcop.type;
1180   if(pc->pcop.name) {
1181     if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1182       fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1183   } else
1184     pcor->pcop.name = NULL;
1185
1186   pcor->r = pc->r;
1187   pcor->rIdx = pc->rIdx;
1188   pcor->r->wasUsed=1;
1189
1190   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1191
1192   return PCOP(pcor);
1193 }
1194 /*-----------------------------------------------------------------*/
1195 /* popGet - asm operator to pcode operator conversion              */
1196 /*-----------------------------------------------------------------*/
1197 pCodeOp *popGetLit(unsigned int lit)
1198 {
1199
1200   return newpCodeOpLit(lit);
1201 }
1202
1203
1204 /*-----------------------------------------------------------------*/
1205 /* popGetImmd - asm operator to pcode immediate conversion         */
1206 /*-----------------------------------------------------------------*/
1207 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1208 {
1209
1210   return newpCodeOpImmd(name, offset,index, 0);
1211 }
1212
1213
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion              */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetWithString(char *str)
1218 {
1219   pCodeOp *pcop;
1220
1221
1222   if(!str) {
1223     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1224     exit (1);
1225   }
1226
1227   pcop = newpCodeOp(str,PO_STR);
1228
1229   return pcop;
1230 }
1231
1232 /*-----------------------------------------------------------------*/
1233 /* popRegFromString -                                              */
1234 /*-----------------------------------------------------------------*/
1235 pCodeOp *popRegFromString(char *str, int size, int offset)
1236 {
1237
1238   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1239   pcop->type = PO_DIR;
1240
1241   DEBUGpic14_emitcode(";","%d",__LINE__);
1242
1243   if(!str)
1244     str = "BAD_STRING";
1245
1246   pcop->name = Safe_calloc(1,strlen(str)+1);
1247   strcpy(pcop->name,str);
1248
1249   //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1250
1251   PCOR(pcop)->r = dirregWithName(pcop->name);
1252   if(PCOR(pcop)->r == NULL) {
1253     //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1254     PCOR(pcop)->r = allocRegByName (pcop->name,size);
1255     DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1256   } else {
1257     DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1258   }
1259   PCOR(pcop)->instance = offset;
1260
1261   return pcop;
1262 }
1263
1264 pCodeOp *popRegFromIdx(int rIdx)
1265 {
1266   pCodeOp *pcop;
1267
1268   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1269                        __FUNCTION__,__LINE__,rIdx);
1270
1271   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1272
1273   PCOR(pcop)->rIdx = rIdx;
1274   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1275   PCOR(pcop)->r->isFree = 0;
1276   PCOR(pcop)->r->wasUsed = 1;
1277
1278   pcop->type = PCOR(pcop)->r->pc_type;
1279
1280
1281   return pcop;
1282 }
1283 /*-----------------------------------------------------------------*/
1284 /* popGet - asm operator to pcode operator conversion              */
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1287 {
1288   //char *s = buffer ;
1289     //char *rs;
1290
1291     pCodeOp *pcop;
1292
1293     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1294     /* offset is greater than
1295     size then zero */
1296
1297     if (offset > (aop->size - 1) &&
1298         aop->type != AOP_LIT)
1299       return NULL;  //zero;
1300
1301     /* depending on type */
1302     switch (aop->type) {
1303         
1304     case AOP_R0:
1305     case AOP_R1:
1306     case AOP_DPTR:
1307     case AOP_DPTR2:
1308     case AOP_ACC:
1309         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1310         return NULL;
1311         
1312     case AOP_IMMD:
1313       DEBUGpic14_emitcode(";","%d",__LINE__);
1314       return popGetImmd(aop->aopu.aop_immd,offset,0);
1315
1316     case AOP_DIR:
1317       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1318 #if 0
1319         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1320         pcop->type = PO_DIR;
1321
1322         /*
1323         if (offset)
1324             sprintf(s,"(%s + %d)",
1325                     aop->aopu.aop_dir,
1326                     offset);
1327         else
1328             sprintf(s,"%s",aop->aopu.aop_dir);
1329         pcop->name = Safe_calloc(1,strlen(s)+1);
1330         strcpy(pcop->name,s);   
1331         */
1332         pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1333         strcpy(pcop->name,aop->aopu.aop_dir);   
1334         PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1335         if(PCOR(pcop)->r == NULL) {
1336           //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1337           PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1338           DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1339         } else {
1340           DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1341         }
1342         PCOR(pcop)->instance = offset;
1343
1344         return pcop;
1345 #endif
1346         
1347     case AOP_REG:
1348       {
1349         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1350
1351         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1352         PCOR(pcop)->rIdx = rIdx;
1353         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1354         PCOR(pcop)->r->wasUsed=1;
1355         PCOR(pcop)->r->isFree=0;
1356
1357         PCOR(pcop)->instance = offset;
1358         pcop->type = PCOR(pcop)->r->pc_type;
1359         //rs = aop->aopu.aop_reg[offset]->name;
1360         //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1361         return pcop;
1362       }
1363
1364     case AOP_CRY:
1365       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1366       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1367       //if(PCOR(pcop)->r == NULL)
1368       //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1369       return pcop;
1370         
1371     case AOP_LIT:
1372       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1373
1374     case AOP_STR:
1375       DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1376       return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1377       /*
1378       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1379       PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1380       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1381       pcop->type = PCOR(pcop)->r->pc_type;
1382       pcop->name = PCOR(pcop)->r->name;
1383
1384       return pcop;
1385       */
1386
1387     case AOP_PCODE:
1388       DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1389                           __LINE__, 
1390                           ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1391       pcop = pCodeOpCopy(aop->aopu.pcop);
1392       PCOI(pcop)->offset = offset;
1393       return pcop;
1394     }
1395
1396     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1397            "popGet got unsupported aop->type");
1398     exit(0);
1399 }
1400 /*-----------------------------------------------------------------*/
1401 /* aopPut - puts a string for a aop                                */
1402 /*-----------------------------------------------------------------*/
1403 void aopPut (asmop *aop, char *s, int offset)
1404 {
1405     char *d = buffer ;
1406     symbol *lbl ;
1407
1408     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1409
1410     if (aop->size && offset > ( aop->size - 1)) {
1411         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1412                "aopPut got offset > aop->size");
1413         exit(0);
1414     }
1415
1416     /* will assign value to value */
1417     /* depending on where it is ofcourse */
1418     switch (aop->type) {
1419     case AOP_DIR:
1420       if (offset) {
1421         sprintf(d,"(%s + %d)",
1422                 aop->aopu.aop_dir,offset);
1423         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1424
1425       } else
1426             sprintf(d,"%s",aop->aopu.aop_dir);
1427         
1428         if (strcmp(d,s)) {
1429           DEBUGpic14_emitcode(";","%d",__LINE__);
1430           if(strcmp(s,"W"))
1431             pic14_emitcode("movf","%s,w",s);
1432           pic14_emitcode("movwf","%s",d);
1433
1434           if(strcmp(s,"W")) {
1435             pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1436             if(offset >= aop->size) {
1437               emitpcode(POC_CLRF,popGet(aop,offset));
1438               break;
1439             } else
1440               emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1441           }
1442
1443           emitpcode(POC_MOVWF,popGet(aop,offset));
1444
1445
1446         }
1447         break;
1448         
1449     case AOP_REG:
1450       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1451         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1452           /*
1453             if (*s == '@'           ||
1454                 strcmp(s,"r0") == 0 ||
1455                 strcmp(s,"r1") == 0 ||
1456                 strcmp(s,"r2") == 0 ||
1457                 strcmp(s,"r3") == 0 ||
1458                 strcmp(s,"r4") == 0 ||
1459                 strcmp(s,"r5") == 0 ||
1460                 strcmp(s,"r6") == 0 || 
1461                 strcmp(s,"r7") == 0 )
1462                 pic14_emitcode("mov","%s,%s  ; %d",
1463                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1464             else
1465           */
1466
1467           if(strcmp(s,"W")==0 )
1468             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1469
1470           pic14_emitcode("movwf","%s",
1471                    aop->aopu.aop_reg[offset]->name);
1472
1473           if(strcmp(s,zero)==0) {
1474             emitpcode(POC_CLRF,popGet(aop,offset));
1475
1476           } else if(strcmp(s,"W")==0) {
1477             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1478             pcop->type = PO_GPR_REGISTER;
1479
1480             PCOR(pcop)->rIdx = -1;
1481             PCOR(pcop)->r = NULL;
1482
1483             DEBUGpic14_emitcode(";","%d",__LINE__);
1484             pcop->name = Safe_strdup(s);
1485             emitpcode(POC_MOVFW,pcop);
1486             emitpcode(POC_MOVWF,popGet(aop,offset));
1487           } else if(strcmp(s,one)==0) {
1488             emitpcode(POC_CLRF,popGet(aop,offset));
1489             emitpcode(POC_INCF,popGet(aop,offset));
1490           } else {
1491             emitpcode(POC_MOVWF,popGet(aop,offset));
1492           }
1493         }
1494         break;
1495         
1496     case AOP_DPTR:
1497     case AOP_DPTR2:
1498     
1499     if (aop->type == AOP_DPTR2)
1500     {
1501         genSetDPTR(1);
1502     }
1503     
1504         if (aop->code) {
1505             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1506                    "aopPut writting to code space");
1507             exit(0);
1508         }
1509         
1510         while (offset > aop->coff) {
1511             aop->coff++;
1512             pic14_emitcode ("inc","dptr");
1513         }
1514         
1515         while (offset < aop->coff) {
1516             aop->coff-- ;
1517             pic14_emitcode("lcall","__decdptr");
1518         }
1519         
1520         aop->coff = offset;
1521         
1522         /* if not in accumulater */
1523         MOVA(s);        
1524         
1525         pic14_emitcode ("movx","@dptr,a");
1526         
1527     if (aop->type == AOP_DPTR2)
1528     {
1529         genSetDPTR(0);
1530     }
1531         break;
1532         
1533     case AOP_R0:
1534     case AOP_R1:
1535         while (offset > aop->coff) {
1536             aop->coff++;
1537             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1538         }
1539         while (offset < aop->coff) {
1540             aop->coff-- ;
1541             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1542         }
1543         aop->coff = offset;
1544         
1545         if (aop->paged) {
1546             MOVA(s);           
1547             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1548             
1549         } else
1550             if (*s == '@') {
1551                 MOVA(s);
1552                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1553             } else
1554                 if (strcmp(s,"r0") == 0 ||
1555                     strcmp(s,"r1") == 0 ||
1556                     strcmp(s,"r2") == 0 ||
1557                     strcmp(s,"r3") == 0 ||
1558                     strcmp(s,"r4") == 0 ||
1559                     strcmp(s,"r5") == 0 ||
1560                     strcmp(s,"r6") == 0 || 
1561                     strcmp(s,"r7") == 0 ) {
1562                     char buffer[10];
1563                     sprintf(buffer,"a%s",s);
1564                     pic14_emitcode("mov","@%s,%s",
1565                              aop->aopu.aop_ptr->name,buffer);
1566                 } else
1567                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1568         
1569         break;
1570         
1571     case AOP_STK:
1572         if (strcmp(s,"a") == 0)
1573             pic14_emitcode("push","acc");
1574         else
1575             pic14_emitcode("push","%s",s);
1576         
1577         break;
1578         
1579     case AOP_CRY:
1580         /* if bit variable */
1581         if (!aop->aopu.aop_dir) {
1582             pic14_emitcode("clr","a");
1583             pic14_emitcode("rlc","a");
1584         } else {
1585             if (s == zero) 
1586                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1587             else
1588                 if (s == one)
1589                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1590                 else
1591                     if (!strcmp(s,"c"))
1592                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1593                     else {
1594                         lbl = newiTempLabel(NULL);
1595                         
1596                         if (strcmp(s,"a")) {
1597                             MOVA(s);
1598                         }
1599                         pic14_emitcode("clr","c");
1600                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1601                         pic14_emitcode("cpl","c");
1602                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1603                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1604                     }
1605         }
1606         break;
1607         
1608     case AOP_STR:
1609         aop->coff = offset;
1610         if (strcmp(aop->aopu.aop_str[offset],s))
1611             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1612         break;
1613         
1614     case AOP_ACC:
1615         aop->coff = offset;
1616         if (!offset && (strcmp(s,"acc") == 0))
1617             break;
1618         
1619         if (strcmp(aop->aopu.aop_str[offset],s))
1620             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1621         break;
1622
1623     default :
1624         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1625                "aopPut got unsupported aop->type");
1626         exit(0);    
1627     }    
1628
1629 }
1630
1631 /*-----------------------------------------------------------------*/
1632 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1633 /*-----------------------------------------------------------------*/
1634 void mov2w (asmop *aop, int offset)
1635 {
1636
1637   if(!aop)
1638     return;
1639
1640   DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1641
1642   if ( aop->type == AOP_PCODE ||
1643        aop->type == AOP_LIT )
1644     emitpcode(POC_MOVLW,popGet(aop,offset));
1645   else
1646     emitpcode(POC_MOVFW,popGet(aop,offset));
1647
1648 }
1649
1650 /*-----------------------------------------------------------------*/
1651 /* reAdjustPreg - points a register back to where it should        */
1652 /*-----------------------------------------------------------------*/
1653 static void reAdjustPreg (asmop *aop)
1654 {
1655     int size ;
1656
1657     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1658     aop->coff = 0;
1659     if ((size = aop->size) <= 1)
1660         return ;
1661     size-- ;
1662     switch (aop->type) {
1663         case AOP_R0 :
1664         case AOP_R1 :
1665             while (size--)
1666                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1667             break;          
1668         case AOP_DPTR :
1669         case AOP_DPTR2:
1670             if (aop->type == AOP_DPTR2)
1671             {
1672                 genSetDPTR(1);
1673             } 
1674             while (size--)
1675             {
1676                 pic14_emitcode("lcall","__decdptr");
1677             }
1678                 
1679             if (aop->type == AOP_DPTR2)
1680             {
1681                 genSetDPTR(0);
1682             }                
1683             break;  
1684
1685     }   
1686
1687 }
1688
1689 /*-----------------------------------------------------------------*/
1690 /* genNotFloat - generates not for float operations              */
1691 /*-----------------------------------------------------------------*/
1692 static void genNotFloat (operand *op, operand *res)
1693 {
1694     int size, offset;
1695     char *l;
1696     symbol *tlbl ;
1697
1698     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1699     /* we will put 127 in the first byte of 
1700     the result */
1701     aopPut(AOP(res),"#127",0);
1702     size = AOP_SIZE(op) - 1;
1703     offset = 1;
1704
1705     l = aopGet(op->aop,offset++,FALSE,FALSE);
1706     MOVA(l);    
1707
1708     while(size--) {
1709         pic14_emitcode("orl","a,%s",
1710                  aopGet(op->aop,
1711                         offset++,FALSE,FALSE));
1712     }
1713     tlbl = newiTempLabel(NULL);
1714
1715     tlbl = newiTempLabel(NULL);
1716     aopPut(res->aop,one,1);
1717     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1718     aopPut(res->aop,zero,1);
1719     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1720
1721     size = res->aop->size - 2;
1722     offset = 2;    
1723     /* put zeros in the rest */
1724     while (size--) 
1725         aopPut(res->aop,zero,offset++);
1726 }
1727
1728 #if 0
1729 /*-----------------------------------------------------------------*/
1730 /* opIsGptr: returns non-zero if the passed operand is             */   
1731 /* a generic pointer type.                                         */
1732 /*-----------------------------------------------------------------*/ 
1733 static int opIsGptr(operand *op)
1734 {
1735     sym_link *type = operandType(op);
1736     
1737     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1738     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1739     {
1740         return 1;
1741     }
1742     return 0;        
1743 }
1744 #endif
1745
1746 /*-----------------------------------------------------------------*/
1747 /* pic14_getDataSize - get the operand data size                         */
1748 /*-----------------------------------------------------------------*/
1749 int pic14_getDataSize(operand *op)
1750 {
1751     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1752
1753
1754     return AOP_SIZE(op);
1755
1756     // tsd- in the pic port, the genptr size is 1, so this code here
1757     // fails. ( in the 8051 port, the size was 4).
1758 #if 0
1759     int size;
1760     size = AOP_SIZE(op);
1761     if (size == GPTRSIZE)
1762     {
1763         sym_link *type = operandType(op);
1764         if (IS_GENPTR(type))
1765         {
1766             /* generic pointer; arithmetic operations
1767              * should ignore the high byte (pointer type).
1768              */
1769             size--;
1770     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1771         }
1772     }
1773     return size;
1774 #endif
1775 }
1776
1777 /*-----------------------------------------------------------------*/
1778 /* pic14_outAcc - output Acc                                             */
1779 /*-----------------------------------------------------------------*/
1780 void pic14_outAcc(operand *result)
1781 {
1782   int size,offset;
1783   DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1784   DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1785
1786
1787   size = pic14_getDataSize(result);
1788   if(size){
1789     emitpcode(POC_MOVWF,popGet(AOP(result),0));
1790     size--;
1791     offset = 1;
1792     /* unsigned or positive */
1793     while(size--)
1794       emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1795   }
1796
1797 }
1798
1799 /*-----------------------------------------------------------------*/
1800 /* pic14_outBitC - output a bit C                                        */
1801 /*-----------------------------------------------------------------*/
1802 void pic14_outBitC(operand *result)
1803 {
1804
1805     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1806     /* if the result is bit */
1807     if (AOP_TYPE(result) == AOP_CRY) 
1808         aopPut(AOP(result),"c",0);
1809     else {
1810         pic14_emitcode("clr","a  ; %d", __LINE__);
1811         pic14_emitcode("rlc","a");
1812         pic14_outAcc(result);
1813     }
1814 }
1815
1816 /*-----------------------------------------------------------------*/
1817 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1818 /*-----------------------------------------------------------------*/
1819 void pic14_toBoolean(operand *oper)
1820 {
1821     int size = AOP_SIZE(oper) - 1;
1822     int offset = 1;
1823
1824     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1825
1826     if ( AOP_TYPE(oper) != AOP_ACC) {
1827       emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1828     }
1829     while (size--) {
1830       emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1831     }
1832 }
1833
1834
1835 /*-----------------------------------------------------------------*/
1836 /* genNot - generate code for ! operation                          */
1837 /*-----------------------------------------------------------------*/
1838 static void genNot (iCode *ic)
1839 {
1840   symbol *tlbl;
1841   sym_link *optype = operandType(IC_LEFT(ic));
1842   int size;
1843
1844   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1845   /* assign asmOps to operand & result */
1846   aopOp (IC_LEFT(ic),ic,FALSE);
1847   aopOp (IC_RESULT(ic),ic,TRUE);
1848
1849   DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1850   /* if in bit space then a special case */
1851   if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1852     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1853       emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1854       emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1855     } else {
1856       emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1857       emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1858       emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1859     }
1860     goto release;
1861   }
1862
1863   /* if type float then do float */
1864   if (IS_FLOAT(optype)) {
1865     genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1866     goto release;
1867   }
1868
1869   size = AOP_SIZE(IC_RESULT(ic));
1870   if(size == 1) {
1871     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1872     emitpcode(POC_ANDLW,popGetLit(1));
1873     emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1874     goto release;
1875   }
1876   pic14_toBoolean(IC_LEFT(ic));
1877
1878   tlbl = newiTempLabel(NULL);
1879   pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1880   pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1881   pic14_outBitC(IC_RESULT(ic));
1882
1883  release:    
1884   /* release the aops */
1885   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1886   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1887 }
1888
1889
1890 /*-----------------------------------------------------------------*/
1891 /* genCpl - generate code for complement                           */
1892 /*-----------------------------------------------------------------*/
1893 static void genCpl (iCode *ic)
1894 {
1895     int offset = 0;
1896     int size ;
1897
1898
1899     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1900     /* assign asmOps to operand & result */
1901     aopOp (IC_LEFT(ic),ic,FALSE);
1902     aopOp (IC_RESULT(ic),ic,TRUE);
1903
1904     /* if both are in bit space then 
1905     a special case */
1906     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1907         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1908
1909         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1910         pic14_emitcode("cpl","c"); 
1911         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1912         goto release; 
1913     } 
1914
1915     size = AOP_SIZE(IC_RESULT(ic));
1916     while (size--) {
1917         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1918         MOVA(l);       
1919         pic14_emitcode("cpl","a");
1920         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1921     }
1922
1923
1924 release:
1925     /* release the aops */
1926     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1927     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1928 }
1929
1930 /*-----------------------------------------------------------------*/
1931 /* genUminusFloat - unary minus for floating points                */
1932 /*-----------------------------------------------------------------*/
1933 static void genUminusFloat(operand *op,operand *result)
1934 {
1935     int size ,offset =0 ;
1936     char *l;
1937
1938     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1939     /* for this we just need to flip the 
1940     first it then copy the rest in place */
1941     size = AOP_SIZE(op) - 1;
1942     l = aopGet(AOP(op),3,FALSE,FALSE);
1943
1944     MOVA(l);    
1945
1946     pic14_emitcode("cpl","acc.7");
1947     aopPut(AOP(result),"a",3);    
1948
1949     while(size--) {
1950         aopPut(AOP(result),
1951                aopGet(AOP(op),offset,FALSE,FALSE),
1952                offset);
1953         offset++;
1954     }          
1955 }
1956
1957 /*-----------------------------------------------------------------*/
1958 /* genUminus - unary minus code generation                         */
1959 /*-----------------------------------------------------------------*/
1960 static void genUminus (iCode *ic)
1961 {
1962   int size, i;
1963   sym_link *optype, *rtype;
1964
1965
1966   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1967   /* assign asmops */
1968   aopOp(IC_LEFT(ic),ic,FALSE);
1969   aopOp(IC_RESULT(ic),ic,TRUE);
1970
1971   /* if both in bit space then special
1972      case */
1973   if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1974       AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1975
1976     emitpcode(POC_BCF,   popGet(AOP(IC_RESULT(ic)),0));
1977     emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1978     emitpcode(POC_BSF,   popGet(AOP(IC_RESULT(ic)),0));
1979
1980     goto release; 
1981   } 
1982
1983   optype = operandType(IC_LEFT(ic));
1984   rtype = operandType(IC_RESULT(ic));
1985
1986   /* if float then do float stuff */
1987   if (IS_FLOAT(optype)) {
1988     genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1989     goto release;
1990   }
1991
1992   /* otherwise subtract from zero by taking the 2's complement */
1993   size = AOP_SIZE(IC_LEFT(ic));
1994
1995   for(i=0; i<size; i++) {
1996     if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1997       emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1998     else {
1999       emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2000       emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2001     }
2002   }
2003
2004   emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
2005   for(i=1; i<size; i++) {
2006     emitSKPNZ;
2007     emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
2008   }
2009
2010  release:
2011   /* release the aops */
2012   freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2013   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
2014 }
2015
2016 /*-----------------------------------------------------------------*/
2017 /* saveRegisters - will look for a call and save the registers     */
2018 /*-----------------------------------------------------------------*/
2019 static void saveRegisters(iCode *lic) 
2020 {
2021     int i;
2022     iCode *ic;
2023     bitVect *rsave;
2024     sym_link *dtype;
2025
2026     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2027     /* look for call */
2028     for (ic = lic ; ic ; ic = ic->next) 
2029         if (ic->op == CALL || ic->op == PCALL)
2030             break;
2031
2032     if (!ic) {
2033         fprintf(stderr,"found parameter push with no function call\n");
2034         return ;
2035     }
2036
2037     /* if the registers have been saved already then
2038     do nothing */
2039     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2040         return ;
2041
2042     /* find the registers in use at this time 
2043     and push them away to safety */
2044     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2045                           ic->rUsed);
2046
2047     ic->regsSaved = 1;
2048     if (options.useXstack) {
2049         if (bitVectBitValue(rsave,R0_IDX))
2050             pic14_emitcode("mov","b,r0");
2051         pic14_emitcode("mov","r0,%s",spname);
2052         for (i = 0 ; i < pic14_nRegs ; i++) {
2053             if (bitVectBitValue(rsave,i)) {
2054                 if (i == R0_IDX)
2055                     pic14_emitcode("mov","a,b");
2056                 else
2057                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2058                 pic14_emitcode("movx","@r0,a");
2059                 pic14_emitcode("inc","r0");
2060             }
2061         }
2062         pic14_emitcode("mov","%s,r0",spname);
2063         if (bitVectBitValue(rsave,R0_IDX))
2064             pic14_emitcode("mov","r0,b");           
2065     }// else
2066     //for (i = 0 ; i < pic14_nRegs ; i++) {
2067     //    if (bitVectBitValue(rsave,i))
2068     //  pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2069     //}
2070
2071     dtype = operandType(IC_LEFT(ic));
2072     if (currFunc && dtype && 
2073         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2074         IFFUNC_ISISR(currFunc->type) &&
2075         !ic->bankSaved) 
2076
2077         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2078
2079 }
2080 /*-----------------------------------------------------------------*/
2081 /* unsaveRegisters - pop the pushed registers                      */
2082 /*-----------------------------------------------------------------*/
2083 static void unsaveRegisters (iCode *ic)
2084 {
2085     int i;
2086     bitVect *rsave;
2087
2088     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2089     /* find the registers in use at this time 
2090     and push them away to safety */
2091     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2092                           ic->rUsed);
2093     
2094     if (options.useXstack) {
2095         pic14_emitcode("mov","r0,%s",spname);   
2096         for (i =  pic14_nRegs ; i >= 0 ; i--) {
2097             if (bitVectBitValue(rsave,i)) {
2098                 pic14_emitcode("dec","r0");
2099                 pic14_emitcode("movx","a,@r0");
2100                 if (i == R0_IDX)
2101                     pic14_emitcode("mov","b,a");
2102                 else
2103                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2104             }       
2105
2106         }
2107         pic14_emitcode("mov","%s,r0",spname);
2108         if (bitVectBitValue(rsave,R0_IDX))
2109             pic14_emitcode("mov","r0,b");
2110     } //else
2111     //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2112     //    if (bitVectBitValue(rsave,i))
2113     //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2114     //}
2115
2116 }  
2117
2118
2119 /*-----------------------------------------------------------------*/
2120 /* pushSide -                                                      */
2121 /*-----------------------------------------------------------------*/
2122 static void pushSide(operand * oper, int size)
2123 {
2124 #if 0
2125         int offset = 0;
2126     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2127         while (size--) {
2128                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2129                 if (AOP_TYPE(oper) != AOP_REG &&
2130                     AOP_TYPE(oper) != AOP_DIR &&
2131                     strcmp(l,"a") ) {
2132                         pic14_emitcode("mov","a,%s",l);
2133                         pic14_emitcode("push","acc");
2134                 } else
2135                         pic14_emitcode("push","%s",l);
2136         }
2137 #endif
2138 }
2139
2140 /*-----------------------------------------------------------------*/
2141 /* assignResultValue -                                             */
2142 /*-----------------------------------------------------------------*/
2143 static void assignResultValue(operand * oper)
2144 {
2145   int size = AOP_SIZE(oper);
2146
2147   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2148
2149   DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2150
2151   if(!GpsuedoStkPtr) {
2152     /* The last byte in the assignment is in W */
2153     size--;
2154     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2155     GpsuedoStkPtr++;
2156   }
2157
2158   while (size--) {
2159     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2160     GpsuedoStkPtr++;
2161     emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2162   }
2163 }
2164
2165
2166 /*-----------------------------------------------------------------*/
2167 /* genIpush - genrate code for pushing this gets a little complex  */
2168 /*-----------------------------------------------------------------*/
2169 static void genIpush (iCode *ic)
2170 {
2171
2172   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2173 #if 0
2174     int size, offset = 0 ;
2175     char *l;
2176
2177
2178     /* if this is not a parm push : ie. it is spill push 
2179     and spill push is always done on the local stack */
2180     if (!ic->parmPush) {
2181
2182         /* and the item is spilt then do nothing */
2183         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2184             return ;
2185
2186         aopOp(IC_LEFT(ic),ic,FALSE);
2187         size = AOP_SIZE(IC_LEFT(ic));
2188         /* push it on the stack */
2189         while(size--) {
2190             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2191             if (*l == '#') {
2192                 MOVA(l);
2193                 l = "acc";
2194             }
2195             pic14_emitcode("push","%s",l);
2196         }
2197         return ;        
2198     }
2199
2200     /* this is a paramter push: in this case we call
2201     the routine to find the call and save those
2202     registers that need to be saved */   
2203     saveRegisters(ic);
2204
2205     /* then do the push */
2206     aopOp(IC_LEFT(ic),ic,FALSE);
2207
2208
2209         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2210     size = AOP_SIZE(IC_LEFT(ic));
2211
2212     while (size--) {
2213         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2214         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2215             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2216             strcmp(l,"a") ) {
2217             pic14_emitcode("mov","a,%s",l);
2218             pic14_emitcode("push","acc");
2219         } else
2220             pic14_emitcode("push","%s",l);
2221     }       
2222
2223     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2224 #endif
2225 }
2226
2227 /*-----------------------------------------------------------------*/
2228 /* genIpop - recover the registers: can happen only for spilling   */
2229 /*-----------------------------------------------------------------*/
2230 static void genIpop (iCode *ic)
2231 {
2232   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2233 #if 0
2234     int size,offset ;
2235
2236
2237     /* if the temp was not pushed then */
2238     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2239         return ;
2240
2241     aopOp(IC_LEFT(ic),ic,FALSE);
2242     size = AOP_SIZE(IC_LEFT(ic));
2243     offset = (size-1);
2244     while (size--) 
2245         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2246                                    FALSE,TRUE));
2247
2248     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2249 #endif
2250 }
2251
2252 /*-----------------------------------------------------------------*/
2253 /* unsaverbank - restores the resgister bank from stack            */
2254 /*-----------------------------------------------------------------*/
2255 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2256 {
2257   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2258 #if 0
2259     int i;
2260     asmop *aop ;
2261     regs *r = NULL;
2262
2263     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2264     if (popPsw) {
2265         if (options.useXstack) {
2266             aop = newAsmop(0);
2267             r = getFreePtr(ic,&aop,FALSE);
2268             
2269             
2270             pic14_emitcode("mov","%s,_spx",r->name);
2271             pic14_emitcode("movx","a,@%s",r->name);
2272             pic14_emitcode("mov","psw,a");
2273             pic14_emitcode("dec","%s",r->name);
2274             
2275         }else
2276             pic14_emitcode ("pop","psw");
2277     }
2278
2279     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2280         if (options.useXstack) {       
2281             pic14_emitcode("movx","a,@%s",r->name);
2282             //pic14_emitcode("mov","(%s+%d),a",
2283             //       regspic14[i].base,8*bank+regspic14[i].offset);
2284             pic14_emitcode("dec","%s",r->name);
2285
2286         } else 
2287           pic14_emitcode("pop",""); //"(%s+%d)",
2288         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2289     }
2290
2291     if (options.useXstack) {
2292
2293         pic14_emitcode("mov","_spx,%s",r->name);
2294         freeAsmop(NULL,aop,ic,TRUE);
2295
2296     }
2297 #endif 
2298 }
2299
2300 /*-----------------------------------------------------------------*/
2301 /* saverbank - saves an entire register bank on the stack          */
2302 /*-----------------------------------------------------------------*/
2303 static void saverbank (int bank, iCode *ic, bool pushPsw)
2304 {
2305   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2306 #if 0
2307     int i;
2308     asmop *aop ;
2309     regs *r = NULL;
2310
2311     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2312     if (options.useXstack) {
2313
2314         aop = newAsmop(0);
2315         r = getFreePtr(ic,&aop,FALSE);  
2316         pic14_emitcode("mov","%s,_spx",r->name);
2317
2318     }
2319
2320     for (i = 0 ; i < pic14_nRegs ;i++) {
2321         if (options.useXstack) {
2322             pic14_emitcode("inc","%s",r->name);
2323             //pic14_emitcode("mov","a,(%s+%d)",
2324             //         regspic14[i].base,8*bank+regspic14[i].offset);
2325             pic14_emitcode("movx","@%s,a",r->name);           
2326         } else 
2327           pic14_emitcode("push","");// "(%s+%d)",
2328                      //regspic14[i].base,8*bank+regspic14[i].offset);
2329     }
2330     
2331     if (pushPsw) {
2332         if (options.useXstack) {
2333             pic14_emitcode("mov","a,psw");
2334             pic14_emitcode("movx","@%s,a",r->name);     
2335             pic14_emitcode("inc","%s",r->name);
2336             pic14_emitcode("mov","_spx,%s",r->name);       
2337             freeAsmop (NULL,aop,ic,TRUE);
2338             
2339         } else
2340             pic14_emitcode("push","psw");
2341         
2342         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2343     }
2344     ic->bankSaved = 1;
2345 #endif
2346 }
2347
2348 /*-----------------------------------------------------------------*/
2349 /* genCall - generates a call statement                            */
2350 /*-----------------------------------------------------------------*/
2351 static void genCall (iCode *ic)
2352 {
2353   sym_link *dtype;   
2354
2355   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2356
2357   /* if caller saves & we have not saved then */
2358   if (!ic->regsSaved)
2359     saveRegisters(ic);
2360
2361   /* if we are calling a function that is not using
2362      the same register bank then we need to save the
2363      destination registers on the stack */
2364   dtype = operandType(IC_LEFT(ic));
2365   if (currFunc && dtype && 
2366       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2367       IFFUNC_ISISR(currFunc->type) &&
2368       !ic->bankSaved) 
2369
2370     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2371
2372   /* if send set is not empty the assign */
2373   if (_G.sendSet) {
2374     iCode *sic;
2375     /* For the Pic port, there is no data stack.
2376      * So parameters passed to functions are stored
2377      * in registers. (The pCode optimizer will get
2378      * rid of most of these :).
2379      */
2380     int psuedoStkPtr=-1; 
2381     int firstTimeThruLoop = 1;
2382
2383     _G.sendSet = reverseSet(_G.sendSet);
2384
2385     /* First figure how many parameters are getting passed */
2386     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2387          sic = setNextItem(_G.sendSet)) {
2388
2389       aopOp(IC_LEFT(sic),sic,FALSE);
2390       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2391       freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2392     }
2393
2394     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2395          sic = setNextItem(_G.sendSet)) {
2396       int size, offset = 0;
2397
2398       aopOp(IC_LEFT(sic),sic,FALSE);
2399       size = AOP_SIZE(IC_LEFT(sic));
2400
2401       while (size--) {
2402         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2403                              AopType(AOP_TYPE(IC_LEFT(sic))));
2404
2405         if(!firstTimeThruLoop) {
2406           /* If this is not the first time we've been through the loop
2407            * then we need to save the parameter in a temporary
2408            * register. The last byte of the last parameter is
2409            * passed in W. */
2410           emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2411
2412         }
2413         firstTimeThruLoop=0;
2414
2415         //if (strcmp(l,fReturn[offset])) {
2416         mov2w (AOP(IC_LEFT(sic)),  offset);
2417 /*
2418         if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2419              ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2420           emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2421         else
2422           emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2423 */
2424         //}
2425         offset++;
2426       }
2427       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2428     }
2429     _G.sendSet = NULL;
2430   }
2431   /* make the call */
2432   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2433                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2434                                       OP_SYMBOL(IC_LEFT(ic))->name));
2435
2436   GpsuedoStkPtr=0;
2437   /* if we need assign a result value */
2438   if ((IS_ITEMP(IC_RESULT(ic)) && 
2439        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2440         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2441       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2442
2443     _G.accInUse++;
2444     aopOp(IC_RESULT(ic),ic,FALSE);
2445     _G.accInUse--;
2446
2447     assignResultValue(IC_RESULT(ic));
2448
2449     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2450                          AopType(AOP_TYPE(IC_RESULT(ic))));
2451                 
2452     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2453   }
2454
2455   /* adjust the stack for parameters if 
2456      required */
2457   if (ic->parmBytes) {
2458     int i;
2459     if (ic->parmBytes > 3) {
2460       pic14_emitcode("mov","a,%s",spname);
2461       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2462       pic14_emitcode("mov","%s,a",spname);
2463     } else 
2464       for ( i = 0 ; i <  ic->parmBytes ;i++)
2465         pic14_emitcode("dec","%s",spname);
2466
2467   }
2468
2469   /* if register bank was saved then pop them */
2470   if (ic->bankSaved)
2471     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2472
2473   /* if we hade saved some registers then unsave them */
2474   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2475     unsaveRegisters (ic);
2476
2477
2478 }
2479
2480 /*-----------------------------------------------------------------*/
2481 /* genPcall - generates a call by pointer statement                */
2482 /*-----------------------------------------------------------------*/
2483 static void genPcall (iCode *ic)
2484 {
2485     sym_link *dtype;
2486     symbol *rlbl = newiTempLabel(NULL);
2487
2488
2489     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2490     /* if caller saves & we have not saved then */
2491     if (!ic->regsSaved)
2492         saveRegisters(ic);
2493
2494     /* if we are calling a function that is not using
2495     the same register bank then we need to save the
2496     destination registers on the stack */
2497     dtype = operandType(IC_LEFT(ic));
2498     if (currFunc && dtype && 
2499         IFFUNC_ISISR(currFunc->type) &&
2500         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2501         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2502
2503
2504     /* push the return address on to the stack */
2505     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2506     pic14_emitcode("push","acc");    
2507     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2508     pic14_emitcode("push","acc");
2509     
2510     if (options.model == MODEL_FLAT24)
2511     {
2512         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2513         pic14_emitcode("push","acc");    
2514     }
2515
2516     /* now push the calling address */
2517     aopOp(IC_LEFT(ic),ic,FALSE);
2518
2519     pushSide(IC_LEFT(ic), FPTRSIZE);
2520
2521     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2522
2523     /* if send set is not empty the assign */
2524     if (_G.sendSet) {
2525         iCode *sic ;
2526
2527         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2528              sic = setNextItem(_G.sendSet)) {
2529             int size, offset = 0;
2530             aopOp(IC_LEFT(sic),sic,FALSE);
2531             size = AOP_SIZE(IC_LEFT(sic));
2532             while (size--) {
2533                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2534                                 FALSE,FALSE);
2535                 if (strcmp(l,fReturn[offset]))
2536                     pic14_emitcode("mov","%s,%s",
2537                              fReturn[offset],
2538                              l);
2539                 offset++;
2540             }
2541             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2542         }
2543         _G.sendSet = NULL;
2544     }
2545
2546     pic14_emitcode("ret","");
2547     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2548
2549
2550     /* if we need assign a result value */
2551     if ((IS_ITEMP(IC_RESULT(ic)) &&
2552          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2553           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2554         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2555
2556         _G.accInUse++;
2557         aopOp(IC_RESULT(ic),ic,FALSE);
2558         _G.accInUse--;
2559         
2560         assignResultValue(IC_RESULT(ic));
2561
2562         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2563     }
2564
2565     /* adjust the stack for parameters if 
2566     required */
2567     if (ic->parmBytes) {
2568         int i;
2569         if (ic->parmBytes > 3) {
2570             pic14_emitcode("mov","a,%s",spname);
2571             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2572             pic14_emitcode("mov","%s,a",spname);
2573         } else 
2574             for ( i = 0 ; i <  ic->parmBytes ;i++)
2575                 pic14_emitcode("dec","%s",spname);
2576
2577     }
2578
2579     /* if register bank was saved then unsave them */
2580     if (currFunc && dtype && 
2581         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2582         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2583
2584     /* if we hade saved some registers then
2585     unsave them */
2586     if (ic->regsSaved)
2587         unsaveRegisters (ic);
2588
2589 }
2590
2591 /*-----------------------------------------------------------------*/
2592 /* resultRemat - result  is rematerializable                       */
2593 /*-----------------------------------------------------------------*/
2594 static int resultRemat (iCode *ic)
2595 {
2596   //    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2597   if (SKIP_IC(ic) || ic->op == IFX)
2598     return 0;
2599
2600   if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2601     symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2602     if (sym->remat && !POINTER_SET(ic)) 
2603       return 1;
2604   }
2605
2606   return 0;
2607 }
2608
2609 #if defined(__BORLANDC__) || defined(_MSC_VER)
2610 #define STRCASECMP stricmp
2611 #else
2612 #define STRCASECMP strcasecmp
2613 #endif
2614
2615 #if 0
2616 /*-----------------------------------------------------------------*/
2617 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2618 /*-----------------------------------------------------------------*/
2619 static bool inExcludeList(char *s)
2620 {
2621   DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2622     int i =0;
2623     
2624     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2625     if (options.excludeRegs[i] &&
2626     STRCASECMP(options.excludeRegs[i],"none") == 0)
2627         return FALSE ;
2628
2629     for ( i = 0 ; options.excludeRegs[i]; i++) {
2630         if (options.excludeRegs[i] &&
2631         STRCASECMP(s,options.excludeRegs[i]) == 0)
2632             return TRUE;
2633     }
2634     return FALSE ;
2635 }
2636 #endif
2637
2638 /*-----------------------------------------------------------------*/
2639 /* genFunction - generated code for function entry                 */
2640 /*-----------------------------------------------------------------*/
2641 static void genFunction (iCode *ic)
2642 {
2643     symbol *sym;
2644     sym_link *ftype;
2645
2646     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2647
2648     labelOffset += (max_key+4);
2649     max_key=0;
2650     GpsuedoStkPtr=0;
2651     _G.nRegsSaved = 0;
2652     /* create the function header */
2653     pic14_emitcode(";","-----------------------------------------");
2654     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2655     pic14_emitcode(";","-----------------------------------------");
2656
2657     pic14_emitcode("","%s:",sym->rname);
2658     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2659
2660     ftype = operandType(IC_LEFT(ic));
2661
2662     /* if critical function then turn interrupts off */
2663     if (IFFUNC_ISCRITICAL(ftype))
2664         pic14_emitcode("clr","ea");
2665
2666     /* here we need to generate the equates for the
2667        register bank if required */
2668 #if 0
2669     if (FUNC_REGBANK(ftype) != rbank) {
2670         int i ;
2671
2672         rbank = FUNC_REGBANK(ftype);
2673         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2674             if (strcmp(regspic14[i].base,"0") == 0)
2675                 pic14_emitcode("","%s = 0x%02x",
2676                          regspic14[i].dname,
2677                          8*rbank+regspic14[i].offset);
2678             else
2679                 pic14_emitcode ("","%s = %s + 0x%02x",
2680                           regspic14[i].dname,
2681                           regspic14[i].base,
2682                           8*rbank+regspic14[i].offset);
2683         }
2684     }
2685 #endif
2686
2687     /* if this is an interrupt service routine then
2688     save acc, b, dpl, dph  */
2689     if (IFFUNC_ISISR(sym->type)) {
2690       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2691       emitpcodeNULLop(POC_NOP);
2692       emitpcodeNULLop(POC_NOP);
2693       emitpcodeNULLop(POC_NOP);
2694       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2695       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2696       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2697       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2698
2699       pBlockConvert2ISR(pb);
2700 #if 0  
2701         if (!inExcludeList("acc"))          
2702             pic14_emitcode ("push","acc");      
2703         if (!inExcludeList("b"))
2704             pic14_emitcode ("push","b");
2705         if (!inExcludeList("dpl"))
2706             pic14_emitcode ("push","dpl");
2707         if (!inExcludeList("dph"))
2708             pic14_emitcode ("push","dph");
2709         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2710         {
2711             pic14_emitcode ("push", "dpx");
2712             /* Make sure we're using standard DPTR */
2713             pic14_emitcode ("push", "dps");
2714             pic14_emitcode ("mov", "dps, #0x00");
2715             if (options.stack10bit)
2716             {   
2717                 /* This ISR could conceivably use DPTR2. Better save it. */
2718                 pic14_emitcode ("push", "dpl1");
2719                 pic14_emitcode ("push", "dph1");
2720                 pic14_emitcode ("push", "dpx1");
2721             }
2722         }
2723         /* if this isr has no bank i.e. is going to
2724            run with bank 0 , then we need to save more
2725            registers :-) */
2726         if (!FUNC_REGBANK(sym->type)) {
2727
2728             /* if this function does not call any other
2729                function then we can be economical and
2730                save only those registers that are used */
2731             if (! IFFUNC_HASFCALL(sym->type)) {
2732                 int i;
2733
2734                 /* if any registers used */
2735                 if (sym->regsUsed) {
2736                     /* save the registers used */
2737                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2738                         if (bitVectBitValue(sym->regsUsed,i) ||
2739                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2740                           pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
2741                     }
2742                 }
2743                 
2744             } else {
2745                 /* this function has  a function call cannot
2746                    determines register usage so we will have the
2747                    entire bank */
2748                 saverbank(0,ic,FALSE);
2749             }       
2750         }
2751 #endif
2752     } else {
2753         /* if callee-save to be used for this function
2754            then save the registers being used in this function */
2755         if (IFFUNC_CALLEESAVES(sym->type)) {
2756             int i;
2757             
2758             /* if any registers used */
2759             if (sym->regsUsed) {
2760                 /* save the registers used */
2761                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2762                     if (bitVectBitValue(sym->regsUsed,i) ||
2763                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2764                       //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2765                         _G.nRegsSaved++;
2766                     }
2767                 }
2768             }
2769         }
2770     }
2771
2772     /* set the register bank to the desired value */
2773     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2774         pic14_emitcode("push","psw");
2775         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2776     }
2777
2778     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2779
2780         if (options.useXstack) {
2781             pic14_emitcode("mov","r0,%s",spname);
2782             pic14_emitcode("mov","a,_bp");
2783             pic14_emitcode("movx","@r0,a");
2784             pic14_emitcode("inc","%s",spname);
2785         }
2786         else
2787         {
2788             /* set up the stack */
2789             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2790         }
2791         pic14_emitcode ("mov","_bp,%s",spname);
2792     }
2793
2794     /* adjust the stack for the function */
2795     if (sym->stack) {
2796
2797         int i = sym->stack;
2798         if (i > 256 ) 
2799             werror(W_STACK_OVERFLOW,sym->name);
2800
2801         if (i > 3 && sym->recvSize < 4) {              
2802
2803             pic14_emitcode ("mov","a,sp");
2804             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2805             pic14_emitcode ("mov","sp,a");
2806            
2807         }
2808         else
2809             while(i--)
2810                 pic14_emitcode("inc","sp");
2811     }
2812
2813      if (sym->xstack) {
2814
2815         pic14_emitcode ("mov","a,_spx");
2816         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2817         pic14_emitcode ("mov","_spx,a");
2818     }    
2819
2820 }
2821
2822 /*-----------------------------------------------------------------*/
2823 /* genEndFunction - generates epilogue for functions               */
2824 /*-----------------------------------------------------------------*/
2825 static void genEndFunction (iCode *ic)
2826 {
2827     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2828
2829     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2830
2831     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2832     {
2833         pic14_emitcode ("mov","%s,_bp",spname);
2834     }
2835
2836     /* if use external stack but some variables were
2837     added to the local stack then decrement the
2838     local stack */
2839     if (options.useXstack && sym->stack) {      
2840         pic14_emitcode("mov","a,sp");
2841         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2842         pic14_emitcode("mov","sp,a");
2843     }
2844
2845
2846     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2847         if (options.useXstack) {
2848             pic14_emitcode("mov","r0,%s",spname);
2849             pic14_emitcode("movx","a,@r0");
2850             pic14_emitcode("mov","_bp,a");
2851             pic14_emitcode("dec","%s",spname);
2852         }
2853         else
2854         {
2855             pic14_emitcode ("pop","_bp");
2856         }
2857     }
2858
2859     /* restore the register bank  */    
2860     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2861         pic14_emitcode ("pop","psw");
2862
2863     if (IFFUNC_ISISR(sym->type)) {
2864
2865         /* now we need to restore the registers */
2866         /* if this isr has no bank i.e. is going to
2867            run with bank 0 , then we need to save more
2868            registers :-) */
2869         if (!FUNC_REGBANK(sym->type)) {
2870             
2871             /* if this function does not call any other
2872                function then we can be economical and
2873                save only those registers that are used */
2874             if (! IFFUNC_HASFCALL(sym->type)) {
2875                 int i;
2876                 
2877                 /* if any registers used */
2878                 if (sym->regsUsed) {
2879                     /* save the registers used */
2880                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2881                         if (bitVectBitValue(sym->regsUsed,i) ||
2882                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2883                           pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2884                     }
2885                 }
2886                 
2887             } else {
2888                 /* this function has  a function call cannot
2889                    determines register usage so we will have the
2890                    entire bank */
2891                 unsaverbank(0,ic,FALSE);
2892             }       
2893         }
2894 #if 0
2895         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2896         {
2897             if (options.stack10bit)
2898             {
2899                 pic14_emitcode ("pop", "dpx1");
2900                 pic14_emitcode ("pop", "dph1");
2901                 pic14_emitcode ("pop", "dpl1");
2902             }   
2903             pic14_emitcode ("pop", "dps");
2904             pic14_emitcode ("pop", "dpx");
2905         }
2906         if (!inExcludeList("dph"))
2907             pic14_emitcode ("pop","dph");
2908         if (!inExcludeList("dpl"))
2909             pic14_emitcode ("pop","dpl");
2910         if (!inExcludeList("b"))
2911             pic14_emitcode ("pop","b");
2912         if (!inExcludeList("acc"))
2913             pic14_emitcode ("pop","acc");
2914
2915         if (IFFUNC_ISCRITICAL(sym->type))
2916             pic14_emitcode("setb","ea");
2917 #endif
2918
2919         /* if debug then send end of function */
2920 /*      if (options.debug && currFunc) { */
2921         if (currFunc) {
2922             _G.debugLine = 1;
2923             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2924                      FileBaseName(ic->filename),currFunc->lastLine,
2925                      ic->level,ic->block); 
2926             if (IS_STATIC(currFunc->etype))         
2927                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2928             else
2929                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2930             _G.debugLine = 0;
2931         }
2932         
2933         pic14_emitcode ("reti","");
2934
2935         emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2936         emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2937         emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2938         emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2939         emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2940         addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2941
2942         emitpcodeNULLop(POC_RETFIE);
2943
2944     }
2945     else {
2946         if (IFFUNC_ISCRITICAL(sym->type))
2947             pic14_emitcode("setb","ea");
2948         
2949         if (IFFUNC_CALLEESAVES(sym->type)) {
2950             int i;
2951             
2952             /* if any registers used */
2953             if (sym->regsUsed) {
2954                 /* save the registers used */
2955                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2956                     if (bitVectBitValue(sym->regsUsed,i) ||
2957                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2958                       pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2959                 }
2960             }
2961             
2962         }
2963
2964         /* if debug then send end of function */
2965         if (currFunc) {
2966             _G.debugLine = 1;
2967             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2968                      FileBaseName(ic->filename),currFunc->lastLine,
2969                      ic->level,ic->block); 
2970             if (IS_STATIC(currFunc->etype))         
2971                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2972             else
2973                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2974             _G.debugLine = 0;
2975         }
2976
2977         pic14_emitcode ("return","");
2978         emitpcodeNULLop(POC_RETURN);
2979
2980         /* Mark the end of a function */
2981         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2982     }
2983
2984 }
2985
2986 /*-----------------------------------------------------------------*/
2987 /* genRet - generate code for return statement                     */
2988 /*-----------------------------------------------------------------*/
2989 static void genRet (iCode *ic)
2990 {
2991   int size,offset = 0 , pushed = 0;
2992     
2993   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2994   /* if we have no return value then
2995      just generate the "ret" */
2996   if (!IC_LEFT(ic)) 
2997     goto jumpret;       
2998     
2999   /* we have something to return then
3000      move the return value into place */
3001   aopOp(IC_LEFT(ic),ic,FALSE);
3002   size = AOP_SIZE(IC_LEFT(ic));
3003     
3004   while (size--) {
3005     char *l ;
3006     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3007       /* #NOCHANGE */
3008       l = aopGet(AOP(IC_LEFT(ic)),offset++,
3009                  FALSE,TRUE);
3010       pic14_emitcode("push","%s",l);
3011       pushed++;
3012     } else {
3013       l = aopGet(AOP(IC_LEFT(ic)),offset,
3014                  FALSE,FALSE);
3015       if (strcmp(fReturn[offset],l)) {
3016         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3017             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3018           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3019         }else {
3020           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3021         }
3022         if(size) {
3023           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3024         }
3025         offset++;
3026       }
3027     }
3028   }    
3029
3030   if (pushed) {
3031     while(pushed) {
3032       pushed--;
3033       if (strcmp(fReturn[pushed],"a"))
3034         pic14_emitcode("pop",fReturn[pushed]);
3035       else
3036         pic14_emitcode("pop","acc");
3037     }
3038   }
3039   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3040     
3041  jumpret:
3042   /* generate a jump to the return label
3043      if the next is not the return statement */
3044   if (!(ic->next && ic->next->op == LABEL &&
3045         IC_LABEL(ic->next) == returnLabel)) {
3046         
3047     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3048     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3049   }
3050     
3051 }
3052
3053 /*-----------------------------------------------------------------*/
3054 /* genLabel - generates a label                                    */
3055 /*-----------------------------------------------------------------*/
3056 static void genLabel (iCode *ic)
3057 {
3058     /* special case never generate */
3059     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3060     if (IC_LABEL(ic) == entryLabel)
3061         return ;
3062
3063     emitpLabel(IC_LABEL(ic)->key);
3064     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3065 }
3066
3067 /*-----------------------------------------------------------------*/
3068 /* genGoto - generates a goto                                      */
3069 /*-----------------------------------------------------------------*/
3070 //tsd
3071 static void genGoto (iCode *ic)
3072 {
3073   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3074   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3075 }
3076
3077
3078 /*-----------------------------------------------------------------*/
3079 /* genMultbits :- multiplication of bits                           */
3080 /*-----------------------------------------------------------------*/
3081 static void genMultbits (operand *left, 
3082                          operand *right, 
3083                          operand *result)
3084 {
3085   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3086
3087   if(!pic14_sameRegs(AOP(result),AOP(right)))
3088     emitpcode(POC_BSF,  popGet(AOP(result),0));
3089
3090   emitpcode(POC_BTFSC,popGet(AOP(right),0));
3091   emitpcode(POC_BTFSS,popGet(AOP(left),0));
3092   emitpcode(POC_BCF,  popGet(AOP(result),0));
3093
3094 }
3095
3096
3097 /*-----------------------------------------------------------------*/
3098 /* genMultOneByte : 8 bit multiplication & division                */
3099 /*-----------------------------------------------------------------*/
3100 static void genMultOneByte (operand *left,
3101                             operand *right,
3102                             operand *result)
3103 {
3104   sym_link *opetype = operandType(result);
3105
3106   // symbol *lbl ;
3107   int size,offset;
3108
3109   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3110   DEBUGpic14_AopType(__LINE__,left,right,result);
3111   DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3112
3113   /* (if two literals, the value is computed before) */
3114   /* if one literal, literal on the right */
3115   if (AOP_TYPE(left) == AOP_LIT){
3116     operand *t = right;
3117     right = left;
3118     left = t;
3119   }
3120
3121   size = AOP_SIZE(result);
3122   if(size == 1) {
3123
3124     if (AOP_TYPE(right) == AOP_LIT){
3125       pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3126                      aopGet(AOP(right),0,FALSE,FALSE), 
3127                      aopGet(AOP(left),0,FALSE,FALSE), 
3128                      aopGet(AOP(result),0,FALSE,FALSE));
3129       pic14_emitcode("call","genMultLit");
3130     } else {
3131       pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3132                      aopGet(AOP(right),0,FALSE,FALSE), 
3133                      aopGet(AOP(left),0,FALSE,FALSE), 
3134                      aopGet(AOP(result),0,FALSE,FALSE));
3135       pic14_emitcode("call","genMult8X8_8");
3136
3137     }
3138     genMult8X8_8 (left, right,result);
3139
3140
3141     /* signed or unsigned */
3142     //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3143     //l = aopGet(AOP(left),0,FALSE,FALSE);
3144     //MOVA(l);       
3145     //pic14_emitcode("mul","ab");
3146     /* if result size = 1, mul signed = mul unsigned */
3147     //aopPut(AOP(result),"a",0);
3148
3149   } else {  // (size > 1)
3150
3151     pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3152                    aopGet(AOP(right),0,FALSE,FALSE), 
3153                    aopGet(AOP(left),0,FALSE,FALSE), 
3154                    aopGet(AOP(result),0,FALSE,FALSE));
3155
3156     if (SPEC_USIGN(opetype)){
3157       pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3158       genUMult8X8_16 (left, right, result, NULL);
3159
3160       if (size > 2) {
3161         /* for filling the MSBs */
3162         emitpcode(POC_CLRF,  popGet(AOP(result),2));
3163         emitpcode(POC_CLRF,  popGet(AOP(result),3));
3164       }
3165     }
3166     else{
3167       pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3168
3169       pic14_emitcode("mov","a,b");
3170
3171       /* adjust the MSB if left or right neg */
3172
3173       /* if one literal */
3174       if (AOP_TYPE(right) == AOP_LIT){
3175         pic14_emitcode("multiply ","right is a lit");
3176         /* AND literal negative */
3177         if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3178           /* adjust MSB (c==0 after mul) */
3179           pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3180         }
3181       }
3182       else{
3183         genSMult8X8_16 (left, right, result, NULL);
3184       }
3185
3186       if(size > 2){
3187         pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3188         /* get the sign */
3189         pic14_emitcode("rlc","a");
3190         pic14_emitcode("subb","a,acc");
3191       }
3192     }
3193
3194     size -= 2;   
3195     offset = 2;
3196     if (size > 0)
3197       while (size--)
3198         pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3199     //aopPut(AOP(result),"a",offset++);
3200   }
3201 }
3202
3203 /*-----------------------------------------------------------------*/
3204 /* genMult - generates code for multiplication                     */
3205 /*-----------------------------------------------------------------*/
3206 static void genMult (iCode *ic)
3207 {
3208     operand *left = IC_LEFT(ic);
3209     operand *right = IC_RIGHT(ic);
3210     operand *result= IC_RESULT(ic);   
3211
3212     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3213     /* assign the amsops */
3214     aopOp (left,ic,FALSE);
3215     aopOp (right,ic,FALSE);
3216     aopOp (result,ic,TRUE);
3217
3218   DEBUGpic14_AopType(__LINE__,left,right,result);
3219
3220     /* special cases first */
3221     /* both are bits */
3222     if (AOP_TYPE(left) == AOP_CRY &&
3223         AOP_TYPE(right)== AOP_CRY) {
3224         genMultbits(left,right,result);
3225         goto release ;
3226     }
3227
3228     /* if both are of size == 1 */
3229     if (AOP_SIZE(left) == 1 &&
3230         AOP_SIZE(right) == 1 ) {
3231         genMultOneByte(left,right,result);
3232         goto release ;
3233     }
3234
3235     pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3236
3237     /* should have been converted to function call */
3238     //assert(0) ;
3239
3240 release :
3241     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3242     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3243     freeAsmop(result,NULL,ic,TRUE); 
3244 }
3245
3246 /*-----------------------------------------------------------------*/
3247 /* genDivbits :- division of bits                                  */
3248 /*-----------------------------------------------------------------*/
3249 static void genDivbits (operand *left, 
3250                         operand *right, 
3251                         operand *result)
3252 {
3253
3254     char *l;
3255
3256     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3257     /* the result must be bit */    
3258     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3259     l = aopGet(AOP(left),0,FALSE,FALSE);
3260
3261     MOVA(l);    
3262
3263     pic14_emitcode("div","ab");
3264     pic14_emitcode("rrc","a");
3265     aopPut(AOP(result),"c",0);
3266 }
3267
3268 /*-----------------------------------------------------------------*/
3269 /* genDivOneByte : 8 bit division                                  */
3270 /*-----------------------------------------------------------------*/
3271 static void genDivOneByte (operand *left,
3272                            operand *right,
3273                            operand *result)
3274 {
3275     sym_link *opetype = operandType(result);
3276     char *l ;
3277     symbol *lbl ;
3278     int size,offset;
3279
3280     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3281     size = AOP_SIZE(result) - 1;
3282     offset = 1;
3283     /* signed or unsigned */
3284     if (SPEC_USIGN(opetype)) {
3285         /* unsigned is easy */
3286         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3287         l = aopGet(AOP(left),0,FALSE,FALSE);
3288         MOVA(l);        
3289         pic14_emitcode("div","ab");
3290         aopPut(AOP(result),"a",0);
3291         while (size--)
3292             aopPut(AOP(result),zero,offset++);
3293         return ;
3294     }
3295
3296     /* signed is a little bit more difficult */
3297
3298     /* save the signs of the operands */
3299     l = aopGet(AOP(left),0,FALSE,FALSE);    
3300     MOVA(l);    
3301     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3302     pic14_emitcode("push","acc"); /* save it on the stack */
3303
3304     /* now sign adjust for both left & right */
3305     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3306     MOVA(l);       
3307     lbl = newiTempLabel(NULL);
3308     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3309     pic14_emitcode("cpl","a");   
3310     pic14_emitcode("inc","a");
3311     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3312     pic14_emitcode("mov","b,a");
3313
3314     /* sign adjust left side */
3315     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3316     MOVA(l);
3317
3318     lbl = newiTempLabel(NULL);
3319     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3320     pic14_emitcode("cpl","a");
3321     pic14_emitcode("inc","a");
3322     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3323
3324     /* now the division */
3325     pic14_emitcode("div","ab");
3326     /* we are interested in the lower order
3327     only */
3328     pic14_emitcode("mov","b,a");
3329     lbl = newiTempLabel(NULL);
3330     pic14_emitcode("pop","acc");   
3331     /* if there was an over flow we don't 
3332     adjust the sign of the result */
3333     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3334     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3335     CLRC;
3336     pic14_emitcode("clr","a");
3337     pic14_emitcode("subb","a,b");
3338     pic14_emitcode("mov","b,a");
3339     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3340
3341     /* now we are done */
3342     aopPut(AOP(result),"b",0);
3343     if(size > 0){
3344         pic14_emitcode("mov","c,b.7");
3345         pic14_emitcode("subb","a,acc");   
3346     }
3347     while (size--)
3348         aopPut(AOP(result),"a",offset++);
3349
3350 }
3351
3352 /*-----------------------------------------------------------------*/
3353 /* genDiv - generates code for division                            */
3354 /*-----------------------------------------------------------------*/
3355 static void genDiv (iCode *ic)
3356 {
3357     operand *left = IC_LEFT(ic);
3358     operand *right = IC_RIGHT(ic);
3359     operand *result= IC_RESULT(ic);   
3360
3361     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3362     /* assign the amsops */
3363     aopOp (left,ic,FALSE);
3364     aopOp (right,ic,FALSE);
3365     aopOp (result,ic,TRUE);
3366
3367     /* special cases first */
3368     /* both are bits */
3369     if (AOP_TYPE(left) == AOP_CRY &&
3370         AOP_TYPE(right)== AOP_CRY) {
3371         genDivbits(left,right,result);
3372         goto release ;
3373     }
3374
3375     /* if both are of size == 1 */
3376     if (AOP_SIZE(left) == 1 &&
3377         AOP_SIZE(right) == 1 ) {
3378         genDivOneByte(left,right,result);
3379         goto release ;
3380     }
3381
3382     /* should have been converted to function call */
3383     assert(0);
3384 release :
3385     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3386     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3387     freeAsmop(result,NULL,ic,TRUE); 
3388 }
3389
3390 /*-----------------------------------------------------------------*/
3391 /* genModbits :- modulus of bits                                   */
3392 /*-----------------------------------------------------------------*/
3393 static void genModbits (operand *left, 
3394                         operand *right, 
3395                         operand *result)
3396 {
3397
3398     char *l;
3399
3400     /* the result must be bit */    
3401     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3402     l = aopGet(AOP(left),0,FALSE,FALSE);
3403
3404     MOVA(l);       
3405
3406     pic14_emitcode("div","ab");
3407     pic14_emitcode("mov","a,b");
3408     pic14_emitcode("rrc","a");
3409     aopPut(AOP(result),"c",0);
3410 }
3411
3412 /*-----------------------------------------------------------------*/
3413 /* genModOneByte : 8 bit modulus                                   */
3414 /*-----------------------------------------------------------------*/
3415 static void genModOneByte (operand *left,
3416                            operand *right,
3417                            operand *result)
3418 {
3419     sym_link *opetype = operandType(result);
3420     char *l ;
3421     symbol *lbl ;
3422
3423     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3424     /* signed or unsigned */
3425     if (SPEC_USIGN(opetype)) {
3426         /* unsigned is easy */
3427         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3428         l = aopGet(AOP(left),0,FALSE,FALSE);
3429         MOVA(l);    
3430         pic14_emitcode("div","ab");
3431         aopPut(AOP(result),"b",0);
3432         return ;
3433     }
3434
3435     /* signed is a little bit more difficult */
3436
3437     /* save the signs of the operands */
3438     l = aopGet(AOP(left),0,FALSE,FALSE);    
3439     MOVA(l);
3440
3441     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3442     pic14_emitcode("push","acc"); /* save it on the stack */
3443
3444     /* now sign adjust for both left & right */
3445     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3446     MOVA(l);
3447
3448     lbl = newiTempLabel(NULL);
3449     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3450     pic14_emitcode("cpl","a");   
3451     pic14_emitcode("inc","a");
3452     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3453     pic14_emitcode("mov","b,a"); 
3454
3455     /* sign adjust left side */
3456     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3457     MOVA(l);
3458
3459     lbl = newiTempLabel(NULL);
3460     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3461     pic14_emitcode("cpl","a");   
3462     pic14_emitcode("inc","a");
3463     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3464
3465     /* now the multiplication */
3466     pic14_emitcode("div","ab");
3467     /* we are interested in the lower order
3468     only */
3469     lbl = newiTempLabel(NULL);
3470     pic14_emitcode("pop","acc");   
3471     /* if there was an over flow we don't 
3472     adjust the sign of the result */
3473     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3474     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3475     CLRC ;
3476     pic14_emitcode("clr","a");
3477     pic14_emitcode("subb","a,b");
3478     pic14_emitcode("mov","b,a");
3479     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3480
3481     /* now we are done */
3482     aopPut(AOP(result),"b",0);
3483
3484 }
3485
3486 /*-----------------------------------------------------------------*/
3487 /* genMod - generates code for division                            */
3488 /*-----------------------------------------------------------------*/
3489 static void genMod (iCode *ic)
3490 {
3491     operand *left = IC_LEFT(ic);
3492     operand *right = IC_RIGHT(ic);
3493     operand *result= IC_RESULT(ic);  
3494
3495     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3496     /* assign the amsops */
3497     aopOp (left,ic,FALSE);
3498     aopOp (right,ic,FALSE);
3499     aopOp (result,ic,TRUE);
3500
3501     /* special cases first */
3502     /* both are bits */
3503     if (AOP_TYPE(left) == AOP_CRY &&
3504         AOP_TYPE(right)== AOP_CRY) {
3505         genModbits(left,right,result);
3506         goto release ;
3507     }
3508
3509     /* if both are of size == 1 */
3510     if (AOP_SIZE(left) == 1 &&
3511         AOP_SIZE(right) == 1 ) {
3512         genModOneByte(left,right,result);
3513         goto release ;
3514     }
3515
3516     /* should have been converted to function call */
3517     assert(0);
3518
3519 release :
3520     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3521     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3522     freeAsmop(result,NULL,ic,TRUE); 
3523 }
3524
3525 /*-----------------------------------------------------------------*/
3526 /* genIfxJump :- will create a jump depending on the ifx           */
3527 /*-----------------------------------------------------------------*/
3528 /*
3529   note: May need to add parameter to indicate when a variable is in bit space.
3530 */
3531 static void genIfxJump (iCode *ic, char *jval)
3532 {
3533
3534     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3535     /* if true label then we jump if condition
3536     supplied is true */
3537     if ( IC_TRUE(ic) ) {
3538
3539         if(strcmp(jval,"a") == 0)
3540           emitSKPZ;
3541         else if (strcmp(jval,"c") == 0)
3542           emitSKPC;
3543         else {
3544           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3545           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3546         }
3547
3548         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3549         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3550
3551     }
3552     else {
3553         /* false label is present */
3554         if(strcmp(jval,"a") == 0)
3555           emitSKPNZ;
3556         else if (strcmp(jval,"c") == 0)
3557           emitSKPNC;
3558         else {
3559           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3560           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3561         }
3562
3563         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3564         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3565
3566     }
3567
3568
3569     /* mark the icode as generated */
3570     ic->generated = 1;
3571 }
3572
3573 /*-----------------------------------------------------------------*/
3574 /* genSkip                                                         */
3575 /*-----------------------------------------------------------------*/
3576 static void genSkip(iCode *ifx,int status_bit)
3577 {
3578   if(!ifx)
3579     return;
3580
3581   if ( IC_TRUE(ifx) ) {
3582     switch(status_bit) {
3583     case 'z':
3584       emitSKPNZ;
3585       break;
3586
3587     case 'c':
3588       emitSKPNC;
3589       break;
3590
3591     case 'd':
3592       emitSKPDC;
3593       break;
3594
3595     }
3596
3597     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3598     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3599
3600   } else {
3601
3602     switch(status_bit) {
3603
3604     case 'z':
3605       emitSKPZ;
3606       break;
3607
3608     case 'c':
3609       emitSKPC;
3610       break;
3611
3612     case 'd':
3613       emitSKPDC;
3614       break;
3615     }
3616     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3617     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3618
3619   }
3620
3621 }
3622
3623 /*-----------------------------------------------------------------*/
3624 /* genSkipc                                                        */
3625 /*-----------------------------------------------------------------*/
3626 static void genSkipc(resolvedIfx *rifx)
3627 {
3628   if(!rifx)
3629     return;
3630
3631   if(rifx->condition)
3632     emitSKPC;
3633   else
3634     emitSKPNC;
3635
3636   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3637   rifx->generated = 1;
3638 }
3639
3640 /*-----------------------------------------------------------------*/
3641 /* genSkipz2                                                       */
3642 /*-----------------------------------------------------------------*/
3643 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3644 {
3645   if(!rifx)
3646     return;
3647
3648   if( (rifx->condition ^ invert_condition) & 1)
3649     emitSKPZ;
3650   else
3651     emitSKPNZ;
3652
3653   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3654   rifx->generated = 1;
3655 }
3656
3657 /*-----------------------------------------------------------------*/
3658 /* genSkipz                                                        */
3659 /*-----------------------------------------------------------------*/
3660 static void genSkipz(iCode *ifx, int condition)
3661 {
3662   if(!ifx)
3663     return;
3664
3665   if(condition)
3666     emitSKPNZ;
3667   else
3668     emitSKPZ;
3669
3670   if ( IC_TRUE(ifx) )
3671     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3672   else
3673     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3674
3675   if ( IC_TRUE(ifx) )
3676     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3677   else
3678     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3679
3680 }
3681 /*-----------------------------------------------------------------*/
3682 /* genSkipCond                                                     */
3683 /*-----------------------------------------------------------------*/
3684 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3685 {
3686   if(!rifx)
3687     return;
3688
3689   if(rifx->condition)
3690     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3691   else
3692     emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3693
3694
3695   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3696   rifx->generated = 1;
3697 }
3698
3699 #if 0
3700 /*-----------------------------------------------------------------*/
3701 /* genChkZeroes :- greater or less than comparison                 */
3702 /*     For each byte in a literal that is zero, inclusive or the   */
3703 /*     the corresponding byte in the operand with W                */
3704 /*     returns true if any of the bytes are zero                   */
3705 /*-----------------------------------------------------------------*/
3706 static int genChkZeroes(operand *op, int lit,  int size)
3707 {
3708
3709   int i;
3710   int flag =1;
3711
3712   while(size--) {
3713     i = (lit >> (size*8)) & 0xff;
3714
3715     if(i==0) {
3716       if(flag) 
3717         emitpcode(POC_MOVFW, popGet(AOP(op),size));
3718       else
3719         emitpcode(POC_IORFW, popGet(AOP(op),size));
3720       flag = 0;
3721     }
3722   }
3723
3724   return (flag==0);
3725 }
3726 #endif
3727
3728 /*-----------------------------------------------------------------*/
3729 /* genCmp :- greater or less than comparison                       */
3730 /*-----------------------------------------------------------------*/
3731 static void genCmp (operand *left,operand *right,
3732                     operand *result, iCode *ifx, int sign)
3733 {
3734   int size; //, offset = 0 ;
3735   unsigned long lit = 0L,i = 0;
3736   resolvedIfx rFalseIfx;
3737   //  resolvedIfx rTrueIfx;
3738   symbol *truelbl;
3739   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3740 /*
3741   if(ifx) {
3742     DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3743     DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3744   }
3745 */
3746
3747   resolveIfx(&rFalseIfx,ifx);
3748   truelbl  = newiTempLabel(NULL);
3749   size = max(AOP_SIZE(left),AOP_SIZE(right));
3750
3751   DEBUGpic14_AopType(__LINE__,left,right,result);
3752
3753 #define _swapp
3754
3755   /* if literal is on the right then swap with left */
3756   if ((AOP_TYPE(right) == AOP_LIT)) {
3757     operand *tmp = right ;
3758     unsigned long mask = (0x100 << (8*(size-1))) - 1;
3759     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3760 #ifdef _swapp
3761
3762     lit = (lit - 1) & mask;
3763     right = left;
3764     left = tmp;
3765     rFalseIfx.condition ^= 1;
3766 #endif
3767
3768   } else if ((AOP_TYPE(left) == AOP_LIT)) {
3769     lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3770   }
3771
3772
3773   //if(IC_TRUE(ifx) == NULL)
3774   /* if left & right are bit variables */
3775   if (AOP_TYPE(left) == AOP_CRY &&
3776       AOP_TYPE(right) == AOP_CRY ) {
3777     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3778     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3779   } else {
3780     /* subtract right from left if at the
3781        end the carry flag is set then we know that
3782        left is greater than right */
3783
3784     //    {
3785
3786     symbol *lbl  = newiTempLabel(NULL);
3787
3788 #ifndef _swapp
3789     if(AOP_TYPE(right) == AOP_LIT) {
3790
3791       //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3792
3793       DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3794
3795       /* special cases */
3796
3797       if(lit == 0) {
3798
3799         if(sign != 0) 
3800           genSkipCond(&rFalseIfx,left,size-1,7);
3801         else 
3802           /* no need to compare to 0...*/
3803           /* NOTE: this is a de-generate compare that most certainly 
3804            *       creates some dead code. */
3805           emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3806
3807         if(ifx) ifx->generated = 1;
3808         return;
3809
3810       }
3811       size--;
3812
3813       if(size == 0) {
3814         //i = (lit >> (size*8)) & 0xff;
3815         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3816         
3817         emitpcode(POC_MOVFW, popGet(AOP(left),size));
3818
3819         i = ((0-lit) & 0xff);
3820         if(sign) {
3821           if( i == 0x81) { 
3822             /* lit is 0x7f, all signed chars are less than
3823              * this except for 0x7f itself */
3824             emitpcode(POC_XORLW, popGetLit(0x7f));
3825             genSkipz2(&rFalseIfx,0);
3826           } else {
3827             emitpcode(POC_ADDLW, popGetLit(0x80));
3828             emitpcode(POC_ADDLW, popGetLit(i^0x80));
3829             genSkipc(&rFalseIfx);
3830           }
3831
3832         } else {
3833           if(lit == 1) {
3834             genSkipz2(&rFalseIfx,1);
3835           } else {
3836             emitpcode(POC_ADDLW, popGetLit(i));
3837             genSkipc(&rFalseIfx);
3838           }
3839         }
3840
3841         if(ifx) ifx->generated = 1;
3842         return;
3843       }
3844
3845       /* chars are out of the way. now do ints and longs */
3846
3847
3848       DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3849         
3850       /* special cases */
3851
3852       if(sign) {
3853
3854         if(lit == 0) {
3855           genSkipCond(&rFalseIfx,left,size,7);
3856           if(ifx) ifx->generated = 1;
3857           return;
3858         }
3859
3860         if(lit <0x100) {
3861           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3862
3863           //rFalseIfx.condition ^= 1;
3864           //genSkipCond(&rFalseIfx,left,size,7);
3865           //rFalseIfx.condition ^= 1;
3866
3867           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3868           if(rFalseIfx.condition)
3869             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3870           else
3871             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3872
3873           emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3874           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3875           emitpcode(POC_MOVFW, popGet(AOP(left),1));
3876
3877           while(size > 1)
3878             emitpcode(POC_IORFW, popGet(AOP(left),size--));
3879
3880           if(rFalseIfx.condition) {
3881             emitSKPZ;
3882             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3883
3884           } else {
3885             emitSKPNZ;
3886           }
3887
3888           genSkipc(&rFalseIfx);
3889           emitpLabel(truelbl->key);
3890           if(ifx) ifx->generated = 1;
3891           return;
3892
3893         }
3894
3895         if(size == 1) {
3896
3897           if( (lit & 0xff) == 0) {
3898             /* lower byte is zero */
3899             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3900             i = ((lit >> 8) & 0xff) ^0x80;
3901             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3902             emitpcode(POC_ADDLW, popGetLit( 0x80));
3903             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3904             genSkipc(&rFalseIfx);
3905
3906
3907             if(ifx) ifx->generated = 1;
3908             return;
3909
3910           }
3911         } else {
3912           /* Special cases for signed longs */
3913           if( (lit & 0xffffff) == 0) {
3914             /* lower byte is zero */
3915             DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3916             i = ((lit >> 8*3) & 0xff) ^0x80;
3917             emitpcode(POC_MOVFW, popGet(AOP(left),size));
3918             emitpcode(POC_ADDLW, popGetLit( 0x80));
3919             emitpcode(POC_ADDLW, popGetLit(0x100-i));
3920             genSkipc(&rFalseIfx);
3921
3922
3923             if(ifx) ifx->generated = 1;
3924             return;
3925
3926           }
3927
3928         }
3929
3930
3931         if(lit & (0x80 << (size*8))) {
3932           /* lit is negative */
3933           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3934
3935           //genSkipCond(&rFalseIfx,left,size,7);
3936
3937           emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3938
3939           if(rFalseIfx.condition)
3940             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3941           else
3942             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3943
3944
3945         } else {
3946           /* lit is positive */
3947           DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3948           emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3949           if(rFalseIfx.condition)
3950             emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3951           else
3952             emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3953
3954         }
3955
3956         /*
3957           This works, but is only good for ints.
3958           It also requires a "known zero" register.
3959           emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3960           emitpcode(POC_ADDFW, popGet(AOP(left),0));
3961           emitpcode(POC_RLFW,  popCopyReg(&pc_kzero));
3962           emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3963           emitpcode(POC_ADDFW, popGet(AOP(left),1));
3964           genSkipc(&rFalseIfx);
3965
3966           emitpLabel(truelbl->key);
3967           if(ifx) ifx->generated = 1;
3968           return;
3969         **/
3970           
3971         /* There are no more special cases, so perform a general compare */
3972   
3973         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3974         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3975
3976         while(size--) {
3977
3978           emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3979           emitSKPNZ;
3980           emitpcode(POC_SUBFW, popGet(AOP(left),size));
3981         }
3982         //rFalseIfx.condition ^= 1;
3983         genSkipc(&rFalseIfx);
3984
3985         emitpLabel(truelbl->key);
3986
3987         if(ifx) ifx->generated = 1;
3988         return;
3989
3990
3991       }
3992
3993
3994       /* sign is out of the way. So now do an unsigned compare */
3995       DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3996
3997
3998       /* General case - compare to an unsigned literal on the right.*/
3999
4000       i = (lit >> (size*8)) & 0xff;
4001       emitpcode(POC_MOVLW, popGetLit(i));
4002       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4003       while(size--) {
4004         i = (lit >> (size*8)) & 0xff;
4005
4006         if(i) {
4007           emitpcode(POC_MOVLW, popGetLit(i));
4008           emitSKPNZ;
4009           emitpcode(POC_SUBFW, popGet(AOP(left),size));
4010         } else {
4011           /* this byte of the lit is zero, 
4012            *if it's not the last then OR in the variable */
4013           if(size)
4014             emitpcode(POC_IORFW, popGet(AOP(left),size));
4015         }
4016       }
4017
4018
4019       emitpLabel(lbl->key);
4020       //if(emitFinalCheck)
4021       genSkipc(&rFalseIfx);
4022       if(sign)
4023         emitpLabel(truelbl->key);
4024
4025       if(ifx) ifx->generated = 1;
4026       return;
4027
4028
4029     }
4030 #endif  // _swapp
4031
4032     if(AOP_TYPE(left) == AOP_LIT) {
4033       //symbol *lbl = newiTempLabel(NULL);
4034
4035       //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4036
4037
4038       DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4039
4040       /* Special cases */
4041       if((lit == 0) && (sign == 0)){
4042
4043         size--;
4044         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4045         while(size) 
4046           emitpcode(POC_IORFW, popGet(AOP(right),--size));
4047
4048         genSkipz2(&rFalseIfx,0);
4049         if(ifx) ifx->generated = 1;
4050         return;
4051       }
4052
4053       if(size==1) {
4054         /* Special cases */
4055         lit &= 0xff;
4056         if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4057           /* degenerate compare can never be true */
4058           if(rFalseIfx.condition == 0)
4059             emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4060
4061           if(ifx) ifx->generated = 1;
4062           return;
4063         }
4064
4065         if(sign) {
4066           /* signed comparisons to a literal byte */
4067
4068           int lp1 = (lit+1) & 0xff;
4069
4070           DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4071           switch (lp1) {
4072           case 0:
4073             rFalseIfx.condition ^= 1;
4074             genSkipCond(&rFalseIfx,right,0,7);
4075             break;
4076           case 0x7f:
4077             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4078             emitpcode(POC_XORLW, popGetLit(0x7f));
4079             genSkipz2(&rFalseIfx,1);
4080             break;
4081           default:
4082             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4083             emitpcode(POC_ADDLW, popGetLit(0x80));
4084             emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4085             rFalseIfx.condition ^= 1;
4086             genSkipc(&rFalseIfx);
4087             break;
4088           }
4089           if(ifx) ifx->generated = 1;
4090         } else {
4091           /* unsigned comparisons to a literal byte */
4092
4093           switch(lit & 0xff ) {
4094           case 0:
4095             emitpcode(POC_MOVFW, popGet(AOP(right),0));
4096             genSkipz2(&rFalseIfx,0);
4097             if(ifx) ifx->generated = 1;
4098             break;
4099           case 0x7f:
4100             rFalseIfx.condition ^= 1;
4101             genSkipCond(&rFalseIfx,right,0,7);
4102             if(ifx) ifx->generated = 1;
4103             break;
4104
4105           default:
4106             emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4107             emitpcode(POC_SUBFW, popGet(AOP(right),0));
4108             DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4109             rFalseIfx.condition ^= 1;
4110             if (AOP_TYPE(result) == AOP_CRY) {
4111               genSkipc(&rFalseIfx);
4112               if(ifx) ifx->generated = 1;
4113             } else {
4114               DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4115               emitpcode(POC_CLRF, popGet(AOP(result),0));
4116               emitpcode(POC_RLF, popGet(AOP(result),0));
4117               emitpcode(POC_MOVLW, popGetLit(0x01));
4118               emitpcode(POC_XORWF, popGet(AOP(result),0));
4119             }         
4120             break;
4121           }
4122         }
4123
4124         //goto check_carry;
4125         return;
4126
4127       } else {
4128
4129         /* Size is greater than 1 */
4130
4131         if(sign) {
4132           int lp1 = lit+1;
4133
4134           size--;
4135
4136           if(lp1 == 0) {
4137             /* this means lit = 0xffffffff, or -1 */
4138
4139
4140             DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4141             rFalseIfx.condition ^= 1;
4142             genSkipCond(&rFalseIfx,right,size,7);
4143             if(ifx) ifx->generated = 1;
4144             return;
4145           }
4146
4147           if(lit == 0) {
4148             int s = size;
4149
4150             if(rFalseIfx.condition) {
4151               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4152               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4153             }
4154
4155             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4156             while(size--)
4157               emitpcode(POC_IORFW, popGet(AOP(right),size));
4158
4159
4160             emitSKPZ;
4161             if(rFalseIfx.condition) {
4162               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4163               emitpLabel(truelbl->key);
4164             }else {
4165               rFalseIfx.condition ^= 1;
4166               genSkipCond(&rFalseIfx,right,s,7);
4167             }
4168
4169             if(ifx) ifx->generated = 1;
4170             return;
4171           }
4172
4173           if((size == 1) &&  (0 == (lp1&0xff))) {
4174             /* lower byte of signed word is zero */
4175             DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4176             i = ((lp1 >> 8) & 0xff) ^0x80;
4177             emitpcode(POC_MOVFW, popGet(AOP(right),size));
4178             emitpcode(POC_ADDLW, popGetLit( 0x80));
4179             emitpcode(POC_ADDLW, popGetLit(0x100-i));
4180             rFalseIfx.condition ^= 1;
4181             genSkipc(&rFalseIfx);
4182
4183
4184             if(ifx) ifx->generated = 1;
4185             return;
4186           }
4187
4188           if(lit & (0x80 << (size*8))) {
4189             /* Lit is less than zero */
4190             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4191             //rFalseIfx.condition ^= 1;
4192             //genSkipCond(&rFalseIfx,left,size,7);
4193             //rFalseIfx.condition ^= 1;
4194             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4195             //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4196
4197             if(rFalseIfx.condition)
4198               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4199             else
4200               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4201
4202
4203           } else {
4204             /* Lit is greater than or equal to zero */
4205             DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4206             //rFalseIfx.condition ^= 1;
4207             //genSkipCond(&rFalseIfx,right,size,7);
4208             //rFalseIfx.condition ^= 1;
4209
4210             //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4211             //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4212
4213             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4214             if(rFalseIfx.condition)
4215               emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4216             else
4217               emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4218
4219           }
4220
4221
4222           emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4223           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4224
4225           while(size--) {
4226
4227             emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4228             emitSKPNZ;
4229             emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230           }
4231           rFalseIfx.condition ^= 1;
4232           //rFalseIfx.condition = 1;
4233           genSkipc(&rFalseIfx);
4234
4235           emitpLabel(truelbl->key);
4236
4237           if(ifx) ifx->generated = 1;
4238           return;
4239           // end of if (sign)
4240         } else {
4241
4242           /* compare word or long to an unsigned literal on the right.*/
4243
4244
4245           size--;
4246           if(lit < 0xff) {
4247             DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4248             switch (lit) {
4249             case 0:
4250               break; /* handled above */
4251 /*
4252             case 0xff:
4253               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4254               while(size--)
4255                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4256               genSkipz2(&rFalseIfx,0);
4257               break;
4258 */
4259             default:
4260               emitpcode(POC_MOVFW, popGet(AOP(right),size));
4261               while(--size)
4262                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4263
4264               emitSKPZ;
4265               if(rFalseIfx.condition)
4266                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4267               else
4268                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4269
4270
4271               emitpcode(POC_MOVLW, popGetLit(lit+1));
4272               emitpcode(POC_SUBFW, popGet(AOP(right),0));
4273
4274               rFalseIfx.condition ^= 1;
4275               genSkipc(&rFalseIfx);
4276             }
4277
4278             emitpLabel(truelbl->key);
4279
4280             if(ifx) ifx->generated = 1;
4281             return;
4282           }
4283
4284
4285           lit++;
4286           DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4287           i = (lit >> (size*8)) & 0xff;
4288
4289           emitpcode(POC_MOVLW, popGetLit(i));
4290           emitpcode(POC_SUBFW, popGet(AOP(right),size));
4291
4292           while(size--) {
4293             i = (lit >> (size*8)) & 0xff;
4294
4295             if(i) {
4296               emitpcode(POC_MOVLW, popGetLit(i));
4297               emitSKPNZ;
4298               emitpcode(POC_SUBFW, popGet(AOP(right),size));
4299             } else {
4300               /* this byte of the lit is zero, 
4301                *if it's not the last then OR in the variable */
4302               if(size)
4303                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4304             }
4305           }
4306
4307
4308           emitpLabel(lbl->key);
4309
4310           rFalseIfx.condition ^= 1;
4311           genSkipc(&rFalseIfx);
4312         }
4313
4314         if(sign)
4315           emitpLabel(truelbl->key);
4316         if(ifx) ifx->generated = 1;
4317         return;
4318       }
4319     }
4320     /* Compare two variables */
4321
4322     DEBUGpic14_emitcode(";sign","%d",sign);
4323
4324     size--;
4325     if(sign) {
4326       /* Sigh. thus sucks... */
4327       if(size) {
4328         emitpcode(POC_MOVFW, popGet(AOP(left),size));
4329         emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4330         emitpcode(POC_MOVLW, popGetLit(0x80));
4331         emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4332         emitpcode(POC_XORFW, popGet(AOP(right),size));
4333         emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4334       } else {
4335         /* Signed char comparison */
4336         /* Special thanks to Nikolai Golovchenko for this snippet */
4337         emitpcode(POC_MOVFW, popGet(AOP(right),0));
4338         emitpcode(POC_SUBFW, popGet(AOP(left),0));
4339         emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4340         emitpcode(POC_XORFW, popGet(AOP(left),0));
4341         emitpcode(POC_XORFW, popGet(AOP(right),0));
4342         emitpcode(POC_ADDLW, popGetLit(0x80));
4343
4344         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4345         genSkipc(&rFalseIfx);
4346           
4347         if(ifx) ifx->generated = 1;
4348         return;
4349       }
4350
4351     } else {
4352
4353       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4354       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4355     }
4356
4357
4358     /* The rest of the bytes of a multi-byte compare */
4359     while (size) {
4360
4361       emitSKPZ;
4362       emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4363       size--;
4364
4365       emitpcode(POC_MOVFW, popGet(AOP(right),size));
4366       emitpcode(POC_SUBFW, popGet(AOP(left),size));
4367
4368
4369     }
4370
4371     emitpLabel(lbl->key);
4372
4373     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4374     if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4375         (AOP_TYPE(result) == AOP_REG)) {
4376       emitpcode(POC_CLRF, popGet(AOP(result),0));
4377       emitpcode(POC_RLF, popGet(AOP(result),0));
4378     } else {
4379       genSkipc(&rFalseIfx);
4380     }         
4381     //genSkipc(&rFalseIfx);
4382     if(ifx) ifx->generated = 1;
4383
4384     return;
4385
4386   }
4387
4388   // check_carry:
4389   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4390     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4391     pic14_outBitC(result);
4392   } else {
4393     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4394     /* if the result is used in the next
4395        ifx conditional branch then generate
4396        code a little differently */
4397     if (ifx )
4398       genIfxJump (ifx,"c");
4399     else
4400       pic14_outBitC(result);
4401     /* leave the result in acc */
4402   }
4403
4404 }
4405
4406 /*-----------------------------------------------------------------*/
4407 /* genCmpGt :- greater than comparison                             */
4408 /*-----------------------------------------------------------------*/
4409 static void genCmpGt (iCode *ic, iCode *ifx)
4410 {
4411     operand *left, *right, *result;
4412     sym_link *letype , *retype;
4413     int sign ;
4414
4415     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4416     left = IC_LEFT(ic);
4417     right= IC_RIGHT(ic);
4418     result = IC_RESULT(ic);
4419
4420     letype = getSpec(operandType(left));
4421     retype =getSpec(operandType(right));
4422     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4423     /* assign the amsops */
4424     aopOp (left,ic,FALSE);
4425     aopOp (right,ic,FALSE);
4426     aopOp (result,ic,TRUE);
4427
4428     genCmp(right, left, result, ifx, sign);
4429
4430     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4431     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4432     freeAsmop(result,NULL,ic,TRUE); 
4433 }
4434
4435 /*-----------------------------------------------------------------*/
4436 /* genCmpLt - less than comparisons                                */
4437 /*-----------------------------------------------------------------*/
4438 static void genCmpLt (iCode *ic, iCode *ifx)
4439 {
4440     operand *left, *right, *result;
4441     sym_link *letype , *retype;
4442     int sign ;
4443
4444     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4445     left = IC_LEFT(ic);
4446     right= IC_RIGHT(ic);
4447     result = IC_RESULT(ic);
4448
4449     letype = getSpec(operandType(left));
4450     retype =getSpec(operandType(right));
4451     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4452
4453     /* assign the amsops */
4454     aopOp (left,ic,FALSE);
4455     aopOp (right,ic,FALSE);
4456     aopOp (result,ic,TRUE);
4457
4458     genCmp(left, right, result, ifx, sign);
4459
4460     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4461     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4462     freeAsmop(result,NULL,ic,TRUE); 
4463 }
4464
4465 /*-----------------------------------------------------------------*/
4466 /* genc16bit2lit - compare a 16 bit value to a literal             */
4467 /*-----------------------------------------------------------------*/
4468 static void genc16bit2lit(operand *op, int lit, int offset)
4469 {
4470   int i;
4471
4472   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4473   if( (lit&0xff) == 0) 
4474     i=1;
4475   else
4476     i=0;
4477
4478   switch( BYTEofLONG(lit,i)) { 
4479   case 0:
4480     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4481     break;
4482   case 1:
4483     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4484     break;
4485   case 0xff:
4486     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4487     break;
4488   default:
4489     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4490     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4491   }
4492
4493   i ^= 1;
4494
4495   switch( BYTEofLONG(lit,i)) { 
4496   case 0:
4497     emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4498     break;
4499   case 1:
4500     emitSKPNZ;
4501     emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4502     break;
4503   case 0xff:
4504     emitSKPNZ;
4505     emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4506     break;
4507   default:
4508     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4509     emitSKPNZ;
4510     emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4511
4512   }
4513
4514 }
4515
4516 /*-----------------------------------------------------------------*/
4517 /* gencjneshort - compare and jump if not equal                    */
4518 /*-----------------------------------------------------------------*/
4519 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4520 {
4521   int size = max(AOP_SIZE(left),AOP_SIZE(right));
4522   int offset = 0;
4523   int res_offset = 0;  /* the result may be a different size then left or right */
4524   int res_size = AOP_SIZE(result);
4525   resolvedIfx rIfx;
4526   symbol *lbl;
4527
4528   unsigned long lit = 0L;
4529   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4530   DEBUGpic14_AopType(__LINE__,left,right,result);
4531   if(result)
4532     DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4533   resolveIfx(&rIfx,ifx);
4534   lbl =  newiTempLabel(NULL);
4535
4536
4537   /* if the left side is a literal or 
4538      if the right is in a pointer register and left 
4539      is not */
4540   if ((AOP_TYPE(left) == AOP_LIT) || 
4541       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4542     operand *t = right;
4543     right = left;
4544     left = t;
4545   }
4546   if(AOP_TYPE(right) == AOP_LIT)
4547     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4548
4549   /* if the right side is a literal then anything goes */
4550   if (AOP_TYPE(right) == AOP_LIT &&
4551       AOP_TYPE(left) != AOP_DIR ) {
4552     switch(size) {
4553     case 2:
4554       genc16bit2lit(left, lit, 0);
4555       emitSKPNZ;
4556       emitpcode(POC_GOTO,popGetLabel(lbl->key));
4557       break;
4558     default:
4559       while (size--) {
4560         if(lit & 0xff) {
4561           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4562           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4563         } else {
4564           emitpcode(POC_MOVF,popGet(AOP(left),offset));
4565         }
4566
4567         emitSKPNZ;
4568         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4569         offset++;
4570         if(res_offset < res_size-1)
4571           res_offset++;
4572         lit >>= 8;
4573       }
4574       break;
4575     }
4576   }
4577
4578   /* if the right side is in a register or in direct space or
4579      if the left is a pointer register & right is not */    
4580   else if (AOP_TYPE(right) == AOP_REG ||
4581            AOP_TYPE(right) == AOP_DIR || 
4582            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4583            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4584     //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4585     int lbl_key = lbl->key;
4586
4587     if(result) {
4588       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4589       //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4590     }else {
4591       DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4592       fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4593               __FUNCTION__,__LINE__);
4594       return;
4595     }
4596
4597 /*     switch(size) { */
4598 /*     case 2: */
4599 /*       genc16bit2lit(left, lit, 0); */
4600 /*       emitSKPNZ; */
4601 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4602 /*       break; */
4603 /*     default: */
4604     while (size--) {
4605       int emit_skip=1;
4606       if((AOP_TYPE(left) == AOP_DIR) && 
4607          ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4608
4609         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4610         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4611
4612       } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4613             
4614         switch (lit & 0xff) {
4615         case 0:
4616           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4617           break;
4618         case 1:
4619           emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4620           emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4621           //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4622           emit_skip=0;
4623           break;
4624         case 0xff:
4625           emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4626           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4627           //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4628           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4629           emit_skip=0;
4630           break;
4631         default:
4632           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4633           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4634         }
4635         lit >>= 8;
4636
4637       } else {
4638         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4639       }
4640       if(emit_skip) {
4641         if(AOP_TYPE(result) == AOP_CRY) {
4642           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4643           if(rIfx.condition)
4644             emitSKPNZ;
4645           else
4646             emitSKPZ;
4647           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4648         } else {
4649           /* fix me. probably need to check result size too */
4650           //emitpcode(POC_CLRF,popGet(AOP(result),0));
4651           if(rIfx.condition)
4652             emitSKPZ;
4653           else
4654             emitSKPNZ;
4655           emitpcode(POC_GOTO,popGetLabel(lbl_key));
4656           //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4657         }
4658         if(ifx)
4659           ifx->generated=1;
4660       }
4661       emit_skip++;
4662       offset++;
4663       if(res_offset < res_size-1)
4664         res_offset++;
4665     }
4666 /*       break; */
4667 /*     } */
4668   } else if(AOP_TYPE(right) == AOP_REG &&
4669             AOP_TYPE(left) != AOP_DIR){
4670
4671     while(size--) {
4672       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4673       emitpcode(POC_XORFW,popGet(AOP(right),offset));
4674       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4675       if(rIfx.condition)
4676         emitSKPNZ;
4677       else
4678         emitSKPZ;
4679       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4680       offset++;
4681       if(res_offset < res_size-1)
4682         res_offset++;
4683     }
4684       
4685   }else{
4686     /* right is a pointer reg need both a & b */
4687     while(size--) {
4688       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4689       if(strcmp(l,"b"))
4690         pic14_emitcode("mov","b,%s",l);
4691       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4692       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4693       offset++;
4694     }
4695   }
4696
4697   emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4698   if(!rIfx.condition)
4699     emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4700
4701   emitpLabel(lbl->key);
4702
4703   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4704
4705   if(ifx)
4706     ifx->generated = 1;
4707 }
4708
4709 #if 0
4710 /*-----------------------------------------------------------------*/
4711 /* gencjne - compare and jump if not equal                         */
4712 /*-----------------------------------------------------------------*/
4713 static void gencjne(operand *left, operand *right, iCode *ifx)
4714 {
4715     symbol *tlbl  = newiTempLabel(NULL);
4716
4717     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4718     gencjneshort(left, right, lbl);
4719
4720     pic14_emitcode("mov","a,%s",one);
4721     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4722     pic14_emitcode("","%05d_DS_:",lbl->key+100);
4723     pic14_emitcode("clr","a");
4724     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4725
4726     emitpLabel(lbl->key);
4727     emitpLabel(tlbl->key);
4728
4729 }
4730 #endif
4731
4732 /*-----------------------------------------------------------------*/
4733 /* genCmpEq - generates code for equal to                          */
4734 /*-----------------------------------------------------------------*/
4735 static void genCmpEq (iCode *ic, iCode *ifx)
4736 {
4737     operand *left, *right, *result;
4738     unsigned long lit = 0L;
4739     int size,offset=0;
4740
4741     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4742
4743     if(ifx)
4744       DEBUGpic14_emitcode ("; ifx is non-null","");
4745     else
4746       DEBUGpic14_emitcode ("; ifx is null","");
4747
4748     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4749     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4750     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4751
4752     size = max(AOP_SIZE(left),AOP_SIZE(right));
4753
4754     DEBUGpic14_AopType(__LINE__,left,right,result);
4755
4756     /* if literal, literal on the right or 
4757     if the right is in a pointer register and left 
4758     is not */
4759     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4760         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4761       operand *tmp = right ;
4762       right = left;
4763       left = tmp;
4764     }
4765
4766
4767     if(ifx && !AOP_SIZE(result)){
4768         symbol *tlbl;
4769         /* if they are both bit variables */
4770         if (AOP_TYPE(left) == AOP_CRY &&
4771             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4772             if(AOP_TYPE(right) == AOP_LIT){
4773                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4774                 if(lit == 0L){
4775                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4776                     pic14_emitcode("cpl","c");
4777                 } else if(lit == 1L) {
4778                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4779                 } else {
4780                     pic14_emitcode("clr","c");
4781                 }
4782                 /* AOP_TYPE(right) == AOP_CRY */
4783             } else {
4784                 symbol *lbl = newiTempLabel(NULL);
4785                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4786                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4787                 pic14_emitcode("cpl","c");
4788                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4789             }
4790             /* if true label then we jump if condition
4791             supplied is true */
4792             tlbl = newiTempLabel(NULL);
4793             if ( IC_TRUE(ifx) ) {
4794                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4795                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4796             } else {
4797                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4798                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4799             }
4800             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4801
4802             {
4803               /* left and right are both bit variables, result is carry */
4804               resolvedIfx rIfx;
4805               
4806               resolveIfx(&rIfx,ifx);
4807
4808               emitpcode(POC_MOVLW,popGet(AOP(left),0));
4809               emitpcode(POC_ANDFW,popGet(AOP(left),0));
4810               emitpcode(POC_BTFSC,popGet(AOP(right),0));
4811               emitpcode(POC_ANDLW,popGet(AOP(left),0));
4812               genSkipz2(&rIfx,0);
4813             }
4814         } else {
4815
4816           /* They're not both bit variables. Is the right a literal? */
4817           if(AOP_TYPE(right) == AOP_LIT) {
4818             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4819             
4820             switch(size) {
4821
4822             case 1:
4823               switch(lit & 0xff) {
4824               case 1:
4825                 if ( IC_TRUE(ifx) ) {
4826                   emitpcode(POC_DECFW,popGet(AOP(left),offset));
4827                   emitSKPNZ;
4828                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4829                 } else {
4830                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4831                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4832                 }
4833                 break;
4834               case 0xff:
4835                 if ( IC_TRUE(ifx) ) {
4836                   emitpcode(POC_INCFW,popGet(AOP(left),offset));
4837                   emitSKPNZ;
4838                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4839                 } else {
4840                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4841                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4842                 }
4843                 break;
4844               default:
4845                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4846                 if(lit)
4847                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4848                 genSkip(ifx,'z');
4849               }
4850
4851
4852               /* end of size == 1 */
4853               break;
4854               
4855             case 2:
4856               genc16bit2lit(left,lit,offset);
4857               genSkip(ifx,'z');
4858               break;
4859               /* end of size == 2 */
4860
4861             default:
4862               /* size is 4 */
4863               if(lit==0) {
4864                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4865                 emitpcode(POC_IORFW,popGet(AOP(left),1));
4866                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4867                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4868
4869               } else {
4870
4871                 /* search for patterns that can be optimized */
4872
4873                 genc16bit2lit(left,lit,0);
4874                 lit >>= 16;
4875                 if(lit) {
4876                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4877                   //genSkip(ifx,'z');
4878                   genc16bit2lit(left,lit,2);
4879                 } else {
4880                   emitpcode(POC_IORFW,popGet(AOP(left),2));
4881                   emitpcode(POC_IORFW,popGet(AOP(left),3));
4882
4883                 }
4884                 
4885               }
4886
4887               genSkip(ifx,'z');
4888             }
4889           
4890             ifx->generated = 1;
4891             goto release ;
4892             
4893
4894           } else if(AOP_TYPE(right) == AOP_CRY ) {
4895             /* we know the left is not a bit, but that the right is */
4896             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4897             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4898                       popGet(AOP(right),offset));
4899             emitpcode(POC_XORLW,popGetLit(1));
4900
4901             /* if the two are equal, then W will be 0 and the Z bit is set
4902              * we could test Z now, or go ahead and check the high order bytes if
4903              * the variable we're comparing is larger than a byte. */
4904
4905             while(--size)
4906               emitpcode(POC_IORFW,popGet(AOP(left),offset));
4907
4908             if ( IC_TRUE(ifx) ) {
4909               emitSKPNZ;
4910               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4911               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4912             } else {
4913               emitSKPZ;
4914               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4915               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4916             }
4917
4918           } else {
4919             /* They're both variables that are larger than bits */
4920             int s = size;
4921
4922             tlbl = newiTempLabel(NULL);
4923
4924             while(size--) {
4925               emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4926               emitpcode(POC_XORFW,popGet(AOP(right),offset));
4927
4928               if ( IC_TRUE(ifx) ) {
4929                 if(size) {
4930                   emitSKPZ;
4931                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4932                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4933                 } else {
4934                   emitSKPNZ;
4935                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4936                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4937                 }
4938               } else {
4939                 emitSKPZ;
4940                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4941                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4942               }
4943               offset++;
4944             }
4945             if(s>1 && IC_TRUE(ifx)) {
4946               emitpLabel(tlbl->key);
4947               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4948             }
4949           }
4950         }
4951         /* mark the icode as generated */
4952         ifx->generated = 1;
4953         goto release ;
4954     }
4955
4956     /* if they are both bit variables */
4957     if (AOP_TYPE(left) == AOP_CRY &&
4958         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4959         if(AOP_TYPE(right) == AOP_LIT){
4960             unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4961             if(lit == 0L){
4962                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4963                 pic14_emitcode("cpl","c");
4964             } else if(lit == 1L) {
4965                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4966             } else {
4967                 pic14_emitcode("clr","c");
4968             }
4969             /* AOP_TYPE(right) == AOP_CRY */
4970         } else {
4971             symbol *lbl = newiTempLabel(NULL);
4972             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4973             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4974             pic14_emitcode("cpl","c");
4975             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4976         }
4977         /* c = 1 if egal */
4978         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4979             pic14_outBitC(result);
4980             goto release ;
4981         }
4982         if (ifx) {
4983             genIfxJump (ifx,"c");
4984             goto release ;
4985         }
4986         /* if the result is used in an arithmetic operation
4987         then put the result in place */
4988         pic14_outBitC(result);
4989     } else {
4990       
4991       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4992       gencjne(left,right,result,ifx);
4993 /*
4994       if(ifx) 
4995         gencjne(left,right,newiTempLabel(NULL));
4996       else {
4997         if(IC_TRUE(ifx)->key)
4998           gencjne(left,right,IC_TRUE(ifx)->key);
4999         else
5000           gencjne(left,right,IC_FALSE(ifx)->key);
5001         ifx->generated = 1;
5002         goto release ;
5003       }
5004       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5005         aopPut(AOP(result),"a",0);
5006         goto release ;
5007       }
5008
5009       if (ifx) {
5010         genIfxJump (ifx,"a");
5011         goto release ;
5012       }
5013 */
5014       /* if the result is used in an arithmetic operation
5015          then put the result in place */
5016 /*
5017       if (AOP_TYPE(result) != AOP_CRY) 
5018         pic14_outAcc(result);
5019 */
5020       /* leave the result in acc */
5021     }
5022
5023 release:
5024     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5025     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5026     freeAsmop(result,NULL,ic,TRUE);
5027 }
5028
5029 /*-----------------------------------------------------------------*/
5030 /* ifxForOp - returns the icode containing the ifx for operand     */
5031 /*-----------------------------------------------------------------*/
5032 static iCode *ifxForOp ( operand *op, iCode *ic )
5033 {
5034     /* if true symbol then needs to be assigned */
5035     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5036     if (IS_TRUE_SYMOP(op))
5037         return NULL ;
5038
5039     /* if this has register type condition and
5040     the next instruction is ifx with the same operand
5041     and live to of the operand is upto the ifx only then */
5042     if (ic->next &&
5043         ic->next->op == IFX &&
5044         IC_COND(ic->next)->key == op->key &&
5045         OP_SYMBOL(op)->liveTo <= ic->next->seq )
5046         return ic->next;
5047
5048     if (ic->next &&
5049         ic->next->op == IFX &&
5050         IC_COND(ic->next)->key == op->key) {
5051       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5052       return ic->next;
5053     }
5054
5055     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5056     if (ic->next &&
5057         ic->next->op == IFX)
5058       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5059
5060     if (ic->next &&
5061         ic->next->op == IFX &&
5062         IC_COND(ic->next)->key == op->key) {
5063       DEBUGpic14_emitcode ("; "," key is okay");
5064       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5065                            OP_SYMBOL(op)->liveTo,
5066                            ic->next->seq);
5067     }
5068
5069
5070     return NULL;
5071 }
5072 /*-----------------------------------------------------------------*/
5073 /* genAndOp - for && operation                                     */
5074 /*-----------------------------------------------------------------*/
5075 static void genAndOp (iCode *ic)
5076 {
5077     operand *left,*right, *result;
5078 /*     symbol *tlbl; */
5079
5080     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5081     /* note here that && operations that are in an
5082     if statement are taken away by backPatchLabels
5083     only those used in arthmetic operations remain */
5084     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5085     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5086     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5087
5088     DEBUGpic14_AopType(__LINE__,left,right,result);
5089
5090     emitpcode(POC_MOVFW,popGet(AOP(left),0));
5091     emitpcode(POC_ANDFW,popGet(AOP(right),0));
5092     emitpcode(POC_MOVWF,popGet(AOP(result),0));
5093
5094     /* if both are bit variables */
5095 /*     if (AOP_TYPE(left) == AOP_CRY && */
5096 /*         AOP_TYPE(right) == AOP_CRY ) { */
5097 /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5098 /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5099 /*         pic14_outBitC(result); */
5100 /*     } else { */
5101 /*         tlbl = newiTempLabel(NULL); */
5102 /*         pic14_toBoolean(left);     */
5103 /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5104 /*         pic14_toBoolean(right); */
5105 /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5106 /*         pic14_outBitAcc(result); */
5107 /*     } */
5108
5109     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5111     freeAsmop(result,NULL,ic,TRUE);
5112 }
5113
5114
5115 /*-----------------------------------------------------------------*/
5116 /* genOrOp - for || operation                                      */
5117 /*-----------------------------------------------------------------*/
5118 /*
5119   tsd pic port -
5120   modified this code, but it doesn't appear to ever get called
5121 */
5122
5123 static void genOrOp (iCode *ic)
5124 {
5125     operand *left,*right, *result;
5126     symbol *tlbl;
5127
5128     /* note here that || operations that are in an
5129     if statement are taken away by backPatchLabels
5130     only those used in arthmetic operations remain */
5131     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5132     aopOp((left=IC_LEFT(ic)),ic,FALSE);
5133     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5134     aopOp((result=IC_RESULT(ic)),ic,FALSE);
5135
5136     DEBUGpic14_AopType(__LINE__,left,right,result);
5137
5138     /* if both are bit variables */
5139     if (AOP_TYPE(left) == AOP_CRY &&
5140         AOP_TYPE(right) == AOP_CRY ) {
5141       pic14_emitcode("clrc","");
5142       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5143                AOP(left)->aopu.aop_dir,
5144                AOP(left)->aopu.aop_dir);
5145       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5146                AOP(right)->aopu.aop_dir,
5147                AOP(right)->aopu.aop_dir);
5148       pic14_emitcode("setc","");
5149
5150     } else {
5151         tlbl = newiTempLabel(NULL);
5152         pic14_toBoolean(left);
5153         emitSKPZ;
5154         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5155         pic14_toBoolean(right);
5156         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5157
5158         pic14_outBitAcc(result);
5159     }
5160
5161     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5162     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5163     freeAsmop(result,NULL,ic,TRUE);            
5164 }
5165
5166 /*-----------------------------------------------------------------*/
5167 /* isLiteralBit - test if lit == 2^n                               */
5168 /*-----------------------------------------------------------------*/
5169 static int isLiteralBit(unsigned long lit)
5170 {
5171     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5172     0x100L,0x200L,0x400L,0x800L,
5173     0x1000L,0x2000L,0x4000L,0x8000L,
5174     0x10000L,0x20000L,0x40000L,0x80000L,
5175     0x100000L,0x200000L,0x400000L,0x800000L,
5176     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5177     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5178     int idx;
5179     
5180     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5181     for(idx = 0; idx < 32; idx++)
5182         if(lit == pw[idx])
5183             return idx+1;
5184     return 0;
5185 }
5186
5187 /*-----------------------------------------------------------------*/
5188 /* continueIfTrue -                                                */
5189 /*-----------------------------------------------------------------*/
5190 static void continueIfTrue (iCode *ic)
5191 {
5192     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5193     if(IC_TRUE(ic))
5194         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5195     ic->generated = 1;
5196 }
5197
5198 /*-----------------------------------------------------------------*/
5199 /* jmpIfTrue -                                                     */
5200 /*-----------------------------------------------------------------*/
5201 static void jumpIfTrue (iCode *ic)
5202 {
5203     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5204     if(!IC_TRUE(ic))
5205         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5206     ic->generated = 1;
5207 }
5208
5209 /*-----------------------------------------------------------------*/
5210 /* jmpTrueOrFalse -                                                */
5211 /*-----------------------------------------------------------------*/
5212 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5213 {
5214     // ugly but optimized by peephole
5215     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5216     if(IC_TRUE(ic)){
5217         symbol *nlbl = newiTempLabel(NULL);
5218         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5219         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5220         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5221         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5222     }
5223     else{
5224         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5225         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5226     }
5227     ic->generated = 1;
5228 }
5229
5230 /*-----------------------------------------------------------------*/
5231 /* genAnd  - code for and                                          */
5232 /*-----------------------------------------------------------------*/
5233 static void genAnd (iCode *ic, iCode *ifx)
5234 {
5235   operand *left, *right, *result;
5236   int size, offset=0;  
5237   unsigned long lit = 0L;
5238   int bytelit = 0;
5239   resolvedIfx rIfx;
5240
5241
5242   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5243   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5244   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5245   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5246
5247   resolveIfx(&rIfx,ifx);
5248
5249   /* if left is a literal & right is not then exchange them */
5250   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5251       AOP_NEEDSACC(left)) {
5252     operand *tmp = right ;
5253     right = left;
5254     left = tmp;
5255   }
5256
5257   /* if result = right then exchange them */
5258   if(pic14_sameRegs(AOP(result),AOP(right))){
5259     operand *tmp = right ;
5260     right = left;
5261     left = tmp;
5262   }
5263
5264   /* if right is bit then exchange them */
5265   if (AOP_TYPE(right) == AOP_CRY &&
5266       AOP_TYPE(left) != AOP_CRY){
5267     operand *tmp = right ;
5268     right = left;
5269     left = tmp;
5270   }
5271   if(AOP_TYPE(right) == AOP_LIT)
5272     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5273
5274   size = AOP_SIZE(result);
5275
5276   DEBUGpic14_AopType(__LINE__,left,right,result);
5277
5278   // if(bit & yy)
5279   // result = bit & yy;
5280   if (AOP_TYPE(left) == AOP_CRY){
5281     // c = bit & literal;
5282     if(AOP_TYPE(right) == AOP_LIT){
5283       if(lit & 1) {
5284         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5285           // no change
5286           goto release;
5287         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5288       } else {
5289         // bit(result) = 0;
5290         if(size && (AOP_TYPE(result) == AOP_CRY)){
5291           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5292           goto release;
5293         }
5294         if((AOP_TYPE(result) == AOP_CRY) && ifx){
5295           jumpIfTrue(ifx);
5296           goto release;
5297         }
5298         pic14_emitcode("clr","c");
5299       }
5300     } else {
5301       if (AOP_TYPE(right) == AOP_CRY){
5302         // c = bit & bit;
5303         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5304         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5305       } else {
5306         // c = bit & val;
5307         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5308         // c = lsb
5309         pic14_emitcode("rrc","a");
5310         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5311       }
5312     }
5313     // bit = c
5314     // val = c
5315     if(size)
5316       pic14_outBitC(result);
5317     // if(bit & ...)
5318     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5319       genIfxJump(ifx, "c");           
5320     goto release ;
5321   }
5322
5323   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5324   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5325   if((AOP_TYPE(right) == AOP_LIT) &&
5326      (AOP_TYPE(result) == AOP_CRY) &&
5327      (AOP_TYPE(left) != AOP_CRY)){
5328     int posbit = isLiteralBit(lit);
5329     /* left &  2^n */
5330     if(posbit){
5331       posbit--;
5332       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5333       // bit = left & 2^n
5334       if(size)
5335         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5336       // if(left &  2^n)
5337       else{
5338         if(ifx){
5339 /*
5340           if(IC_TRUE(ifx)) {
5341             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5342             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5343           } else {
5344             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5345             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5346           }
5347 */
5348           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5349                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5350           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5351           
5352           ifx->generated = 1;
5353         }
5354         goto release;
5355       }
5356     } else {
5357       symbol *tlbl = newiTempLabel(NULL);
5358       int sizel = AOP_SIZE(left);
5359       if(size)
5360         pic14_emitcode("setb","c");
5361       while(sizel--){
5362         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5363           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5364           // byte ==  2^n ?
5365           if((posbit = isLiteralBit(bytelit)) != 0)
5366             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5367           else{
5368             if(bytelit != 0x0FFL)
5369               pic14_emitcode("anl","a,%s",
5370                              aopGet(AOP(right),offset,FALSE,TRUE));
5371             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5372           }
5373         }
5374         offset++;
5375       }
5376       // bit = left & literal
5377       if(size){
5378         pic14_emitcode("clr","c");
5379         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5380       }
5381       // if(left & literal)
5382       else{
5383         if(ifx)
5384           jmpTrueOrFalse(ifx, tlbl);
5385         goto release ;
5386       }
5387     }
5388     pic14_outBitC(result);
5389     goto release ;
5390   }
5391
5392   /* if left is same as result */
5393   if(pic14_sameRegs(AOP(result),AOP(left))){
5394     int know_W = -1;
5395     for(;size--; offset++,lit>>=8) {
5396       if(AOP_TYPE(right) == AOP_LIT){
5397         switch(lit & 0xff) {
5398         case 0x00:
5399           /*  and'ing with 0 has clears the result */
5400           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5401           emitpcode(POC_CLRF,popGet(AOP(result),offset));
5402           break;
5403         case 0xff:
5404           /* and'ing with 0xff is a nop when the result and left are the same */
5405           break;
5406
5407         default:
5408           {
5409             int p = my_powof2( (~lit) & 0xff );
5410             if(p>=0) {
5411               /* only one bit is set in the literal, so use a bcf instruction */
5412               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5413               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5414
5415             } else {
5416               pic14_emitcode("movlw","0x%x", (lit & 0xff));
5417               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5418               if(know_W != (lit&0xff))
5419                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5420               know_W = lit &0xff;
5421               emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5422             }
5423           }    
5424         }
5425       } else {
5426         if (AOP_TYPE(left) == AOP_ACC) {
5427           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5428         } else {                    
5429           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5430           emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5431
5432         }
5433       }
5434     }
5435
5436   } else {
5437     // left & result in different registers
5438     if(AOP_TYPE(result) == AOP_CRY){
5439       // result = bit
5440       // if(size), result in bit
5441       // if(!size && ifx), conditional oper: if(left & right)
5442       symbol *tlbl = newiTempLabel(NULL);
5443       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5444       if(size)
5445         pic14_emitcode("setb","c");
5446       while(sizer--){
5447         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5448         pic14_emitcode("anl","a,%s",
5449                        aopGet(AOP(left),offset,FALSE,FALSE));
5450         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5451         offset++;
5452       }
5453       if(size){
5454         CLRC;
5455         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5456         pic14_outBitC(result);
5457       } else if(ifx)
5458         jmpTrueOrFalse(ifx, tlbl);
5459     } else {
5460       for(;(size--);offset++) {
5461         // normal case
5462         // result = left & right
5463         if(AOP_TYPE(right) == AOP_LIT){
5464           int t = (lit >> (offset*8)) & 0x0FFL;
5465           switch(t) { 
5466           case 0x00:
5467             pic14_emitcode("clrf","%s",
5468                            aopGet(AOP(result),offset,FALSE,FALSE));
5469             emitpcode(POC_CLRF,popGet(AOP(result),offset));
5470             break;
5471           case 0xff:
5472             pic14_emitcode("movf","%s,w",
5473                            aopGet(AOP(left),offset,FALSE,FALSE));
5474             pic14_emitcode("movwf","%s",
5475                            aopGet(AOP(result),offset,FALSE,FALSE));
5476             emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5477             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5478             break;
5479           default:
5480             pic14_emitcode("movlw","0x%x",t);
5481             pic14_emitcode("andwf","%s,w",
5482                            aopGet(AOP(left),offset,FALSE,FALSE));
5483             pic14_emitcode("movwf","%s",
5484                            aopGet(AOP(result),offset,FALSE,FALSE));
5485               
5486             emitpcode(POC_MOVLW, popGetLit(t));
5487             emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5488             emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5489           }
5490           continue;
5491         }
5492
5493         if (AOP_TYPE(left) == AOP_ACC) {
5494           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5495           emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5496         } else {
5497           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5498           pic14_emitcode("andwf","%s,w",
5499                          aopGet(AOP(left),offset,FALSE,FALSE));
5500           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5501           emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5502         }
5503         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5504         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5505       }
5506     }
5507   }
5508
5509   release :
5510     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5511   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5512   freeAsmop(result,NULL,ic,TRUE);     
5513 }
5514
5515 /*-----------------------------------------------------------------*/
5516 /* genOr  - code for or                                            */
5517 /*-----------------------------------------------------------------*/
5518 static void genOr (iCode *ic, iCode *ifx)
5519 {
5520     operand *left, *right, *result;
5521     int size, offset=0;
5522     unsigned long lit = 0L;
5523
5524     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5525
5526     aopOp((left = IC_LEFT(ic)),ic,FALSE);
5527     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5528     aopOp((result=IC_RESULT(ic)),ic,TRUE);
5529
5530     DEBUGpic14_AopType(__LINE__,left,right,result);
5531
5532     /* if left is a literal & right is not then exchange them */
5533     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5534         AOP_NEEDSACC(left)) {
5535         operand *tmp = right ;
5536         right = left;
5537         left = tmp;
5538     }
5539
5540     /* if result = right then exchange them */
5541     if(pic14_sameRegs(AOP(result),AOP(right))){
5542         operand *tmp = right ;
5543         right = left;
5544         left = tmp;
5545     }
5546
5547     /* if right is bit then exchange them */
5548     if (AOP_TYPE(right) == AOP_CRY &&
5549         AOP_TYPE(left) != AOP_CRY){
5550         operand *tmp = right ;
5551         right = left;
5552         left = tmp;
5553     }
5554
5555     DEBUGpic14_AopType(__LINE__,left,right,result);
5556
5557     if(AOP_TYPE(right) == AOP_LIT)
5558         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5559
5560     size = AOP_SIZE(result);
5561
5562     // if(bit | yy)
5563     // xx = bit | yy;
5564     if (AOP_TYPE(left) == AOP_CRY){
5565         if(AOP_TYPE(right) == AOP_LIT){
5566             // c = bit & literal;
5567             if(lit){
5568                 // lit != 0 => result = 1
5569                 if(AOP_TYPE(result) == AOP_CRY){
5570                   if(size)
5571                     emitpcode(POC_BSF, popGet(AOP(result),0));
5572                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5573                   //     AOP(result)->aopu.aop_dir,
5574                   //     AOP(result)->aopu.aop_dir);
5575                     else if(ifx)
5576                         continueIfTrue(ifx);
5577                     goto release;
5578                 }
5579             } else {
5580                 // lit == 0 => result = left
5581                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5582                     goto release;
5583                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5584             }
5585         } else {
5586             if (AOP_TYPE(right) == AOP_CRY){
5587               if(pic14_sameRegs(AOP(result),AOP(left))){
5588                 // c = bit | bit;
5589                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5590                 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5591                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5592
5593                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5594                          AOP(result)->aopu.aop_dir,
5595                          AOP(result)->aopu.aop_dir);
5596                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5597                          AOP(right)->aopu.aop_dir,
5598                          AOP(right)->aopu.aop_dir);
5599                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5600                          AOP(result)->aopu.aop_dir,
5601                          AOP(result)->aopu.aop_dir);
5602               } else {
5603                 if( AOP_TYPE(result) == AOP_ACC) {
5604                   emitpcode(POC_MOVLW, popGetLit(0));
5605                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5606                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5607                   emitpcode(POC_MOVLW, popGetLit(1));
5608
5609                 } else {
5610
5611                   emitpcode(POC_BCF,   popGet(AOP(result),0));
5612                   emitpcode(POC_BTFSS, popGet(AOP(right),0));
5613                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5614                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5615
5616                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5617                                  AOP(result)->aopu.aop_dir,
5618                                  AOP(result)->aopu.aop_dir);
5619                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5620                                  AOP(right)->aopu.aop_dir,
5621                                  AOP(right)->aopu.aop_dir);
5622                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5623                                  AOP(left)->aopu.aop_dir,
5624                                  AOP(left)->aopu.aop_dir);
5625                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5626                                  AOP(result)->aopu.aop_dir,
5627                                  AOP(result)->aopu.aop_dir);
5628                 }
5629               }
5630             } else {
5631                 // c = bit | val;
5632                 symbol *tlbl = newiTempLabel(NULL);
5633                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5634
5635
5636                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5637                 if( AOP_TYPE(right) == AOP_ACC) {
5638                   emitpcode(POC_IORLW, popGetLit(0));
5639                   emitSKPNZ;
5640                   emitpcode(POC_BTFSC, popGet(AOP(left),0));
5641                   emitpcode(POC_BSF,   popGet(AOP(result),0));
5642                 }
5643
5644
5645
5646                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5647                     pic14_emitcode(";XXX setb","c");
5648                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5649                          AOP(left)->aopu.aop_dir,tlbl->key+100);
5650                 pic14_toBoolean(right);
5651                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5652                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5653                     jmpTrueOrFalse(ifx, tlbl);
5654                     goto release;
5655                 } else {
5656                     CLRC;
5657                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5658                 }
5659             }
5660         }
5661         // bit = c
5662         // val = c
5663         if(size)
5664             pic14_outBitC(result);
5665         // if(bit | ...)
5666         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5667             genIfxJump(ifx, "c");           
5668         goto release ;
5669     }
5670
5671     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5672     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5673     if((AOP_TYPE(right) == AOP_LIT) &&
5674        (AOP_TYPE(result) == AOP_CRY) &&
5675        (AOP_TYPE(left) != AOP_CRY)){
5676         if(lit){
5677           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5678             // result = 1
5679             if(size)
5680                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5681             else 
5682                 continueIfTrue(ifx);
5683             goto release;
5684         } else {
5685           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5686             // lit = 0, result = boolean(left)
5687             if(size)
5688                 pic14_emitcode(";XXX setb","c");
5689             pic14_toBoolean(right);
5690             if(size){
5691                 symbol *tlbl = newiTempLabel(NULL);
5692                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5693                 CLRC;
5694                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5695             } else {
5696                 genIfxJump (ifx,"a");
5697                 goto release;
5698             }
5699         }
5700         pic14_outBitC(result);
5701         goto release ;
5702     }
5703
5704     /* if left is same as result */
5705     if(pic14_sameRegs(AOP(result),AOP(left))){
5706       int know_W = -1;
5707       for(;size--; offset++,lit>>=8) {
5708         if(AOP_TYPE(right) == AOP_LIT){
5709           if((lit & 0xff) == 0)
5710             /*  or'ing with 0 has no effect */
5711             continue;
5712           else {
5713             int p = my_powof2(lit & 0xff);
5714             if(p>=0) {
5715               /* only one bit is set in the literal, so use a bsf instruction */
5716               emitpcode(POC_BSF,
5717                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5718             } else {
5719               if(know_W != (lit & 0xff))
5720                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5721               know_W = lit & 0xff;
5722               emitpcode(POC_IORWF, popGet(AOP(left),offset));
5723             }
5724                     
5725           }
5726         } else {
5727           if (AOP_TYPE(left) == AOP_ACC) {
5728             emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5729             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5730           } else {                  
5731             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5732             emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5733
5734             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5735             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5736
5737           }
5738         }
5739       }
5740     } else {
5741         // left & result in different registers
5742         if(AOP_TYPE(result) == AOP_CRY){
5743             // result = bit
5744             // if(size), result in bit
5745             // if(!size && ifx), conditional oper: if(left | right)
5746             symbol *tlbl = newiTempLabel(NULL);
5747             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5748             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5749
5750
5751             if(size)
5752                 pic14_emitcode(";XXX setb","c");
5753             while(sizer--){
5754                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5755                 pic14_emitcode(";XXX orl","a,%s",
5756                          aopGet(AOP(left),offset,FALSE,FALSE));
5757                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5758                 offset++;
5759             }
5760             if(size){
5761                 CLRC;
5762                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5763                 pic14_outBitC(result);
5764             } else if(ifx)
5765                 jmpTrueOrFalse(ifx, tlbl);
5766         } else for(;(size--);offset++){
5767           // normal case
5768           // result = left & right
5769           if(AOP_TYPE(right) == AOP_LIT){
5770             int t = (lit >> (offset*8)) & 0x0FFL;
5771             switch(t) { 
5772             case 0x00:
5773               emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5774               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5775
5776               pic14_emitcode("movf","%s,w",
5777                        aopGet(AOP(left),offset,FALSE,FALSE));
5778               pic14_emitcode("movwf","%s",
5779                        aopGet(AOP(result),offset,FALSE,FALSE));
5780               break;
5781             default:
5782               emitpcode(POC_MOVLW,  popGetLit(t));
5783               emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5784               emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5785
5786               pic14_emitcode("movlw","0x%x",t);
5787               pic14_emitcode("iorwf","%s,w",
5788                        aopGet(AOP(left),offset,FALSE,FALSE));
5789               pic14_emitcode("movwf","%s",
5790                        aopGet(AOP(result),offset,FALSE,FALSE));
5791               
5792             }
5793             continue;
5794           }
5795
5796           // faster than result <- left, anl result,right
5797           // and better if result is SFR
5798           if (AOP_TYPE(left) == AOP_ACC) {
5799             emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5800             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5801           } else {
5802             emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5803             emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5804
5805             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5806             pic14_emitcode("iorwf","%s,w",
5807                      aopGet(AOP(left),offset,FALSE,FALSE));
5808           }
5809           emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5810           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5811         }
5812     }
5813
5814 release :
5815     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5816     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5817     freeAsmop(result,NULL,ic,TRUE);     
5818 }
5819
5820 /*-----------------------------------------------------------------*/
5821 /* genXor - code for xclusive or                                   */
5822 /*-----------------------------------------------------------------*/
5823 static void genXor (iCode *ic, iCode *ifx)
5824 {
5825   operand *left, *right, *result;
5826   int size, offset=0;
5827   unsigned long lit = 0L;
5828
5829   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5830
5831   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5832   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5833   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5834
5835   /* if left is a literal & right is not ||
5836      if left needs acc & right does not */
5837   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5838       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5839     operand *tmp = right ;
5840     right = left;
5841     left = tmp;
5842   }
5843
5844   /* if result = right then exchange them */
5845   if(pic14_sameRegs(AOP(result),AOP(right))){
5846     operand *tmp = right ;
5847     right = left;
5848     left = tmp;
5849   }
5850
5851   /* if right is bit then exchange them */
5852   if (AOP_TYPE(right) == AOP_CRY &&
5853       AOP_TYPE(left) != AOP_CRY){
5854     operand *tmp = right ;
5855     right = left;
5856     left = tmp;
5857   }
5858   if(AOP_TYPE(right) == AOP_LIT)
5859     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5860
5861   size = AOP_SIZE(result);
5862
5863   // if(bit ^ yy)
5864   // xx = bit ^ yy;
5865   if (AOP_TYPE(left) == AOP_CRY){
5866     if(AOP_TYPE(right) == AOP_LIT){
5867       // c = bit & literal;
5868       if(lit>>1){
5869         // lit>>1  != 0 => result = 1
5870         if(AOP_TYPE(result) == AOP_CRY){
5871           if(size)
5872             {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5873             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5874           else if(ifx)
5875             continueIfTrue(ifx);
5876           goto release;
5877         }
5878         pic14_emitcode("setb","c");
5879       } else{
5880         // lit == (0 or 1)
5881         if(lit == 0){
5882           // lit == 0, result = left
5883           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5884             goto release;
5885           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5886         } else{
5887           // lit == 1, result = not(left)
5888           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5889             emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5890             emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5891             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5892             goto release;
5893           } else {
5894             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5895             pic14_emitcode("cpl","c");
5896           }
5897         }
5898       }
5899
5900     } else {
5901       // right != literal
5902       symbol *tlbl = newiTempLabel(NULL);
5903       if (AOP_TYPE(right) == AOP_CRY){
5904         // c = bit ^ bit;
5905         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5906       }
5907       else{
5908         int sizer = AOP_SIZE(right);
5909         // c = bit ^ val
5910         // if val>>1 != 0, result = 1
5911         pic14_emitcode("setb","c");
5912         while(sizer){
5913           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5914           if(sizer == 1)
5915             // test the msb of the lsb
5916             pic14_emitcode("anl","a,#0xfe");
5917           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5918           sizer--;
5919         }
5920         // val = (0,1)
5921         pic14_emitcode("rrc","a");
5922       }
5923       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5924       pic14_emitcode("cpl","c");
5925       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5926     }
5927     // bit = c
5928     // val = c
5929     if(size)
5930       pic14_outBitC(result);
5931     // if(bit | ...)
5932     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5933       genIfxJump(ifx, "c");           
5934     goto release ;
5935   }
5936
5937   if(pic14_sameRegs(AOP(result),AOP(left))){
5938     /* if left is same as result */
5939     for(;size--; offset++) {
5940       if(AOP_TYPE(right) == AOP_LIT){
5941         int t  = (lit >> (offset*8)) & 0x0FFL;
5942         if(t == 0x00L)
5943           continue;
5944         else
5945           if (IS_AOP_PREG(left)) {
5946             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5947             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5948             aopPut(AOP(result),"a",offset);
5949           } else {
5950             emitpcode(POC_MOVLW, popGetLit(t));
5951             emitpcode(POC_XORWF,popGet(AOP(left),offset));
5952             pic14_emitcode("xrl","%s,%s",
5953                            aopGet(AOP(left),offset,FALSE,TRUE),
5954                            aopGet(AOP(right),offset,FALSE,FALSE));
5955           }
5956       } else {
5957         if (AOP_TYPE(left) == AOP_ACC)
5958           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5959         else {
5960           emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5961           emitpcode(POC_XORWF,popGet(AOP(left),offset));
5962 /*
5963           if (IS_AOP_PREG(left)) {
5964             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5965             aopPut(AOP(result),"a",offset);
5966           } else
5967             pic14_emitcode("xrl","%s,a",
5968                            aopGet(AOP(left),offset,FALSE,TRUE));
5969 */
5970         }
5971       }
5972     }
5973   } else {
5974     // left & result in different registers
5975     if(AOP_TYPE(result) == AOP_CRY){
5976       // result = bit
5977       // if(size), result in bit
5978       // if(!size && ifx), conditional oper: if(left ^ right)
5979       symbol *tlbl = newiTempLabel(NULL);
5980       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5981       if(size)
5982         pic14_emitcode("setb","c");
5983       while(sizer--){
5984         if((AOP_TYPE(right) == AOP_LIT) &&
5985            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5986           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5987         } else {
5988           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5989           pic14_emitcode("xrl","a,%s",
5990                          aopGet(AOP(left),offset,FALSE,FALSE));
5991         }
5992         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5993         offset++;
5994       }
5995       if(size){
5996         CLRC;
5997         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5998         pic14_outBitC(result);
5999       } else if(ifx)
6000         jmpTrueOrFalse(ifx, tlbl);
6001     } else for(;(size--);offset++){
6002       // normal case
6003       // result = left & right
6004       if(AOP_TYPE(right) == AOP_LIT){
6005         int t = (lit >> (offset*8)) & 0x0FFL;
6006         switch(t) { 
6007         case 0x00:
6008           emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6009           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6010           pic14_emitcode("movf","%s,w",
6011                          aopGet(AOP(left),offset,FALSE,FALSE));
6012           pic14_emitcode("movwf","%s",
6013                          aopGet(AOP(result),offset,FALSE,FALSE));
6014           break;
6015         case 0xff:
6016           emitpcode(POC_COMFW,popGet(AOP(left),offset));
6017           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6018           pic14_emitcode("comf","%s,w",
6019                          aopGet(AOP(left),offset,FALSE,FALSE));
6020           pic14_emitcode("movwf","%s",
6021                          aopGet(AOP(result),offset,FALSE,FALSE));
6022           break;
6023         default:
6024           emitpcode(POC_MOVLW, popGetLit(t));
6025           emitpcode(POC_XORFW,popGet(AOP(left),offset));
6026           emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027           pic14_emitcode("movlw","0x%x",t);
6028           pic14_emitcode("xorwf","%s,w",
6029                          aopGet(AOP(left),offset,FALSE,FALSE));
6030           pic14_emitcode("movwf","%s",
6031                          aopGet(AOP(result),offset,FALSE,FALSE));
6032
6033         }
6034         continue;
6035       }
6036
6037       // faster than result <- left, anl result,right
6038       // and better if result is SFR
6039       if (AOP_TYPE(left) == AOP_ACC) {
6040         emitpcode(POC_XORFW,popGet(AOP(right),offset));
6041         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6042       } else {
6043         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6044         emitpcode(POC_XORFW,popGet(AOP(left),offset));
6045         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6046         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6047       }
6048       if ( AOP_TYPE(result) != AOP_ACC){
6049         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6050         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6051       }
6052     }
6053   }
6054
6055   release :
6056     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6057   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6058   freeAsmop(result,NULL,ic,TRUE);     
6059 }
6060
6061 /*-----------------------------------------------------------------*/
6062 /* genInline - write the inline code out                           */
6063 /*-----------------------------------------------------------------*/
6064 static void genInline (iCode *ic)
6065 {
6066     char *buffer, *bp, *bp1;
6067     
6068     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6069
6070     _G.inLine += (!options.asmpeep);
6071
6072     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6073     strcpy(buffer,IC_INLINE(ic));
6074
6075     /* emit each line as a code */
6076     while (*bp) {
6077         if (*bp == '\n') {
6078             *bp++ = '\0';
6079
6080             if(*bp1)
6081               addpCode2pBlock(pb,AssembleLine(bp1));
6082             bp1 = bp;
6083         } else {
6084             if (*bp == ':') {
6085                 bp++;
6086                 *bp = '\0';
6087                 bp++;
6088                 pic14_emitcode(bp1,"");
6089                 bp1 = bp;
6090             } else
6091                 bp++;
6092         }
6093     }
6094     if ((bp1 != bp) && *bp1)
6095       addpCode2pBlock(pb,AssembleLine(bp1));
6096
6097     Safe_free(buffer);
6098
6099     _G.inLine -= (!options.asmpeep);
6100 }
6101
6102 /*-----------------------------------------------------------------*/
6103 /* genRRC - rotate right with carry                                */
6104 /*-----------------------------------------------------------------*/
6105 static void genRRC (iCode *ic)
6106 {
6107   operand *left , *result ;
6108   int size, offset = 0, same;
6109
6110   /* rotate right with carry */
6111   left = IC_LEFT(ic);
6112   result=IC_RESULT(ic);
6113   aopOp (left,ic,FALSE);
6114   aopOp (result,ic,FALSE);
6115
6116   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6117
6118   same = pic14_sameRegs(AOP(result),AOP(left));
6119
6120   size = AOP_SIZE(result);    
6121
6122   /* get the lsb and put it into the carry */
6123   emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6124
6125   offset = 0 ;
6126
6127   while(size--) {
6128
6129     if(same) {
6130       emitpcode(POC_RRF, popGet(AOP(left),offset));
6131     } else {
6132       emitpcode(POC_RRFW, popGet(AOP(left),offset));
6133       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6134     }
6135
6136     offset++;
6137   }
6138
6139   freeAsmop(left,NULL,ic,TRUE);
6140   freeAsmop(result,NULL,ic,TRUE);
6141 }
6142
6143 /*-----------------------------------------------------------------*/
6144 /* genRLC - generate code for rotate left with carry               */
6145 /*-----------------------------------------------------------------*/
6146 static void genRLC (iCode *ic)
6147 {    
6148   operand *left , *result ;
6149   int size, offset = 0;
6150   int same;
6151
6152   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6153   /* rotate right with carry */
6154   left = IC_LEFT(ic);
6155   result=IC_RESULT(ic);
6156   aopOp (left,ic,FALSE);
6157   aopOp (result,ic,FALSE);
6158
6159   DEBUGpic14_AopType(__LINE__,left,NULL,result);
6160
6161   same = pic14_sameRegs(AOP(result),AOP(left));
6162
6163   /* move it to the result */
6164   size = AOP_SIZE(result);    
6165
6166   /* get the msb and put it into the carry */
6167   emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6168
6169   offset = 0 ;
6170
6171   while(size--) {
6172
6173     if(same) {
6174       emitpcode(POC_RLF, popGet(AOP(left),offset));
6175     } else {
6176       emitpcode(POC_RLFW, popGet(AOP(left),offset));
6177       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6178     }
6179
6180     offset++;
6181   }
6182
6183
6184   freeAsmop(left,NULL,ic,TRUE);
6185   freeAsmop(result,NULL,ic,TRUE);
6186 }
6187
6188 /*-----------------------------------------------------------------*/
6189 /* genGetHbit - generates code get highest order bit               */
6190 /*-----------------------------------------------------------------*/
6191 static void genGetHbit (iCode *ic)
6192 {
6193     operand *left, *result;
6194     left = IC_LEFT(ic);
6195     result=IC_RESULT(ic);
6196     aopOp (left,ic,FALSE);
6197     aopOp (result,ic,FALSE);
6198
6199     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6200     /* get the highest order byte into a */
6201     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6202     if(AOP_TYPE(result) == AOP_CRY){
6203         pic14_emitcode("rlc","a");
6204         pic14_outBitC(result);
6205     }
6206     else{
6207         pic14_emitcode("rl","a");
6208         pic14_emitcode("anl","a,#0x01");
6209         pic14_outAcc(result);
6210     }
6211
6212
6213     freeAsmop(left,NULL,ic,TRUE);
6214     freeAsmop(result,NULL,ic,TRUE);
6215 }
6216
6217 /*-----------------------------------------------------------------*/
6218 /* AccRol - rotate left accumulator by known count                 */
6219 /*-----------------------------------------------------------------*/
6220 static void AccRol (int shCount)
6221 {
6222     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6223     shCount &= 0x0007;              // shCount : 0..7
6224     switch(shCount){
6225         case 0 :
6226             break;
6227         case 1 :
6228             pic14_emitcode("rl","a");
6229             break;
6230         case 2 :
6231             pic14_emitcode("rl","a");
6232             pic14_emitcode("rl","a");
6233             break;
6234         case 3 :
6235             pic14_emitcode("swap","a");
6236             pic14_emitcode("rr","a");
6237             break;
6238         case 4 :
6239             pic14_emitcode("swap","a");
6240             break;
6241         case 5 :
6242             pic14_emitcode("swap","a");
6243             pic14_emitcode("rl","a");
6244             break;
6245         case 6 :
6246             pic14_emitcode("rr","a");
6247             pic14_emitcode("rr","a");
6248             break;
6249         case 7 :
6250             pic14_emitcode("rr","a");
6251             break;
6252     }
6253 }
6254
6255 /*-----------------------------------------------------------------*/
6256 /* AccLsh - left shift accumulator by known count                  */
6257 /*-----------------------------------------------------------------*/
6258 static void AccLsh (int shCount)
6259 {
6260     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6261     if(shCount != 0){
6262         if(shCount == 1)
6263             pic14_emitcode("add","a,acc");
6264         else 
6265             if(shCount == 2) {
6266             pic14_emitcode("add","a,acc");
6267             pic14_emitcode("add","a,acc");
6268         } else {
6269             /* rotate left accumulator */
6270             AccRol(shCount);
6271             /* and kill the lower order bits */
6272             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6273         }
6274     }
6275 }
6276
6277 /*-----------------------------------------------------------------*/
6278 /* AccRsh - right shift accumulator by known count                 */
6279 /*-----------------------------------------------------------------*/
6280 static void AccRsh (int shCount)
6281 {
6282     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6283     if(shCount != 0){
6284         if(shCount == 1){
6285             CLRC;
6286             pic14_emitcode("rrc","a");
6287         } else {
6288             /* rotate right accumulator */
6289             AccRol(8 - shCount);
6290             /* and kill the higher order bits */
6291             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6292         }
6293     }
6294 }
6295
6296 #if 0
6297 /*-----------------------------------------------------------------*/
6298 /* AccSRsh - signed right shift accumulator by known count                 */
6299 /*-----------------------------------------------------------------*/
6300 static void AccSRsh (int shCount)
6301 {
6302     symbol *tlbl ;
6303     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6304     if(shCount != 0){
6305         if(shCount == 1){
6306             pic14_emitcode("mov","c,acc.7");
6307             pic14_emitcode("rrc","a");
6308         } else if(shCount == 2){
6309             pic14_emitcode("mov","c,acc.7");
6310             pic14_emitcode("rrc","a");
6311             pic14_emitcode("mov","c,acc.7");
6312             pic14_emitcode("rrc","a");
6313         } else {
6314             tlbl = newiTempLabel(NULL);
6315             /* rotate right accumulator */
6316             AccRol(8 - shCount);
6317             /* and kill the higher order bits */
6318             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6319             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6320             pic14_emitcode("orl","a,#0x%02x",
6321                      (unsigned char)~SRMask[shCount]);
6322             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6323         }
6324     }
6325 }
6326 #endif
6327 /*-----------------------------------------------------------------*/
6328 /* shiftR1Left2Result - shift right one byte from left to result   */
6329 /*-----------------------------------------------------------------*/
6330 static void shiftR1Left2ResultSigned (operand *left, int offl,
6331                                 operand *result, int offr,
6332                                 int shCount)
6333 {
6334   int same;
6335
6336   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6337
6338   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6339
6340   switch(shCount) {
6341   case 1:
6342     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6343     if(same) 
6344       emitpcode(POC_RRF, popGet(AOP(result),offr));
6345     else {
6346       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6347       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6348     }
6349
6350     break;
6351   case 2:
6352
6353     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6354     if(same) 
6355       emitpcode(POC_RRF, popGet(AOP(result),offr));
6356     else {
6357       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6358       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6359     }
6360     emitpcode(POC_RLFW, popGet(AOP(result),offr));
6361     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6362
6363     break;
6364
6365   case 3:
6366     if(same)
6367       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6368     else {
6369       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6370       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6371     }
6372
6373     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6374     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6375     emitpcode(POC_ANDLW, popGetLit(0x1f));
6376
6377     emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6378     emitpcode(POC_IORLW, popGetLit(0xe0));
6379
6380     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6381     break;
6382
6383   case 4:
6384     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6385     emitpcode(POC_ANDLW,  popGetLit(0x0f));
6386     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6387     emitpcode(POC_IORLW,  popGetLit(0xf0));
6388     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6389     break;
6390   case 5:
6391     if(same) {
6392       emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6393     } else {
6394       emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6395       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6396     }
6397     emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6398     emitpcode(POC_ANDLW,  popGetLit(0x07));
6399     emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6400     emitpcode(POC_IORLW,  popGetLit(0xf8));
6401     emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6402     break;
6403
6404   case 6:
6405     if(same) {
6406       emitpcode(POC_MOVLW, popGetLit(0x00));
6407       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6408       emitpcode(POC_MOVLW, popGetLit(0xfe));
6409       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6410       emitpcode(POC_IORLW, popGetLit(0x01));
6411       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6412     } else {
6413       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6414       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6415       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6416       emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6417       emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6418     }
6419     break;
6420
6421   case 7:
6422     if(same) {
6423       emitpcode(POC_MOVLW, popGetLit(0x00));
6424       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6425       emitpcode(POC_MOVLW, popGetLit(0xff));
6426       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427     } else {
6428       emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6429       emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6430       emitpcode(POC_DECF,  popGet(AOP(result),offr));
6431     }
6432
6433   default:
6434     break;
6435   }
6436 }
6437
6438 /*-----------------------------------------------------------------*/
6439 /* shiftR1Left2Result - shift right one byte from left to result   */
6440 /*-----------------------------------------------------------------*/
6441 static void shiftR1Left2Result (operand *left, int offl,
6442                                 operand *result, int offr,
6443                                 int shCount, int sign)
6444 {
6445   int same;
6446
6447   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6448
6449   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6450
6451   /* Copy the msb into the carry if signed. */
6452   if(sign) {
6453     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6454     return;
6455   }
6456
6457
6458
6459   switch(shCount) {
6460   case 1:
6461     emitCLRC;
6462     if(same) 
6463       emitpcode(POC_RRF, popGet(AOP(result),offr));
6464     else {
6465       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6466       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6467     }
6468     break;
6469   case 2:
6470     emitCLRC;
6471     if(same) {
6472       emitpcode(POC_RRF, popGet(AOP(result),offr));
6473     } else {
6474       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6476     }
6477     emitCLRC;
6478     emitpcode(POC_RRF, popGet(AOP(result),offr));
6479
6480     break;
6481   case 3:
6482     if(same)
6483       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6484     else {
6485       emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6486       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6487     }
6488
6489     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6490     emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6491     emitpcode(POC_ANDLW, popGetLit(0x1f));
6492     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6493     break;
6494       
6495   case 4:
6496     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6497     emitpcode(POC_ANDLW, popGetLit(0x0f));
6498     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6499     break;
6500
6501   case 5:
6502     emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6503     emitpcode(POC_ANDLW, popGetLit(0x0f));
6504     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505     emitCLRC;
6506     emitpcode(POC_RRF, popGet(AOP(result),offr));
6507
6508     break;
6509   case 6:
6510
6511     emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6512     emitpcode(POC_ANDLW, popGetLit(0x80));
6513     emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6515     emitpcode(POC_RLF,   popGet(AOP(result),offr));
6516     break;
6517
6518   case 7:
6519
6520     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6521     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6522     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6523
6524     break;
6525
6526   default:
6527     break;
6528   }
6529 }
6530
6531 /*-----------------------------------------------------------------*/
6532 /* shiftL1Left2Result - shift left one byte from left to result    */
6533 /*-----------------------------------------------------------------*/
6534 static void shiftL1Left2Result (operand *left, int offl,
6535                                 operand *result, int offr, int shCount)
6536 {
6537   int same;
6538
6539   //    char *l;
6540   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6541
6542   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6543   DEBUGpic14_emitcode ("; ***","same =  %d",same);
6544     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6545     //    MOVA(l);
6546     /* shift left accumulator */
6547     //AccLsh(shCount); // don't comment out just yet...
6548   //    aopPut(AOP(result),"a",offr);
6549
6550   switch(shCount) {
6551   case 1:
6552     /* Shift left 1 bit position */
6553     emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6554     if(same) {
6555       emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6556     } else {
6557       emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6558       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6559     }
6560     break;
6561   case 2:
6562     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6563     emitpcode(POC_ANDLW,popGetLit(0x7e));
6564     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6565     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6566     break;
6567   case 3:
6568     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6569     emitpcode(POC_ANDLW,popGetLit(0x3e));
6570     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6571     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6572     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6573     break;
6574   case 4:
6575     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6576     emitpcode(POC_ANDLW, popGetLit(0xf0));
6577     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6578     break;
6579   case 5:
6580     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6581     emitpcode(POC_ANDLW, popGetLit(0xf0));
6582     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6583     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6584     break;
6585   case 6:
6586     emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6587     emitpcode(POC_ANDLW, popGetLit(0x30));
6588     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589     emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6590     emitpcode(POC_RLF,  popGet(AOP(result),offr));
6591     break;
6592   case 7:
6593     emitpcode(POC_RRFW, popGet(AOP(left),offl));
6594     emitpcode(POC_CLRF, popGet(AOP(result),offr));
6595     emitpcode(POC_RRF,  popGet(AOP(result),offr));
6596     break;
6597
6598   default:
6599     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6600   }
6601
6602 }
6603
6604 /*-----------------------------------------------------------------*/
6605 /* movLeft2Result - move byte from left to result                  */
6606 /*-----------------------------------------------------------------*/
6607 static void movLeft2Result (operand *left, int offl,
6608                             operand *result, int offr)
6609 {
6610   char *l;
6611   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6612   if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6613     l = aopGet(AOP(left),offl,FALSE,FALSE);
6614
6615     if (*l == '@' && (IS_AOP_PREG(result))) {
6616       pic14_emitcode("mov","a,%s",l);
6617       aopPut(AOP(result),"a",offr);
6618     } else {
6619       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6620       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6621     }
6622   }
6623 }
6624
6625 /*-----------------------------------------------------------------*/
6626 /* shiftL2Left2Result - shift left two bytes from left to result   */
6627 /*-----------------------------------------------------------------*/
6628 static void shiftL2Left2Result (operand *left, int offl,
6629                                 operand *result, int offr, int shCount)
6630 {
6631
6632
6633   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6634
6635   if(pic14_sameRegs(AOP(result), AOP(left))) {
6636     switch(shCount) {
6637     case 0:
6638       break;
6639     case 1:
6640     case 2:
6641     case 3:
6642
6643       emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6644       emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6645       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6646
6647       while(--shCount) {
6648         emitCLRC;
6649         emitpcode(POC_RLF, popGet(AOP(result),offr));
6650         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6651       }
6652
6653       break;
6654     case 4:
6655     case 5:
6656       emitpcode(POC_MOVLW, popGetLit(0x0f));
6657       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6658       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6659       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6660       emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6661       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6662       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6663       if(shCount >=5) {
6664         emitpcode(POC_RLF, popGet(AOP(result),offr));
6665         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6666       }
6667       break;
6668     case 6:
6669       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6670       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6671       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6672       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6673       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6674       emitpcode(POC_ANDLW,popGetLit(0xc0));
6675       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6676       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6677       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6678       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6679       break;
6680     case 7:
6681       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682       emitpcode(POC_RRFW, popGet(AOP(result),offr));
6683       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6684       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6685       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6686     }
6687
6688   } else {
6689     switch(shCount) {
6690     case 0:
6691       break;
6692     case 1:
6693     case 2:
6694     case 3:
6695       /* note, use a mov/add for the shift since the mov has a
6696          chance of getting optimized out */
6697       emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6698       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6699       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6700       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6701       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6702
6703       while(--shCount) {
6704         emitCLRC;
6705         emitpcode(POC_RLF, popGet(AOP(result),offr));
6706         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6707       }
6708       break;
6709
6710     case 4:
6711     case 5:
6712       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6713       emitpcode(POC_ANDLW, popGetLit(0xF0));
6714       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6715       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6716       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6717       emitpcode(POC_ANDLW, popGetLit(0xF0));
6718       emitpcode(POC_XORWF, popGet(AOP(result),offr));
6719       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6720
6721
6722       if(shCount == 5) {
6723         emitpcode(POC_RLF, popGet(AOP(result),offr));
6724         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6725       }
6726       break;
6727     case 6:
6728       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6729       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6730       emitpcode(POC_RRFW, popGet(AOP(result),offl));
6731       emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6732
6733       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6734       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6735       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6736       emitpcode(POC_ANDLW,popGetLit(0xc0));
6737       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6738       emitpcode(POC_XORWF,popGet(AOP(result),offr));
6739       emitpcode(POC_XORFW,popGet(AOP(result),offr));
6740       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6741       break;
6742     case 7:
6743       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6744       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6745       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746       emitpcode(POC_CLRF, popGet(AOP(result),offr));
6747       emitpcode(POC_RRF,  popGet(AOP(result),offr));
6748     }
6749   }
6750
6751 }
6752 /*-----------------------------------------------------------------*/
6753 /* shiftR2Left2Result - shift right two bytes from left to result  */
6754 /*-----------------------------------------------------------------*/
6755 static void shiftR2Left2Result (operand *left, int offl,
6756                                 operand *result, int offr,
6757                                 int shCount, int sign)
6758 {
6759   int same=0;
6760
6761   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6762   same = pic14_sameRegs(AOP(result), AOP(left));
6763
6764   if(same && ((offl + MSB16) == offr)){
6765     same=1;
6766     /* don't crash result[offr] */
6767     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6768     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6769   }
6770 /* else {
6771     movLeft2Result(left,offl, result, offr);
6772     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6773   }
6774 */
6775   /* a:x >> shCount (x = lsb(result))*/
6776 /*
6777   if(sign)
6778     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6779   else {
6780     AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6781 */
6782   switch(shCount) {
6783   case 0:
6784     break;
6785   case 1:
6786   case 2:
6787   case 3:
6788     if(sign)
6789       emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6790     else
6791       emitCLRC;
6792
6793     if(same) {
6794       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6795       emitpcode(POC_RRF,popGet(AOP(result),offr));
6796     } else {
6797       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6798       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6799       emitpcode(POC_RRFW, popGet(AOP(left),offl));
6800       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6801     }
6802
6803     while(--shCount) {
6804       if(sign)
6805         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6806       else
6807         emitCLRC;
6808       emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6809       emitpcode(POC_RRF,popGet(AOP(result),offr));
6810     }
6811     break;
6812   case 4:
6813   case 5:
6814     if(same) {
6815
6816       emitpcode(POC_MOVLW, popGetLit(0xf0));
6817       emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6818       emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6819
6820       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6821       emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6822       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6823       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6824     } else {
6825       emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6826       emitpcode(POC_ANDLW, popGetLit(0x0f));
6827       emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6828
6829       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6830       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6831       emitpcode(POC_ANDLW, popGetLit(0xf0));
6832       emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6833       emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6834     }
6835
6836     if(shCount >=5) {
6837       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6838       emitpcode(POC_RRF, popGet(AOP(result),offr));
6839     }
6840
6841     if(sign) {
6842       emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6843       emitpcode(POC_BTFSC, 
6844                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6845       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6846     }
6847
6848     break;
6849
6850   case 6:
6851     if(same) {
6852
6853       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6854       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6855
6856       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6857       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6858       emitpcode(POC_RLFW, popGet(AOP(result),offr));
6859       emitpcode(POC_ANDLW,popGetLit(0x03));
6860       if(sign) {
6861         emitpcode(POC_BTFSC, 
6862                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6863         emitpcode(POC_IORLW,popGetLit(0xfc));
6864       }
6865       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6866       emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6867       emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6868       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6869     } else {
6870       emitpcode(POC_RLFW, popGet(AOP(left),offl));
6871       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6872       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6873       emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6874       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6875       emitpcode(POC_RLF,  popGet(AOP(result),offr));
6876       emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6877       emitpcode(POC_ANDLW,popGetLit(0x03));
6878       if(sign) {
6879         emitpcode(POC_BTFSC, 
6880                   newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6881         emitpcode(POC_IORLW,popGetLit(0xfc));
6882       }
6883       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6884       //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6885
6886         
6887     }
6888
6889     break;
6890   case 7:
6891     emitpcode(POC_RLFW, popGet(AOP(left),offl));
6892     emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6893     emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6894     emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6895     if(sign) {
6896       emitSKPNC;
6897       emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6898     } else 
6899       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6900   }
6901 }
6902
6903
6904 /*-----------------------------------------------------------------*/
6905 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6906 /*-----------------------------------------------------------------*/
6907 static void shiftLLeftOrResult (operand *left, int offl,
6908                                 operand *result, int offr, int shCount)
6909 {
6910     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6911     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6912     /* shift left accumulator */
6913     AccLsh(shCount);
6914     /* or with result */
6915     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6916     /* back to result */
6917     aopPut(AOP(result),"a",offr);
6918 }
6919
6920 /*-----------------------------------------------------------------*/
6921 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftRLeftOrResult (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 right accumulator */
6929     AccRsh(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 /* genlshOne - left shift a one byte quantity by known count       */
6938 /*-----------------------------------------------------------------*/
6939 static void genlshOne (operand *result, operand *left, int shCount)
6940 {       
6941     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6942     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6943 }
6944
6945 /*-----------------------------------------------------------------*/
6946 /* genlshTwo - left shift two bytes by known amount != 0           */
6947 /*-----------------------------------------------------------------*/
6948 static void genlshTwo (operand *result,operand *left, int shCount)
6949 {
6950     int size;
6951     
6952     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6953     size = pic14_getDataSize(result);
6954
6955     /* if shCount >= 8 */
6956     if (shCount >= 8) {
6957         shCount -= 8 ;
6958
6959         if (size > 1){
6960             if (shCount)
6961                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6962             else 
6963                 movLeft2Result(left, LSB, result, MSB16);
6964         }
6965         emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6966     }
6967
6968     /*  1 <= shCount <= 7 */
6969     else {  
6970         if(size == 1)
6971             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6972         else 
6973             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6974     }
6975 }
6976
6977 /*-----------------------------------------------------------------*/
6978 /* shiftLLong - shift left one long from left to result            */
6979 /* offl = LSB or MSB16                                             */
6980 /*-----------------------------------------------------------------*/
6981 static void shiftLLong (operand *left, operand *result, int offr )
6982 {
6983     char *l;
6984     int size = AOP_SIZE(result);
6985
6986     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6987     if(size >= LSB+offr){
6988         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6989         MOVA(l);
6990         pic14_emitcode("add","a,acc");
6991         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6992             size >= MSB16+offr && offr != LSB )
6993             pic14_emitcode("xch","a,%s",
6994                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6995         else        
6996             aopPut(AOP(result),"a",LSB+offr);
6997     }
6998
6999     if(size >= MSB16+offr){
7000         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7001             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7002             MOVA(l);
7003         }
7004         pic14_emitcode("rlc","a");
7005         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7006             size >= MSB24+offr && offr != LSB)
7007             pic14_emitcode("xch","a,%s",
7008                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7009         else        
7010             aopPut(AOP(result),"a",MSB16+offr);
7011     }
7012
7013     if(size >= MSB24+offr){
7014         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7015             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7016             MOVA(l);
7017         }
7018         pic14_emitcode("rlc","a");
7019         if (pic14_sameRegs(AOP(left),AOP(result)) && 
7020             size >= MSB32+offr && offr != LSB )
7021             pic14_emitcode("xch","a,%s",
7022                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7023         else        
7024             aopPut(AOP(result),"a",MSB24+offr);
7025     }
7026
7027     if(size > MSB32+offr){
7028         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7029             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7030             MOVA(l);    
7031         }
7032         pic14_emitcode("rlc","a");
7033         aopPut(AOP(result),"a",MSB32+offr);
7034     }
7035     if(offr != LSB)
7036         aopPut(AOP(result),zero,LSB);       
7037 }
7038
7039 /*-----------------------------------------------------------------*/
7040 /* genlshFour - shift four byte by a known amount != 0             */
7041 /*-----------------------------------------------------------------*/
7042 static void genlshFour (operand *result, operand *left, int shCount)
7043 {
7044     int size;
7045
7046     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7047     size = AOP_SIZE(result);
7048
7049     /* if shifting more that 3 bytes */
7050     if (shCount >= 24 ) {
7051         shCount -= 24;
7052         if (shCount)
7053             /* lowest order of left goes to the highest
7054             order of the destination */
7055             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7056         else
7057             movLeft2Result(left, LSB, result, MSB32);
7058         aopPut(AOP(result),zero,LSB);
7059         aopPut(AOP(result),zero,MSB16);
7060         aopPut(AOP(result),zero,MSB32);
7061         return;
7062     }
7063
7064     /* more than two bytes */
7065     else if ( shCount >= 16 ) {
7066         /* lower order two bytes goes to higher order two bytes */
7067         shCount -= 16;
7068         /* if some more remaining */
7069         if (shCount)
7070             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7071         else {
7072             movLeft2Result(left, MSB16, result, MSB32);
7073             movLeft2Result(left, LSB, result, MSB24);
7074         }
7075         aopPut(AOP(result),zero,MSB16);
7076         aopPut(AOP(result),zero,LSB);
7077         return;
7078     }    
7079
7080     /* if more than 1 byte */
7081     else if ( shCount >= 8 ) {
7082         /* lower order three bytes goes to higher order  three bytes */
7083         shCount -= 8;
7084         if(size == 2){
7085             if(shCount)
7086                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7087             else
7088                 movLeft2Result(left, LSB, result, MSB16);
7089         }
7090         else{   /* size = 4 */
7091             if(shCount == 0){
7092                 movLeft2Result(left, MSB24, result, MSB32);
7093                 movLeft2Result(left, MSB16, result, MSB24);
7094                 movLeft2Result(left, LSB, result, MSB16);
7095                 aopPut(AOP(result),zero,LSB);
7096             }
7097             else if(shCount == 1)
7098                 shiftLLong(left, result, MSB16);
7099             else{
7100                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7101                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7102                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7103                 aopPut(AOP(result),zero,LSB);
7104             }
7105         }
7106     }
7107
7108     /* 1 <= shCount <= 7 */
7109     else if(shCount <= 2){
7110         shiftLLong(left, result, LSB);
7111         if(shCount == 2)
7112             shiftLLong(result, result, LSB);
7113     }
7114     /* 3 <= shCount <= 7, optimize */
7115     else{
7116         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7117         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7118         shiftL2Left2Result(left, LSB, result, LSB, shCount);
7119     }
7120 }
7121
7122 /*-----------------------------------------------------------------*/
7123 /* genLeftShiftLiteral - left shifting by known count              */
7124 /*-----------------------------------------------------------------*/
7125 static void genLeftShiftLiteral (operand *left,
7126                                  operand *right,
7127                                  operand *result,
7128                                  iCode *ic)
7129 {    
7130     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7131     int size;
7132
7133     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7134     freeAsmop(right,NULL,ic,TRUE);
7135
7136     aopOp(left,ic,FALSE);
7137     aopOp(result,ic,FALSE);
7138
7139     size = getSize(operandType(result));
7140
7141 #if VIEW_SIZE
7142     pic14_emitcode("; shift left ","result %d, left %d",size,
7143              AOP_SIZE(left));
7144 #endif
7145
7146     /* I suppose that the left size >= result size */
7147     if(shCount == 0){
7148         while(size--){
7149             movLeft2Result(left, size, result, size);
7150         }
7151     }
7152
7153     else if(shCount >= (size * 8))
7154         while(size--)
7155             aopPut(AOP(result),zero,size);
7156     else{
7157         switch (size) {
7158             case 1:
7159                 genlshOne (result,left,shCount);
7160                 break;
7161
7162             case 2:
7163             case 3:
7164                 genlshTwo (result,left,shCount);
7165                 break;
7166
7167             case 4:
7168                 genlshFour (result,left,shCount);
7169                 break;
7170         }
7171     }
7172     freeAsmop(left,NULL,ic,TRUE);
7173     freeAsmop(result,NULL,ic,TRUE);
7174 }
7175
7176 /*-----------------------------------------------------------------*
7177  * genMultiAsm - repeat assembly instruction for size of register.
7178  * if endian == 1, then the high byte (i.e base address + size of 
7179  * register) is used first else the low byte is used first;
7180  *-----------------------------------------------------------------*/
7181 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7182 {
7183
7184   int offset = 0;
7185
7186   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7187
7188   if(!reg)
7189     return;
7190
7191   if(!endian) {
7192     endian = 1;
7193   } else {
7194     endian = -1;
7195     offset = size-1;
7196   }
7197
7198   while(size--) {
7199     emitpcode(poc,    popGet(AOP(reg),offset));
7200     offset += endian;
7201   }
7202
7203 }
7204 /*-----------------------------------------------------------------*/
7205 /* genLeftShift - generates code for left shifting                 */
7206 /*-----------------------------------------------------------------*/
7207 static void genLeftShift (iCode *ic)
7208 {
7209   operand *left,*right, *result;
7210   int size, offset;
7211   char *l;
7212   symbol *tlbl , *tlbl1;
7213   pCodeOp *pctemp;
7214
7215   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7216
7217   right = IC_RIGHT(ic);
7218   left  = IC_LEFT(ic);
7219   result = IC_RESULT(ic);
7220
7221   aopOp(right,ic,FALSE);
7222
7223   /* if the shift count is known then do it 
7224      as efficiently as possible */
7225   if (AOP_TYPE(right) == AOP_LIT) {
7226     genLeftShiftLiteral (left,right,result,ic);
7227     return ;
7228   }
7229
7230   /* shift count is unknown then we have to form 
7231      a loop get the loop count in B : Note: we take
7232      only the lower order byte since shifting
7233      more that 32 bits make no sense anyway, ( the
7234      largest size of an object can be only 32 bits ) */  
7235
7236     
7237   aopOp(left,ic,FALSE);
7238   aopOp(result,ic,FALSE);
7239
7240   /* now move the left to the result if they are not the
7241      same */
7242   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7243       AOP_SIZE(result) > 1) {
7244
7245     size = AOP_SIZE(result);
7246     offset=0;
7247     while (size--) {
7248       l = aopGet(AOP(left),offset,FALSE,TRUE);
7249       if (*l == '@' && (IS_AOP_PREG(result))) {
7250
7251         pic14_emitcode("mov","a,%s",l);
7252         aopPut(AOP(result),"a",offset);
7253       } else {
7254         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7255         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7256         //aopPut(AOP(result),l,offset);
7257       }
7258       offset++;
7259     }
7260   }
7261
7262   size = AOP_SIZE(result);
7263
7264   /* if it is only one byte then */
7265   if (size == 1) {
7266     if(optimized_for_speed) {
7267       emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7268       emitpcode(POC_ANDLW,  popGetLit(0xf0));
7269       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7270       emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7271       emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7272       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7273       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7274       emitpcode(POC_RLFW,   popGet(AOP(result),0));
7275       emitpcode(POC_ANDLW,  popGetLit(0xfe));
7276       emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7277       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7278       emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7279     } else {
7280
7281       tlbl = newiTempLabel(NULL);
7282       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7283         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7284         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7285       }
7286
7287       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7288       emitpcode(POC_RRF,    popGet(AOP(result),0));
7289       emitpLabel(tlbl->key);
7290       emitpcode(POC_RLF,    popGet(AOP(result),0));
7291       emitpcode(POC_ADDLW,  popGetLit(1));
7292       emitSKPC;
7293       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7294     }
7295     goto release ;
7296   }
7297     
7298   if (pic14_sameRegs(AOP(left),AOP(result))) {
7299
7300     tlbl = newiTempLabel(NULL);
7301     emitpcode(POC_COMFW,  popGet(AOP(right),0));
7302     genMultiAsm(POC_RRF, result, size,1);
7303     emitpLabel(tlbl->key);
7304     genMultiAsm(POC_RLF, result, size,0);
7305     emitpcode(POC_ADDLW,  popGetLit(1));
7306     emitSKPC;
7307     emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7308     goto release;
7309   }
7310
7311   //tlbl = newiTempLabel(NULL);
7312   //offset = 0 ;   
7313   //tlbl1 = newiTempLabel(NULL);
7314
7315   //reAdjustPreg(AOP(result));    
7316     
7317   //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7318   //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7319   //l = aopGet(AOP(result),offset,FALSE,FALSE);
7320   //MOVA(l);
7321   //pic14_emitcode("add","a,acc");         
7322   //aopPut(AOP(result),"a",offset++);
7323   //while (--size) {
7324   //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7325   //  MOVA(l);
7326   //  pic14_emitcode("rlc","a");         
7327   //  aopPut(AOP(result),"a",offset++);
7328   //}
7329   //reAdjustPreg(AOP(result));
7330
7331   //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7332   //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7333
7334
7335   tlbl = newiTempLabel(NULL);
7336   tlbl1= newiTempLabel(NULL);
7337
7338   size = AOP_SIZE(result);
7339   offset = 1;
7340
7341   pctemp = popGetTempReg();  /* grab a temporary working register. */
7342
7343   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7344
7345   /* offset should be 0, 1 or 3 */
7346   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7347   emitSKPNZ;
7348   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7349
7350   emitpcode(POC_MOVWF, pctemp);
7351
7352
7353   emitpLabel(tlbl->key);
7354
7355   emitCLRC;
7356   emitpcode(POC_RLF,  popGet(AOP(result),0));
7357   while(--size)
7358     emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7359
7360   emitpcode(POC_DECFSZ,  pctemp);
7361   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7362   emitpLabel(tlbl1->key);
7363
7364   popReleaseTempReg(pctemp);
7365
7366
7367  release:
7368   freeAsmop (right,NULL,ic,TRUE);
7369   freeAsmop(left,NULL,ic,TRUE);
7370   freeAsmop(result,NULL,ic,TRUE);
7371 }
7372
7373 /*-----------------------------------------------------------------*/
7374 /* genrshOne - right shift a one byte quantity by known count      */
7375 /*-----------------------------------------------------------------*/
7376 static void genrshOne (operand *result, operand *left,
7377                        int shCount, int sign)
7378 {
7379     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7380     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7381 }
7382
7383 /*-----------------------------------------------------------------*/
7384 /* genrshTwo - right shift two bytes by known amount != 0          */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshTwo (operand *result,operand *left,
7387                        int shCount, int sign)
7388 {
7389   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7390   /* if shCount >= 8 */
7391   if (shCount >= 8) {
7392     shCount -= 8 ;
7393     if (shCount)
7394       shiftR1Left2Result(left, MSB16, result, LSB,
7395                          shCount, sign);
7396     else
7397       movLeft2Result(left, MSB16, result, LSB);
7398
7399     emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7400
7401     if(sign) {
7402       emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7403       emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7404     }
7405   }
7406
7407   /*  1 <= shCount <= 7 */
7408   else
7409     shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7410 }
7411
7412 /*-----------------------------------------------------------------*/
7413 /* shiftRLong - shift right one long from left to result           */
7414 /* offl = LSB or MSB16                                             */
7415 /*-----------------------------------------------------------------*/
7416 static void shiftRLong (operand *left, int offl,
7417                         operand *result, int sign)
7418 {
7419     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7420     if(!sign)
7421         pic14_emitcode("clr","c");
7422     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7423     if(sign)
7424         pic14_emitcode("mov","c,acc.7");
7425     pic14_emitcode("rrc","a");
7426     aopPut(AOP(result),"a",MSB32-offl);
7427     if(offl == MSB16)
7428         /* add sign of "a" */
7429         addSign(result, MSB32, sign);
7430
7431     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7432     pic14_emitcode("rrc","a");
7433     aopPut(AOP(result),"a",MSB24-offl);
7434
7435     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7436     pic14_emitcode("rrc","a");
7437     aopPut(AOP(result),"a",MSB16-offl);
7438
7439     if(offl == LSB){
7440         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7441         pic14_emitcode("rrc","a");
7442         aopPut(AOP(result),"a",LSB);
7443     }
7444 }
7445
7446 /*-----------------------------------------------------------------*/
7447 /* genrshFour - shift four byte by a known amount != 0             */
7448 /*-----------------------------------------------------------------*/
7449 static void genrshFour (operand *result, operand *left,
7450                         int shCount, int sign)
7451 {
7452   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7453   /* if shifting more that 3 bytes */
7454   if(shCount >= 24 ) {
7455     shCount -= 24;
7456     if(shCount)
7457       shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7458     else
7459       movLeft2Result(left, MSB32, result, LSB);
7460
7461     addSign(result, MSB16, sign);
7462   }
7463   else if(shCount >= 16){
7464     shCount -= 16;
7465     if(shCount)
7466       shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7467     else{
7468       movLeft2Result(left, MSB24, result, LSB);
7469       movLeft2Result(left, MSB32, result, MSB16);
7470     }
7471     addSign(result, MSB24, sign);
7472   }
7473   else if(shCount >= 8){
7474     shCount -= 8;
7475     if(shCount == 1)
7476       shiftRLong(left, MSB16, result, sign);
7477     else if(shCount == 0){
7478       movLeft2Result(left, MSB16, result, LSB);
7479       movLeft2Result(left, MSB24, result, MSB16);
7480       movLeft2Result(left, MSB32, result, MSB24);
7481       addSign(result, MSB32, sign);
7482     }
7483     else{
7484       shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7485       shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7486       /* the last shift is signed */
7487       shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7488       addSign(result, MSB32, sign);
7489     }
7490   }
7491   else{   /* 1 <= shCount <= 7 */
7492     if(shCount <= 2){
7493       shiftRLong(left, LSB, result, sign);
7494       if(shCount == 2)
7495         shiftRLong(result, LSB, result, sign);
7496     }
7497     else{
7498       shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7499       shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7500       shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7501     }
7502   }
7503 }
7504
7505 /*-----------------------------------------------------------------*/
7506 /* genRightShiftLiteral - right shifting by known count            */
7507 /*-----------------------------------------------------------------*/
7508 static void genRightShiftLiteral (operand *left,
7509                                   operand *right,
7510                                   operand *result,
7511                                   iCode *ic,
7512                                   int sign)
7513 {    
7514   int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7515   int lsize,res_size;
7516
7517   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7518   freeAsmop(right,NULL,ic,TRUE);
7519
7520   aopOp(left,ic,FALSE);
7521   aopOp(result,ic,FALSE);
7522
7523 #if VIEW_SIZE
7524   pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7525                  AOP_SIZE(left));
7526 #endif
7527
7528   lsize = pic14_getDataSize(left);
7529   res_size = pic14_getDataSize(result);
7530   /* test the LEFT size !!! */
7531
7532   /* I suppose that the left size >= result size */
7533   if(shCount == 0){
7534     while(res_size--)
7535       movLeft2Result(left, lsize, result, res_size);
7536   }
7537
7538   else if(shCount >= (lsize * 8)){
7539
7540     if(res_size == 1) {
7541       emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7542       if(sign) {
7543         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7544         emitpcode(POC_DECF, popGet(AOP(result),LSB));
7545       }
7546     } else {
7547
7548       if(sign) {
7549         emitpcode(POC_MOVLW, popGetLit(0));
7550         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7551         emitpcode(POC_MOVLW, popGetLit(0xff));
7552         while(res_size--)
7553           emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7554
7555       } else {
7556
7557         while(res_size--)
7558           emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7559       }
7560     }
7561   } else {
7562
7563     switch (res_size) {
7564     case 1:
7565       genrshOne (result,left,shCount,sign);
7566       break;
7567
7568     case 2:
7569       genrshTwo (result,left,shCount,sign);
7570       break;
7571
7572     case 4:
7573       genrshFour (result,left,shCount,sign);
7574       break;
7575     default :
7576       break;
7577     }
7578
7579   }
7580
7581   freeAsmop(left,NULL,ic,TRUE);
7582   freeAsmop(result,NULL,ic,TRUE);
7583 }
7584
7585 /*-----------------------------------------------------------------*/
7586 /* genSignedRightShift - right shift of signed number              */
7587 /*-----------------------------------------------------------------*/
7588 static void genSignedRightShift (iCode *ic)
7589 {
7590   operand *right, *left, *result;
7591   int size, offset;
7592   //  char *l;
7593   symbol *tlbl, *tlbl1 ;
7594   pCodeOp *pctemp;
7595
7596   //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7597
7598   /* we do it the hard way put the shift count in b
7599      and loop thru preserving the sign */
7600   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7601
7602   right = IC_RIGHT(ic);
7603   left  = IC_LEFT(ic);
7604   result = IC_RESULT(ic);
7605
7606   aopOp(right,ic,FALSE);  
7607   aopOp(left,ic,FALSE);
7608   aopOp(result,ic,FALSE);
7609
7610
7611   if ( AOP_TYPE(right) == AOP_LIT) {
7612     genRightShiftLiteral (left,right,result,ic,1);
7613     return ;
7614   }
7615   /* shift count is unknown then we have to form 
7616      a loop get the loop count in B : Note: we take
7617      only the lower order byte since shifting
7618      more that 32 bits make no sense anyway, ( the
7619      largest size of an object can be only 32 bits ) */  
7620
7621   //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7622   //pic14_emitcode("inc","b");
7623   //freeAsmop (right,NULL,ic,TRUE);
7624   //aopOp(left,ic,FALSE);
7625   //aopOp(result,ic,FALSE);
7626
7627   /* now move the left to the result if they are not the
7628      same */
7629   if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7630       AOP_SIZE(result) > 1) {
7631
7632     size = AOP_SIZE(result);
7633     offset=0;
7634     while (size--) { 
7635       /*
7636         l = aopGet(AOP(left),offset,FALSE,TRUE);
7637         if (*l == '@' && IS_AOP_PREG(result)) {
7638
7639         pic14_emitcode("mov","a,%s",l);
7640         aopPut(AOP(result),"a",offset);
7641         } else
7642         aopPut(AOP(result),l,offset);
7643       */
7644       emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7645       emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7646
7647       offset++;
7648     }
7649   }
7650
7651   /* mov the highest order bit to OVR */    
7652   tlbl = newiTempLabel(NULL);
7653   tlbl1= newiTempLabel(NULL);
7654
7655   size = AOP_SIZE(result);
7656   offset = size - 1;
7657
7658   pctemp = popGetTempReg();  /* grab a temporary working register. */
7659
7660   emitpcode(POC_MOVFW, popGet(AOP(right),0));
7661
7662   /* offset should be 0, 1 or 3 */
7663   emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7664   emitSKPNZ;
7665   emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7666
7667   emitpcode(POC_MOVWF, pctemp);
7668
7669
7670   emitpLabel(tlbl->key);
7671
7672   emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7673   emitpcode(POC_RRF,   popGet(AOP(result),offset));
7674
7675   while(--size) {
7676     emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7677   }
7678
7679   emitpcode(POC_DECFSZ,  pctemp);
7680   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7681   emitpLabel(tlbl1->key);
7682
7683   popReleaseTempReg(pctemp);
7684 #if 0
7685   size = AOP_SIZE(result);
7686   offset = size - 1;
7687   pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7688   pic14_emitcode("rlc","a");
7689   pic14_emitcode("mov","ov,c");
7690   /* if it is only one byte then */
7691   if (size == 1) {
7692     l = aopGet(AOP(left),0,FALSE,FALSE);
7693     MOVA(l);
7694     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7695     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7696     pic14_emitcode("mov","c,ov");
7697     pic14_emitcode("rrc","a");
7698     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7699     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7700     aopPut(AOP(result),"a",0);
7701     goto release ;
7702   }
7703
7704   reAdjustPreg(AOP(result));
7705   pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7706   pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7707   pic14_emitcode("mov","c,ov");
7708   while (size--) {
7709     l = aopGet(AOP(result),offset,FALSE,FALSE);
7710     MOVA(l);
7711     pic14_emitcode("rrc","a");         
7712     aopPut(AOP(result),"a",offset--);
7713   }
7714   reAdjustPreg(AOP(result));
7715   pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7716   pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7717
7718  release:
7719 #endif
7720
7721   freeAsmop(left,NULL,ic,TRUE);
7722   freeAsmop(result,NULL,ic,TRUE);
7723   freeAsmop(right,NULL,ic,TRUE);
7724 }
7725
7726 /*-----------------------------------------------------------------*/
7727 /* genRightShift - generate code for right shifting                */
7728 /*-----------------------------------------------------------------*/
7729 static void genRightShift (iCode *ic)
7730 {
7731     operand *right, *left, *result;
7732     sym_link *retype ;
7733     int size, offset;
7734     char *l;
7735     symbol *tlbl, *tlbl1 ;
7736
7737     /* if signed then we do it the hard way preserve the
7738     sign bit moving it inwards */
7739     retype = getSpec(operandType(IC_RESULT(ic)));
7740     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7741
7742     if (!SPEC_USIGN(retype)) {
7743         genSignedRightShift (ic);
7744         return ;
7745     }
7746
7747     /* signed & unsigned types are treated the same : i.e. the
7748     signed is NOT propagated inwards : quoting from the
7749     ANSI - standard : "for E1 >> E2, is equivalent to division
7750     by 2**E2 if unsigned or if it has a non-negative value,
7751     otherwise the result is implementation defined ", MY definition
7752     is that the sign does not get propagated */
7753
7754     right = IC_RIGHT(ic);
7755     left  = IC_LEFT(ic);
7756     result = IC_RESULT(ic);
7757
7758     aopOp(right,ic,FALSE);
7759
7760     /* if the shift count is known then do it 
7761     as efficiently as possible */
7762     if (AOP_TYPE(right) == AOP_LIT) {
7763         genRightShiftLiteral (left,right,result,ic, 0);
7764         return ;
7765     }
7766
7767     /* shift count is unknown then we have to form 
7768     a loop get the loop count in B : Note: we take
7769     only the lower order byte since shifting
7770     more that 32 bits make no sense anyway, ( the
7771     largest size of an object can be only 32 bits ) */  
7772
7773     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7774     pic14_emitcode("inc","b");
7775     aopOp(left,ic,FALSE);
7776     aopOp(result,ic,FALSE);
7777
7778     /* now move the left to the result if they are not the
7779     same */
7780     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7781         AOP_SIZE(result) > 1) {
7782
7783         size = AOP_SIZE(result);
7784         offset=0;
7785         while (size--) {
7786             l = aopGet(AOP(left),offset,FALSE,TRUE);
7787             if (*l == '@' && IS_AOP_PREG(result)) {
7788
7789                 pic14_emitcode("mov","a,%s",l);
7790                 aopPut(AOP(result),"a",offset);
7791             } else
7792                 aopPut(AOP(result),l,offset);
7793             offset++;
7794         }
7795     }
7796
7797     tlbl = newiTempLabel(NULL);
7798     tlbl1= newiTempLabel(NULL);
7799     size = AOP_SIZE(result);
7800     offset = size - 1;
7801
7802     /* if it is only one byte then */
7803     if (size == 1) {
7804
7805       tlbl = newiTempLabel(NULL);
7806       if (!pic14_sameRegs(AOP(left),AOP(result))) {
7807         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7808         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7809       }
7810
7811       emitpcode(POC_COMFW,  popGet(AOP(right),0));
7812       emitpcode(POC_RLF,    popGet(AOP(result),0));
7813       emitpLabel(tlbl->key);
7814       emitpcode(POC_RRF,    popGet(AOP(result),0));
7815       emitpcode(POC_ADDLW,  popGetLit(1));
7816       emitSKPC;
7817       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7818
7819       goto release ;
7820     }
7821
7822     reAdjustPreg(AOP(result));
7823     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7824     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7825     CLRC;
7826     while (size--) {
7827         l = aopGet(AOP(result),offset,FALSE,FALSE);
7828         MOVA(l);
7829         pic14_emitcode("rrc","a");         
7830         aopPut(AOP(result),"a",offset--);
7831     }
7832     reAdjustPreg(AOP(result));
7833
7834     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7835     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7836
7837 release:
7838     freeAsmop(left,NULL,ic,TRUE);
7839     freeAsmop (right,NULL,ic,TRUE);
7840     freeAsmop(result,NULL,ic,TRUE);
7841 }
7842
7843 /*-----------------------------------------------------------------*/
7844 /* genUnpackBits - generates code for unpacking bits               */
7845 /*-----------------------------------------------------------------*/
7846 static void genUnpackBits (operand *result, char *rname, int ptype)
7847 {    
7848     int shCnt ;
7849     int rlen = 0 ;
7850     sym_link *etype;
7851     int offset = 0 ;
7852
7853     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7854     etype = getSpec(operandType(result));
7855
7856     /* read the first byte  */
7857     switch (ptype) {
7858
7859     case POINTER:
7860     case IPOINTER:
7861         pic14_emitcode("mov","a,@%s",rname);
7862         break;
7863         
7864     case PPOINTER:
7865         pic14_emitcode("movx","a,@%s",rname);
7866         break;
7867         
7868     case FPOINTER:
7869         pic14_emitcode("movx","a,@dptr");
7870         break;
7871
7872     case CPOINTER:
7873         pic14_emitcode("clr","a");
7874         pic14_emitcode("movc","a","@a+dptr");
7875         break;
7876
7877     case GPOINTER:
7878         pic14_emitcode("lcall","__gptrget");
7879         break;
7880     }
7881
7882     /* if we have bitdisplacement then it fits   */
7883     /* into this byte completely or if length is */
7884     /* less than a byte                          */
7885     if ((shCnt = SPEC_BSTR(etype)) || 
7886         (SPEC_BLEN(etype) <= 8))  {
7887
7888         /* shift right acc */
7889         AccRsh(shCnt);
7890
7891         pic14_emitcode("anl","a,#0x%02x",
7892                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7893         aopPut(AOP(result),"a",offset);
7894         return ;
7895     }
7896
7897     /* bit field did not fit in a byte  */
7898     rlen = SPEC_BLEN(etype) - 8;
7899     aopPut(AOP(result),"a",offset++);
7900
7901     while (1)  {
7902
7903         switch (ptype) {
7904         case POINTER:
7905         case IPOINTER:
7906             pic14_emitcode("inc","%s",rname);
7907             pic14_emitcode("mov","a,@%s",rname);
7908             break;
7909             
7910         case PPOINTER:
7911             pic14_emitcode("inc","%s",rname);
7912             pic14_emitcode("movx","a,@%s",rname);
7913             break;
7914
7915         case FPOINTER:
7916             pic14_emitcode("inc","dptr");
7917             pic14_emitcode("movx","a,@dptr");
7918             break;
7919             
7920         case CPOINTER:
7921             pic14_emitcode("clr","a");
7922             pic14_emitcode("inc","dptr");
7923             pic14_emitcode("movc","a","@a+dptr");
7924             break;
7925             
7926         case GPOINTER:
7927             pic14_emitcode("inc","dptr");
7928             pic14_emitcode("lcall","__gptrget");
7929             break;
7930         }
7931
7932         rlen -= 8;            
7933         /* if we are done */
7934         if ( rlen <= 0 )
7935             break ;
7936         
7937         aopPut(AOP(result),"a",offset++);
7938                               
7939     }
7940     
7941     if (rlen) {
7942         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7943         aopPut(AOP(result),"a",offset);        
7944     }
7945     
7946     return ;
7947 }
7948
7949 #if 0
7950 /*-----------------------------------------------------------------*/
7951 /* genDataPointerGet - generates code when ptr offset is known     */
7952 /*-----------------------------------------------------------------*/
7953 static void genDataPointerGet (operand *left, 
7954                                operand *result, 
7955                                iCode *ic)
7956 {
7957   int size , offset = 0;
7958
7959
7960   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7961
7962
7963   /* optimization - most of the time, left and result are the same
7964    * address, but different types. for the pic code, we could omit
7965    * the following
7966    */
7967
7968   aopOp(result,ic,TRUE);
7969
7970   DEBUGpic14_AopType(__LINE__,left,NULL,result);
7971
7972   emitpcode(POC_MOVFW, popGet(AOP(left),0));
7973
7974   size = AOP_SIZE(result);
7975
7976   while (size--) {
7977     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7978     offset++;
7979   }
7980
7981   freeAsmop(left,NULL,ic,TRUE);
7982   freeAsmop(result,NULL,ic,TRUE);
7983 }
7984 #endif
7985 /*-----------------------------------------------------------------*/
7986 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7987 /*-----------------------------------------------------------------*/
7988 static void genNearPointerGet (operand *left, 
7989                                operand *result, 
7990                                iCode *ic)
7991 {
7992     asmop *aop = NULL;
7993     //regs *preg = NULL ;
7994     char *rname ;
7995     sym_link *rtype, *retype;
7996     sym_link *ltype = operandType(left);    
7997     //char buffer[80];
7998
7999     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8000
8001     rtype = operandType(result);
8002     retype= getSpec(rtype);
8003     
8004     aopOp(left,ic,FALSE);
8005     
8006     /* if left is rematerialisable and
8007        result is not bit variable type and
8008        the left is pointer to data space i.e
8009        lower 128 bytes of space */
8010     if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
8011         !IS_BITVAR(retype)         &&
8012         DCL_TYPE(ltype) == POINTER) {
8013       //genDataPointerGet (left,result,ic);
8014         return ;
8015     }
8016     
8017     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8018
8019         /* if the value is already in a pointer register
8020        then don't need anything more */
8021     if (!AOP_INPREG(AOP(left))) {
8022         /* otherwise get a free pointer register */
8023     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8024 /*
8025         aop = newAsmop(0);
8026         preg = getFreePtr(ic,&aop,FALSE);
8027         pic14_emitcode("mov","%s,%s",
8028                 preg->name,
8029                 aopGet(AOP(left),0,FALSE,TRUE));
8030         rname = preg->name ;
8031 */
8032     rname ="BAD";
8033     } else
8034         rname = aopGet(AOP(left),0,FALSE,FALSE);
8035     
8036     aopOp (result,ic,FALSE);
8037     
8038       /* if bitfield then unpack the bits */
8039     if (IS_BITVAR(retype)) 
8040         genUnpackBits (result,rname,POINTER);
8041     else {
8042         /* we have can just get the values */
8043       int size = AOP_SIZE(result);
8044       int offset = 0 ;  
8045         
8046       DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8047
8048       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8049       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8050       while(size--) {
8051         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8052         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8053         if(size)
8054           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8055       }
8056 /*
8057         while (size--) {
8058             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8059
8060                 pic14_emitcode("mov","a,@%s",rname);
8061                 aopPut(AOP(result),"a",offset);
8062             } else {
8063                 sprintf(buffer,"@%s",rname);
8064                 aopPut(AOP(result),buffer,offset);
8065             }
8066             offset++ ;
8067             if (size)
8068                 pic14_emitcode("inc","%s",rname);
8069         }
8070 */
8071     }
8072
8073     /* now some housekeeping stuff */
8074     if (aop) {
8075         /* we had to allocate for this iCode */
8076     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8077         freeAsmop(NULL,aop,ic,TRUE);
8078     } else { 
8079         /* we did not allocate which means left
8080            already in a pointer register, then
8081            if size > 0 && this could be used again
8082            we have to point it back to where it 
8083            belongs */
8084     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8085         if (AOP_SIZE(result) > 1 &&
8086             !OP_SYMBOL(left)->remat &&
8087             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8088               ic->depth )) {
8089             int size = AOP_SIZE(result) - 1;
8090             while (size--)
8091                 pic14_emitcode("dec","%s",rname);
8092         }
8093     }
8094
8095     /* done */
8096     freeAsmop(left,NULL,ic,TRUE);
8097     freeAsmop(result,NULL,ic,TRUE);
8098      
8099 }
8100
8101 /*-----------------------------------------------------------------*/
8102 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8103 /*-----------------------------------------------------------------*/
8104 static void genPagedPointerGet (operand *left, 
8105                                operand *result, 
8106                                iCode *ic)
8107 {
8108     asmop *aop = NULL;
8109     regs *preg = NULL ;
8110     char *rname ;
8111     sym_link *rtype, *retype;    
8112
8113     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8114
8115     rtype = operandType(result);
8116     retype= getSpec(rtype);
8117     
8118     aopOp(left,ic,FALSE);
8119
8120   /* if the value is already in a pointer register
8121        then don't need anything more */
8122     if (!AOP_INPREG(AOP(left))) {
8123         /* otherwise get a free pointer register */
8124         aop = newAsmop(0);
8125         preg = getFreePtr(ic,&aop,FALSE);
8126         pic14_emitcode("mov","%s,%s",
8127                 preg->name,
8128                 aopGet(AOP(left),0,FALSE,TRUE));
8129         rname = preg->name ;
8130     } else
8131         rname = aopGet(AOP(left),0,FALSE,FALSE);
8132     
8133     freeAsmop(left,NULL,ic,TRUE);
8134     aopOp (result,ic,FALSE);
8135
8136     /* if bitfield then unpack the bits */
8137     if (IS_BITVAR(retype)) 
8138         genUnpackBits (result,rname,PPOINTER);
8139     else {
8140         /* we have can just get the values */
8141         int size = AOP_SIZE(result);
8142         int offset = 0 ;        
8143         
8144         while (size--) {
8145             
8146             pic14_emitcode("movx","a,@%s",rname);
8147             aopPut(AOP(result),"a",offset);
8148             
8149             offset++ ;
8150             
8151             if (size)
8152                 pic14_emitcode("inc","%s",rname);
8153         }
8154     }
8155
8156     /* now some housekeeping stuff */
8157     if (aop) {
8158         /* we had to allocate for this iCode */
8159         freeAsmop(NULL,aop,ic,TRUE);
8160     } else { 
8161         /* we did not allocate which means left
8162            already in a pointer register, then
8163            if size > 0 && this could be used again
8164            we have to point it back to where it 
8165            belongs */
8166         if (AOP_SIZE(result) > 1 &&
8167             !OP_SYMBOL(left)->remat &&
8168             ( OP_SYMBOL(left)->liveTo > ic->seq ||
8169               ic->depth )) {
8170             int size = AOP_SIZE(result) - 1;
8171             while (size--)
8172                 pic14_emitcode("dec","%s",rname);
8173         }
8174     }
8175
8176     /* done */
8177     freeAsmop(result,NULL,ic,TRUE);
8178     
8179         
8180 }
8181
8182 /*-----------------------------------------------------------------*/
8183 /* genFarPointerGet - gget value from far space                    */
8184 /*-----------------------------------------------------------------*/
8185 static void genFarPointerGet (operand *left,
8186                               operand *result, iCode *ic)
8187 {
8188     int size, offset ;
8189     sym_link *retype = getSpec(operandType(result));
8190
8191     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8192
8193     aopOp(left,ic,FALSE);
8194
8195     /* if the operand is already in dptr 
8196     then we do nothing else we move the value to dptr */
8197     if (AOP_TYPE(left) != AOP_STR) {
8198         /* if this is remateriazable */
8199         if (AOP_TYPE(left) == AOP_IMMD)
8200             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8201         else { /* we need to get it byte by byte */
8202             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8203             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8204             if (options.model == MODEL_FLAT24)
8205             {
8206                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8207             }
8208         }
8209     }
8210     /* so dptr know contains the address */
8211     freeAsmop(left,NULL,ic,TRUE);
8212     aopOp(result,ic,FALSE);
8213
8214     /* if bit then unpack */
8215     if (IS_BITVAR(retype)) 
8216         genUnpackBits(result,"dptr",FPOINTER);
8217     else {
8218         size = AOP_SIZE(result);
8219         offset = 0 ;
8220
8221         while (size--) {
8222             pic14_emitcode("movx","a,@dptr");
8223             aopPut(AOP(result),"a",offset++);
8224             if (size)
8225                 pic14_emitcode("inc","dptr");
8226         }
8227     }
8228
8229     freeAsmop(result,NULL,ic,TRUE);
8230 }
8231 #if 0
8232 /*-----------------------------------------------------------------*/
8233 /* genCodePointerGet - get value from code space                  */
8234 /*-----------------------------------------------------------------*/
8235 static void genCodePointerGet (operand *left,
8236                                 operand *result, iCode *ic)
8237 {
8238     int size, offset ;
8239     sym_link *retype = getSpec(operandType(result));
8240
8241     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8242
8243     aopOp(left,ic,FALSE);
8244
8245     /* if the operand is already in dptr 
8246     then we do nothing else we move the value to dptr */
8247     if (AOP_TYPE(left) != AOP_STR) {
8248         /* if this is remateriazable */
8249         if (AOP_TYPE(left) == AOP_IMMD)
8250             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8251         else { /* we need to get it byte by byte */
8252             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8253             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8254             if (options.model == MODEL_FLAT24)
8255             {
8256                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8257             }
8258         }
8259     }
8260     /* so dptr know contains the address */
8261     freeAsmop(left,NULL,ic,TRUE);
8262     aopOp(result,ic,FALSE);
8263
8264     /* if bit then unpack */
8265     if (IS_BITVAR(retype)) 
8266         genUnpackBits(result,"dptr",CPOINTER);
8267     else {
8268         size = AOP_SIZE(result);
8269         offset = 0 ;
8270
8271         while (size--) {
8272             pic14_emitcode("clr","a");
8273             pic14_emitcode("movc","a,@a+dptr");
8274             aopPut(AOP(result),"a",offset++);
8275             if (size)
8276                 pic14_emitcode("inc","dptr");
8277         }
8278     }
8279
8280     freeAsmop(result,NULL,ic,TRUE);
8281 }
8282 #endif
8283 /*-----------------------------------------------------------------*/
8284 /* genGenPointerGet - gget value from generic pointer space        */
8285 /*-----------------------------------------------------------------*/
8286 static void genGenPointerGet (operand *left,
8287                               operand *result, iCode *ic)
8288 {
8289   int size, offset ;
8290   sym_link *retype = getSpec(operandType(result));
8291
8292   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8293   aopOp(left,ic,FALSE);
8294   aopOp(result,ic,FALSE);
8295
8296
8297   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8298
8299   /* if the operand is already in dptr 
8300      then we do nothing else we move the value to dptr */
8301   //  if (AOP_TYPE(left) != AOP_STR) {
8302     /* if this is remateriazable */
8303     if (AOP_TYPE(left) == AOP_IMMD) {
8304       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8305       pic14_emitcode("mov","b,#%d",pointerCode(retype));
8306     }
8307     else { /* we need to get it byte by byte */
8308
8309       emitpcode(POC_MOVFW,popGet(AOP(left),0));
8310       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8311
8312       size = AOP_SIZE(result);
8313       offset = 0 ;
8314
8315       while(size--) {
8316         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8317         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8318         if(size)
8319           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8320       }
8321       goto release;
8322     }
8323     //}
8324   /* so dptr know contains the address */
8325
8326   /* if bit then unpack */
8327   //if (IS_BITVAR(retype)) 
8328   //  genUnpackBits(result,"dptr",GPOINTER);
8329
8330  release:
8331   freeAsmop(left,NULL,ic,TRUE);
8332   freeAsmop(result,NULL,ic,TRUE);
8333
8334 }
8335
8336 /*-----------------------------------------------------------------*/
8337 /* genConstPointerGet - get value from const generic pointer space */
8338 /*-----------------------------------------------------------------*/
8339 static void genConstPointerGet (operand *left,
8340                                 operand *result, iCode *ic)
8341 {
8342   //sym_link *retype = getSpec(operandType(result));
8343   symbol *albl = newiTempLabel(NULL);
8344   symbol *blbl = newiTempLabel(NULL);
8345   PIC_OPCODE poc;
8346
8347   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8348   aopOp(left,ic,FALSE);
8349   aopOp(result,ic,FALSE);
8350
8351
8352   DEBUGpic14_AopType(__LINE__,left,NULL,result);
8353
8354   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8355
8356   emitpcode(POC_CALL,popGetLabel(albl->key));
8357   emitpcode(POC_GOTO,popGetLabel(blbl->key));
8358   emitpLabel(albl->key);
8359
8360   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8361     
8362   emitpcode(poc,popGet(AOP(left),1));
8363   emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8364   emitpcode(poc,popGet(AOP(left),0));
8365   emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8366
8367   emitpLabel(blbl->key);
8368
8369   emitpcode(POC_MOVWF,popGet(AOP(result),0));
8370
8371
8372   freeAsmop(left,NULL,ic,TRUE);
8373   freeAsmop(result,NULL,ic,TRUE);
8374
8375 }
8376 /*-----------------------------------------------------------------*/
8377 /* genPointerGet - generate code for pointer get                   */
8378 /*-----------------------------------------------------------------*/
8379 static void genPointerGet (iCode *ic)
8380 {
8381     operand *left, *result ;
8382     sym_link *type, *etype;
8383     int p_type;
8384
8385     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8386
8387     left = IC_LEFT(ic);
8388     result = IC_RESULT(ic) ;
8389
8390     /* depending on the type of pointer we need to
8391     move it to the correct pointer register */
8392     type = operandType(left);
8393     etype = getSpec(type);
8394
8395     if (IS_PTR_CONST(type))
8396       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8397
8398     /* if left is of type of pointer then it is simple */
8399     if (IS_PTR(type) && !IS_FUNC(type->next)) 
8400         p_type = DCL_TYPE(type);
8401     else {
8402         /* we have to go by the storage class */
8403         p_type = PTR_TYPE(SPEC_OCLS(etype));
8404
8405         DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8406
8407         if (SPEC_OCLS(etype)->codesp ) {
8408           DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8409           //p_type = CPOINTER ; 
8410         }
8411         else
8412             if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8413               DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8414                /*p_type = FPOINTER ;*/ 
8415             else
8416                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8417                   DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8418 /*                  p_type = PPOINTER; */
8419                 else
8420                     if (SPEC_OCLS(etype) == idata )
8421                       DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8422 /*                      p_type = IPOINTER; */
8423                     else
8424                       DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8425 /*                      p_type = POINTER ; */
8426     }
8427
8428     /* now that we have the pointer type we assign
8429     the pointer values */
8430     switch (p_type) {
8431
8432     case POINTER:       
8433     case IPOINTER:
8434         genNearPointerGet (left,result,ic);
8435         break;
8436
8437     case PPOINTER:
8438         genPagedPointerGet(left,result,ic);
8439         break;
8440
8441     case FPOINTER:
8442         genFarPointerGet (left,result,ic);
8443         break;
8444
8445     case CPOINTER:
8446         genConstPointerGet (left,result,ic);
8447         //pic14_emitcodePointerGet (left,result,ic);
8448         break;
8449
8450     case GPOINTER:
8451       if (IS_PTR_CONST(type))
8452         genConstPointerGet (left,result,ic);
8453       else
8454         genGenPointerGet (left,result,ic);
8455       break;
8456     }
8457
8458 }
8459
8460 /*-----------------------------------------------------------------*/
8461 /* genPackBits - generates code for packed bit storage             */
8462 /*-----------------------------------------------------------------*/
8463 static void genPackBits (sym_link    *etype ,
8464                          operand *right ,
8465                          char *rname, int p_type)
8466 {
8467     int shCount = 0 ;
8468     int offset = 0  ;
8469     int rLen = 0 ;
8470     int blen, bstr ;   
8471     char *l ;
8472
8473     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8474     blen = SPEC_BLEN(etype);
8475     bstr = SPEC_BSTR(etype);
8476
8477     l = aopGet(AOP(right),offset++,FALSE,FALSE);
8478     MOVA(l);   
8479
8480     /* if the bit lenth is less than or    */
8481     /* it exactly fits a byte then         */
8482     if (SPEC_BLEN(etype) <= 8 )  {
8483         shCount = SPEC_BSTR(etype) ;
8484
8485         /* shift left acc */
8486         AccLsh(shCount);
8487
8488         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8489
8490
8491             switch (p_type) {
8492                 case POINTER:
8493                     pic14_emitcode ("mov","b,a");
8494                     pic14_emitcode("mov","a,@%s",rname);
8495                     break;
8496
8497                 case FPOINTER:
8498                     pic14_emitcode ("mov","b,a");
8499                     pic14_emitcode("movx","a,@dptr");
8500                     break;
8501
8502                 case GPOINTER:
8503                     pic14_emitcode ("push","b");
8504                     pic14_emitcode ("push","acc");
8505                     pic14_emitcode ("lcall","__gptrget");
8506                     pic14_emitcode ("pop","b");
8507                     break;
8508             }
8509
8510             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8511                       ((unsigned char)(0xFF << (blen+bstr)) | 
8512                        (unsigned char)(0xFF >> (8-bstr)) ) );
8513             pic14_emitcode ("orl","a,b");
8514             if (p_type == GPOINTER)
8515                 pic14_emitcode("pop","b");
8516         }
8517     }
8518
8519     switch (p_type) {
8520         case POINTER:
8521             pic14_emitcode("mov","@%s,a",rname);
8522             break;
8523
8524         case FPOINTER:
8525             pic14_emitcode("movx","@dptr,a");
8526             break;
8527
8528         case GPOINTER:
8529             DEBUGpic14_emitcode(";lcall","__gptrput");
8530             break;
8531     }
8532
8533     /* if we r done */
8534     if ( SPEC_BLEN(etype) <= 8 )
8535         return ;
8536
8537     pic14_emitcode("inc","%s",rname);
8538     rLen = SPEC_BLEN(etype) ;     
8539
8540     /* now generate for lengths greater than one byte */
8541     while (1) {
8542
8543         l = aopGet(AOP(right),offset++,FALSE,TRUE);
8544
8545         rLen -= 8 ;
8546         if (rLen <= 0 )
8547             break ;
8548
8549         switch (p_type) {
8550             case POINTER:
8551                 if (*l == '@') {
8552                     MOVA(l);
8553                     pic14_emitcode("mov","@%s,a",rname);
8554                 } else
8555                     pic14_emitcode("mov","@%s,%s",rname,l);
8556                 break;
8557
8558             case FPOINTER:
8559                 MOVA(l);
8560                 pic14_emitcode("movx","@dptr,a");
8561                 break;
8562
8563             case GPOINTER:
8564                 MOVA(l);
8565                 DEBUGpic14_emitcode(";lcall","__gptrput");
8566                 break;  
8567         }   
8568         pic14_emitcode ("inc","%s",rname);
8569     }
8570
8571     MOVA(l);
8572
8573     /* last last was not complete */
8574     if (rLen)   {
8575         /* save the byte & read byte */
8576         switch (p_type) {
8577             case POINTER:
8578                 pic14_emitcode ("mov","b,a");
8579                 pic14_emitcode("mov","a,@%s",rname);
8580                 break;
8581
8582             case FPOINTER:
8583                 pic14_emitcode ("mov","b,a");
8584                 pic14_emitcode("movx","a,@dptr");
8585                 break;
8586
8587             case GPOINTER:
8588                 pic14_emitcode ("push","b");
8589                 pic14_emitcode ("push","acc");
8590                 pic14_emitcode ("lcall","__gptrget");
8591                 pic14_emitcode ("pop","b");
8592                 break;
8593         }
8594
8595         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8596         pic14_emitcode ("orl","a,b");
8597     }
8598
8599     if (p_type == GPOINTER)
8600         pic14_emitcode("pop","b");
8601
8602     switch (p_type) {
8603
8604     case POINTER:
8605         pic14_emitcode("mov","@%s,a",rname);
8606         break;
8607         
8608     case FPOINTER:
8609         pic14_emitcode("movx","@dptr,a");
8610         break;
8611         
8612     case GPOINTER:
8613         DEBUGpic14_emitcode(";lcall","__gptrput");
8614         break;                  
8615     }
8616 }
8617 /*-----------------------------------------------------------------*/
8618 /* genDataPointerSet - remat pointer to data space                 */
8619 /*-----------------------------------------------------------------*/
8620 static void genDataPointerSet(operand *right,
8621                               operand *result,
8622                               iCode *ic)
8623 {
8624     int size, offset = 0 ;
8625     char *l, buffer[256];
8626
8627     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8628     aopOp(right,ic,FALSE);
8629     
8630     l = aopGet(AOP(result),0,FALSE,TRUE);
8631     size = AOP_SIZE(right);
8632 /*
8633     if ( AOP_TYPE(result) == AOP_PCODE) {
8634       fprintf(stderr,"genDataPointerSet   %s, %d\n",
8635               AOP(result)->aopu.pcop->name,
8636               PCOI(AOP(result)->aopu.pcop)->offset);
8637     }
8638 */
8639
8640     // tsd, was l+1 - the underline `_' prefix was being stripped
8641     while (size--) {
8642       if (offset) {
8643         sprintf(buffer,"(%s + %d)",l,offset);
8644         fprintf(stderr,"oops  %s\n",buffer);
8645       } else
8646         sprintf(buffer,"%s",l);
8647
8648         if (AOP_TYPE(right) == AOP_LIT) {
8649           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8650           lit = lit >> (8*offset);
8651           if(lit&0xff) {
8652             pic14_emitcode("movlw","%d",lit);
8653             pic14_emitcode("movwf","%s",buffer);
8654
8655             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8656             //emitpcode(POC_MOVWF, popRegFromString(buffer));
8657             emitpcode(POC_MOVWF, popGet(AOP(result),0));
8658
8659           } else {
8660             pic14_emitcode("clrf","%s",buffer);
8661             //emitpcode(POC_CLRF, popRegFromString(buffer));
8662             emitpcode(POC_CLRF, popGet(AOP(result),0));
8663           }
8664         }else {
8665           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8666           pic14_emitcode("movwf","%s",buffer);
8667
8668           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8669           //emitpcode(POC_MOVWF, popRegFromString(buffer));
8670           emitpcode(POC_MOVWF, popGet(AOP(result),0));
8671
8672         }
8673
8674         offset++;
8675     }
8676
8677     freeAsmop(right,NULL,ic,TRUE);
8678     freeAsmop(result,NULL,ic,TRUE);
8679 }
8680
8681 /*-----------------------------------------------------------------*/
8682 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8683 /*-----------------------------------------------------------------*/
8684 static void genNearPointerSet (operand *right,
8685                                operand *result, 
8686                                iCode *ic)
8687 {
8688   asmop *aop = NULL;
8689   char *l;
8690   sym_link *retype;
8691   sym_link *ptype = operandType(result);
8692
8693     
8694   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8695   retype= getSpec(operandType(right));
8696
8697   aopOp(result,ic,FALSE);
8698
8699     
8700   /* if the result is rematerializable &
8701      in data space & not a bit variable */
8702   //if (AOP_TYPE(result) == AOP_IMMD &&
8703   if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8704       DCL_TYPE(ptype) == POINTER   &&
8705       !IS_BITVAR(retype)) {
8706     genDataPointerSet (right,result,ic);
8707     freeAsmop(result,NULL,ic,TRUE);
8708     return;
8709   }
8710
8711   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8712   aopOp(right,ic,FALSE);
8713   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8714
8715   /* if the value is already in a pointer register
8716      then don't need anything more */
8717   if (!AOP_INPREG(AOP(result))) {
8718     /* otherwise get a free pointer register */
8719     //aop = newAsmop(0);
8720     //preg = getFreePtr(ic,&aop,FALSE);
8721     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8722     //pic14_emitcode("mov","%s,%s",
8723     //         preg->name,
8724     //         aopGet(AOP(result),0,FALSE,TRUE));
8725     //rname = preg->name ;
8726     //pic14_emitcode("movwf","fsr");
8727     emitpcode(POC_MOVFW, popGet(AOP(result),0));
8728     emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8729     emitpcode(POC_MOVFW, popGet(AOP(right),0));
8730     emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8731     goto release;
8732
8733   }// else
8734   //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8735
8736
8737   /* if bitfield then unpack the bits */
8738   if (IS_BITVAR(retype)) {
8739     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8740            "The programmer is obviously confused");
8741     //genPackBits (retype,right,rname,POINTER);
8742     exit(1);
8743   }
8744   else {
8745     /* we have can just get the values */
8746     int size = AOP_SIZE(right);
8747     int offset = 0 ;    
8748
8749     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8750     while (size--) {
8751       l = aopGet(AOP(right),offset,FALSE,TRUE);
8752       if (*l == '@' ) {
8753         //MOVA(l);
8754         //pic14_emitcode("mov","@%s,a",rname);
8755         pic14_emitcode("movf","indf,w ;1");
8756       } else {
8757
8758         if (AOP_TYPE(right) == AOP_LIT) {
8759           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8760           if(lit) {
8761             pic14_emitcode("movlw","%s",l);
8762             pic14_emitcode("movwf","indf ;2");
8763           } else 
8764             pic14_emitcode("clrf","indf");
8765         }else {
8766           pic14_emitcode("movf","%s,w",l);
8767           pic14_emitcode("movwf","indf ;2");
8768         }
8769         //pic14_emitcode("mov","@%s,%s",rname,l);
8770       }
8771       if (size)
8772         pic14_emitcode("incf","fsr,f ;3");
8773       //pic14_emitcode("inc","%s",rname);
8774       offset++;
8775     }
8776   }
8777
8778   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8779   /* now some housekeeping stuff */
8780   if (aop) {
8781     /* we had to allocate for this iCode */
8782     freeAsmop(NULL,aop,ic,TRUE);
8783   } else { 
8784     /* we did not allocate which means left
8785        already in a pointer register, then
8786        if size > 0 && this could be used again
8787        we have to point it back to where it 
8788        belongs */
8789     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8790     if (AOP_SIZE(right) > 1 &&
8791         !OP_SYMBOL(result)->remat &&
8792         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8793           ic->depth )) {
8794       int size = AOP_SIZE(right) - 1;
8795       while (size--)
8796         pic14_emitcode("decf","fsr,f");
8797       //pic14_emitcode("dec","%s",rname);
8798     }
8799   }
8800
8801   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8802   /* done */
8803  release:
8804   freeAsmop(right,NULL,ic,TRUE);
8805   freeAsmop(result,NULL,ic,TRUE);
8806 }
8807
8808 /*-----------------------------------------------------------------*/
8809 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8810 /*-----------------------------------------------------------------*/
8811 static void genPagedPointerSet (operand *right,
8812                                operand *result, 
8813                                iCode *ic)
8814 {
8815     asmop *aop = NULL;
8816     regs *preg = NULL ;
8817     char *rname , *l;
8818     sym_link *retype;
8819        
8820     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8821
8822     retype= getSpec(operandType(right));
8823     
8824     aopOp(result,ic,FALSE);
8825     
8826     /* if the value is already in a pointer register
8827        then don't need anything more */
8828     if (!AOP_INPREG(AOP(result))) {
8829         /* otherwise get a free pointer register */
8830         aop = newAsmop(0);
8831         preg = getFreePtr(ic,&aop,FALSE);
8832         pic14_emitcode("mov","%s,%s",
8833                 preg->name,
8834                 aopGet(AOP(result),0,FALSE,TRUE));
8835         rname = preg->name ;
8836     } else
8837         rname = aopGet(AOP(result),0,FALSE,FALSE);
8838     
8839     freeAsmop(result,NULL,ic,TRUE);
8840     aopOp (right,ic,FALSE);
8841
8842     /* if bitfield then unpack the bits */
8843     if (IS_BITVAR(retype)) 
8844         genPackBits (retype,right,rname,PPOINTER);
8845     else {
8846         /* we have can just get the values */
8847         int size = AOP_SIZE(right);
8848         int offset = 0 ;        
8849         
8850         while (size--) {
8851             l = aopGet(AOP(right),offset,FALSE,TRUE);
8852             
8853             MOVA(l);
8854             pic14_emitcode("movx","@%s,a",rname);
8855
8856             if (size)
8857                 pic14_emitcode("inc","%s",rname);
8858
8859             offset++;
8860         }
8861     }
8862     
8863     /* now some housekeeping stuff */
8864     if (aop) {
8865         /* we had to allocate for this iCode */
8866         freeAsmop(NULL,aop,ic,TRUE);
8867     } else { 
8868         /* we did not allocate which means left
8869            already in a pointer register, then
8870            if size > 0 && this could be used again
8871            we have to point it back to where it 
8872            belongs */
8873         if (AOP_SIZE(right) > 1 &&
8874             !OP_SYMBOL(result)->remat &&
8875             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8876               ic->depth )) {
8877             int size = AOP_SIZE(right) - 1;
8878             while (size--)
8879                 pic14_emitcode("dec","%s",rname);
8880         }
8881     }
8882
8883     /* done */
8884     freeAsmop(right,NULL,ic,TRUE);
8885     
8886         
8887 }
8888
8889 /*-----------------------------------------------------------------*/
8890 /* genFarPointerSet - set value from far space                     */
8891 /*-----------------------------------------------------------------*/
8892 static void genFarPointerSet (operand *right,
8893                               operand *result, iCode *ic)
8894 {
8895     int size, offset ;
8896     sym_link *retype = getSpec(operandType(right));
8897
8898     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8899     aopOp(result,ic,FALSE);
8900
8901     /* if the operand is already in dptr 
8902     then we do nothing else we move the value to dptr */
8903     if (AOP_TYPE(result) != AOP_STR) {
8904         /* if this is remateriazable */
8905         if (AOP_TYPE(result) == AOP_IMMD)
8906             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8907         else { /* we need to get it byte by byte */
8908             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8909             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8910             if (options.model == MODEL_FLAT24)
8911             {
8912                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8913             }
8914         }
8915     }
8916     /* so dptr know contains the address */
8917     freeAsmop(result,NULL,ic,TRUE);
8918     aopOp(right,ic,FALSE);
8919
8920     /* if bit then unpack */
8921     if (IS_BITVAR(retype)) 
8922         genPackBits(retype,right,"dptr",FPOINTER);
8923     else {
8924         size = AOP_SIZE(right);
8925         offset = 0 ;
8926
8927         while (size--) {
8928             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8929             MOVA(l);
8930             pic14_emitcode("movx","@dptr,a");
8931             if (size)
8932                 pic14_emitcode("inc","dptr");
8933         }
8934     }
8935
8936     freeAsmop(right,NULL,ic,TRUE);
8937 }
8938
8939 /*-----------------------------------------------------------------*/
8940 /* genGenPointerSet - set value from generic pointer space         */
8941 /*-----------------------------------------------------------------*/
8942 static void genGenPointerSet (operand *right,
8943                               operand *result, iCode *ic)
8944 {
8945   int size, offset ;
8946   sym_link *retype = getSpec(operandType(right));
8947
8948   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8949
8950   aopOp(result,ic,FALSE);
8951   aopOp(right,ic,FALSE);
8952   size = AOP_SIZE(right);
8953
8954   DEBUGpic14_AopType(__LINE__,NULL,right,result);
8955
8956   /* if the operand is already in dptr 
8957      then we do nothing else we move the value to dptr */
8958   if (AOP_TYPE(result) != AOP_STR) {
8959     /* if this is remateriazable */
8960     if (AOP_TYPE(result) == AOP_IMMD) {
8961       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8962       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8963     }
8964     else { /* we need to get it byte by byte */
8965       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8966       size = AOP_SIZE(right);
8967       offset = 0 ;
8968
8969       /* hack hack! see if this the FSR. If so don't load W */
8970       if(AOP_TYPE(right) != AOP_ACC) {
8971
8972
8973         emitpcode(POC_MOVFW,popGet(AOP(result),0));
8974         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8975
8976         if(AOP_SIZE(result) > 1) {
8977           emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8978           emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8979           emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8980
8981         }
8982
8983         //if(size==2)
8984         //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8985         //if(size==4) {
8986         //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8987         //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8988         //}
8989
8990         while(size--) {
8991           emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8992           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8993           
8994           if(size)
8995             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8996         }
8997
8998
8999         goto release;
9000       } 
9001
9002       if(aopIdx(AOP(result),0) != 4) {
9003
9004         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9005         goto release;
9006       }
9007
9008       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9009       goto release;
9010
9011     }
9012   }
9013   /* so dptr know contains the address */
9014
9015
9016   /* if bit then unpack */
9017   if (IS_BITVAR(retype)) 
9018     genPackBits(retype,right,"dptr",GPOINTER);
9019   else {
9020     size = AOP_SIZE(right);
9021     offset = 0 ;
9022
9023   DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
9024
9025     while (size--) {
9026
9027       emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9028       emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9029
9030       if (AOP_TYPE(right) == AOP_LIT) 
9031         emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9032       else
9033         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9034
9035       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9036
9037       offset++;
9038     }
9039   }
9040
9041  release:
9042   freeAsmop(right,NULL,ic,TRUE);
9043   freeAsmop(result,NULL,ic,TRUE);
9044 }
9045
9046 /*-----------------------------------------------------------------*/
9047 /* genPointerSet - stores the value into a pointer location        */
9048 /*-----------------------------------------------------------------*/
9049 static void genPointerSet (iCode *ic)
9050 {    
9051     operand *right, *result ;
9052     sym_link *type, *etype;
9053     int p_type;
9054
9055     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9056
9057     right = IC_RIGHT(ic);
9058     result = IC_RESULT(ic) ;
9059
9060     /* depending on the type of pointer we need to
9061     move it to the correct pointer register */
9062     type = operandType(result);
9063     etype = getSpec(type);
9064     /* if left is of type of pointer then it is simple */
9065     if (IS_PTR(type) && !IS_FUNC(type->next)) {
9066         p_type = DCL_TYPE(type);
9067     }
9068     else {
9069         /* we have to go by the storage class */
9070         p_type = PTR_TYPE(SPEC_OCLS(etype));
9071
9072 /*      if (SPEC_OCLS(etype)->codesp ) { */
9073 /*          p_type = CPOINTER ;  */
9074 /*      } */
9075 /*      else */
9076 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9077 /*              p_type = FPOINTER ; */
9078 /*          else */
9079 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9080 /*                  p_type = PPOINTER ; */
9081 /*              else */
9082 /*                  if (SPEC_OCLS(etype) == idata ) */
9083 /*                      p_type = IPOINTER ; */
9084 /*                  else */
9085 /*                      p_type = POINTER ; */
9086     }
9087
9088     /* now that we have the pointer type we assign
9089     the pointer values */
9090     switch (p_type) {
9091
9092     case POINTER:
9093     case IPOINTER:
9094         genNearPointerSet (right,result,ic);
9095         break;
9096
9097     case PPOINTER:
9098         genPagedPointerSet (right,result,ic);
9099         break;
9100
9101     case FPOINTER:
9102         genFarPointerSet (right,result,ic);
9103         break;
9104
9105     case GPOINTER:
9106         genGenPointerSet (right,result,ic);
9107         break;
9108
9109     default:
9110       werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9111               "genPointerSet: illegal pointer type");
9112     }
9113 }
9114
9115 /*-----------------------------------------------------------------*/
9116 /* genIfx - generate code for Ifx statement                        */
9117 /*-----------------------------------------------------------------*/
9118 static void genIfx (iCode *ic, iCode *popIc)
9119 {
9120   operand *cond = IC_COND(ic);
9121   int isbit =0;
9122
9123   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9124
9125   aopOp(cond,ic,FALSE);
9126
9127   /* get the value into acc */
9128   if (AOP_TYPE(cond) != AOP_CRY)
9129     pic14_toBoolean(cond);
9130   else
9131     isbit = 1;
9132   /* the result is now in the accumulator */
9133   freeAsmop(cond,NULL,ic,TRUE);
9134
9135   /* if there was something to be popped then do it */
9136   if (popIc)
9137     genIpop(popIc);
9138
9139   /* if the condition is  a bit variable */
9140   if (isbit && IS_ITEMP(cond) && 
9141       SPIL_LOC(cond)) {
9142     genIfxJump(ic,SPIL_LOC(cond)->rname);
9143     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9144   }
9145   else {
9146     if (isbit && !IS_ITEMP(cond))
9147       genIfxJump(ic,OP_SYMBOL(cond)->rname);
9148     else
9149       genIfxJump(ic,"a");
9150   }
9151   ic->generated = 1;
9152
9153 }
9154
9155 /*-----------------------------------------------------------------*/
9156 /* genAddrOf - generates code for address of                       */
9157 /*-----------------------------------------------------------------*/
9158 static void genAddrOf (iCode *ic)
9159 {
9160   operand *right, *result, *left;
9161   int size, offset ;
9162
9163   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9164
9165
9166   //aopOp(IC_RESULT(ic),ic,FALSE);
9167
9168   aopOp((left=IC_LEFT(ic)),ic,FALSE);
9169   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9170   aopOp((result=IC_RESULT(ic)),ic,TRUE);
9171
9172   DEBUGpic14_AopType(__LINE__,left,right,result);
9173
9174   size = AOP_SIZE(IC_RESULT(ic));
9175   offset = 0;
9176
9177   while (size--) {
9178     emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9179     emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9180     offset++;
9181   }
9182
9183   freeAsmop(left,NULL,ic,FALSE);
9184   freeAsmop(result,NULL,ic,TRUE);
9185
9186 }
9187
9188 #if 0
9189 /*-----------------------------------------------------------------*/
9190 /* genFarFarAssign - assignment when both are in far space         */
9191 /*-----------------------------------------------------------------*/
9192 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9193 {
9194     int size = AOP_SIZE(right);
9195     int offset = 0;
9196     char *l ;
9197     /* first push the right side on to the stack */
9198     while (size--) {
9199         l = aopGet(AOP(right),offset++,FALSE,FALSE);
9200         MOVA(l);
9201         pic14_emitcode ("push","acc");
9202     }
9203     
9204     freeAsmop(right,NULL,ic,FALSE);
9205     /* now assign DPTR to result */
9206     aopOp(result,ic,FALSE);
9207     size = AOP_SIZE(result);
9208     while (size--) {
9209         pic14_emitcode ("pop","acc");
9210         aopPut(AOP(result),"a",--offset);
9211     }
9212     freeAsmop(result,NULL,ic,FALSE);
9213         
9214 }
9215 #endif
9216
9217 /*-----------------------------------------------------------------*/
9218 /* genAssign - generate code for assignment                        */
9219 /*-----------------------------------------------------------------*/
9220 static void genAssign (iCode *ic)
9221 {
9222   operand *result, *right;
9223   int size, offset,know_W;
9224   unsigned long lit = 0L;
9225
9226   result = IC_RESULT(ic);
9227   right  = IC_RIGHT(ic) ;
9228
9229   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9230
9231   /* if they are the same */
9232   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9233     return ;
9234
9235   aopOp(right,ic,FALSE);
9236   aopOp(result,ic,TRUE);
9237
9238   DEBUGpic14_AopType(__LINE__,NULL,right,result);
9239
9240   /* if they are the same registers */
9241   if (pic14_sameRegs(AOP(right),AOP(result)))
9242     goto release;
9243
9244   /* if the result is a bit */
9245   if (AOP_TYPE(result) == AOP_CRY) {
9246
9247     /* if the right size is a literal then
9248        we know what the value is */
9249     if (AOP_TYPE(right) == AOP_LIT) {
9250           
9251       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9252                   popGet(AOP(result),0));
9253
9254       if (((int) operandLitValue(right))) 
9255         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9256                        AOP(result)->aopu.aop_dir,
9257                        AOP(result)->aopu.aop_dir);
9258       else
9259         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9260                        AOP(result)->aopu.aop_dir,
9261                        AOP(result)->aopu.aop_dir);
9262       goto release;
9263     }
9264
9265     /* the right is also a bit variable */
9266     if (AOP_TYPE(right) == AOP_CRY) {
9267       emitpcode(POC_BCF,    popGet(AOP(result),0));
9268       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9269       emitpcode(POC_BSF,    popGet(AOP(result),0));
9270
9271       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9272                      AOP(result)->aopu.aop_dir,
9273                      AOP(result)->aopu.aop_dir);
9274       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9275                      AOP(right)->aopu.aop_dir,
9276                      AOP(right)->aopu.aop_dir);
9277       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9278                      AOP(result)->aopu.aop_dir,
9279                      AOP(result)->aopu.aop_dir);
9280       goto release ;
9281     }
9282
9283     /* we need to or */
9284     emitpcode(POC_BCF,    popGet(AOP(result),0));
9285     pic14_toBoolean(right);
9286     emitSKPZ;
9287     emitpcode(POC_BSF,    popGet(AOP(result),0));
9288     //aopPut(AOP(result),"a",0);
9289     goto release ;
9290   }
9291
9292   /* bit variables done */
9293   /* general case */
9294   size = AOP_SIZE(result);
9295   offset = 0 ;
9296   if(AOP_TYPE(right) == AOP_LIT)
9297     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9298
9299   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9300   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9301     if(aopIdx(AOP(result),0) == 4) {
9302   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9303       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9304       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9305       goto release;
9306     } else
9307       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9308   }
9309
9310   know_W=-1;
9311   while (size--) {
9312   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9313     if(AOP_TYPE(right) == AOP_LIT) {
9314       if(lit&0xff) {
9315         if(know_W != (lit&0xff))
9316           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9317         know_W = lit&0xff;
9318         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9319       } else
9320         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9321
9322       lit >>= 8;
9323
9324     } else if (AOP_TYPE(right) == AOP_CRY) {
9325       emitpcode(POC_CLRF, popGet(AOP(result),offset));
9326       if(offset == 0) {
9327         emitpcode(POC_BTFSS, popGet(AOP(right),0));
9328         emitpcode(POC_INCF, popGet(AOP(result),0));
9329       }
9330     } else {
9331   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9332       emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9333       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9334     }
9335             
9336     offset++;
9337   }
9338
9339     
9340  release:
9341   freeAsmop (right,NULL,ic,FALSE);
9342   freeAsmop (result,NULL,ic,TRUE);
9343 }   
9344
9345 /*-----------------------------------------------------------------*/
9346 /* genJumpTab - genrates code for jump table                       */
9347 /*-----------------------------------------------------------------*/
9348 static void genJumpTab (iCode *ic)
9349 {
9350     symbol *jtab;
9351     char *l;
9352
9353     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9354
9355     aopOp(IC_JTCOND(ic),ic,FALSE);
9356     /* get the condition into accumulator */
9357     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9358     MOVA(l);
9359     /* multiply by three */
9360     pic14_emitcode("add","a,acc");
9361     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9362
9363     jtab = newiTempLabel(NULL);
9364     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9365     pic14_emitcode("jmp","@a+dptr");
9366     pic14_emitcode("","%05d_DS_:",jtab->key+100);
9367
9368     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9369     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9370     emitSKPNC;
9371     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9372     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9373     emitpLabel(jtab->key);
9374
9375     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9376
9377     /* now generate the jump labels */
9378     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9379          jtab = setNextItem(IC_JTLABELS(ic))) {
9380         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9381         emitpcode(POC_GOTO,popGetLabel(jtab->key));
9382         
9383     }
9384
9385 }
9386
9387 /*-----------------------------------------------------------------*/
9388 /* genMixedOperation - gen code for operators between mixed types  */
9389 /*-----------------------------------------------------------------*/
9390 /*
9391   TSD - Written for the PIC port - but this unfortunately is buggy.
9392   This routine is good in that it is able to efficiently promote 
9393   types to different (larger) sizes. Unfortunately, the temporary
9394   variables that are optimized out by this routine are sometimes
9395   used in other places. So until I know how to really parse the 
9396   iCode tree, I'm going to not be using this routine :(.
9397 */
9398 static int genMixedOperation (iCode *ic)
9399 {
9400 #if 0
9401   operand *result = IC_RESULT(ic);
9402   sym_link *ctype = operandType(IC_LEFT(ic));
9403   operand *right = IC_RIGHT(ic);
9404   int ret = 0;
9405   int big,small;
9406   int offset;
9407
9408   iCode *nextic;
9409   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9410
9411   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9412
9413   nextic = ic->next;
9414   if(!nextic)
9415     return 0;
9416
9417   nextright = IC_RIGHT(nextic);
9418   nextleft  = IC_LEFT(nextic);
9419   nextresult = IC_RESULT(nextic);
9420
9421   aopOp(right,ic,FALSE);
9422   aopOp(result,ic,FALSE);
9423   aopOp(nextright,  nextic, FALSE);
9424   aopOp(nextleft,   nextic, FALSE);
9425   aopOp(nextresult, nextic, FALSE);
9426
9427   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9428
9429     operand *t = right;
9430     right = nextright;
9431     nextright = t; 
9432
9433     pic14_emitcode(";remove right +","");
9434
9435   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9436 /*
9437     operand *t = right;
9438     right = nextleft;
9439     nextleft = t; 
9440 */
9441     pic14_emitcode(";remove left +","");
9442   } else
9443     return 0;
9444
9445   big = AOP_SIZE(nextleft);
9446   small = AOP_SIZE(nextright);
9447
9448   switch(nextic->op) {
9449
9450   case '+':
9451     pic14_emitcode(";optimize a +","");
9452     /* if unsigned or not an integral type */
9453     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9454       pic14_emitcode(";add a bit to something","");
9455     } else {
9456
9457       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9458
9459       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9460         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9461         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9462       } else
9463         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9464
9465       offset = 0;
9466       while(--big) {
9467
9468         offset++;
9469
9470         if(--small) {
9471           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9472             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9473             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9474           }
9475
9476           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9477           emitSKPNC;
9478           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9479                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9480                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9481           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9482           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9483
9484         } else {
9485           pic14_emitcode("rlf","known_zero,w");
9486
9487           /*
9488             if right is signed
9489               btfsc  right,7
9490                addlw ff
9491           */
9492           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9493             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9494             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9495           } else {
9496             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9497           }
9498         }
9499       }
9500       ret = 1;
9501     }
9502   }
9503   ret = 1;
9504
9505 release:
9506   freeAsmop(right,NULL,ic,TRUE);
9507   freeAsmop(result,NULL,ic,TRUE);
9508   freeAsmop(nextright,NULL,ic,TRUE);
9509   freeAsmop(nextleft,NULL,ic,TRUE);
9510   if(ret)
9511     nextic->generated = 1;
9512
9513   return ret;
9514 #else
9515   return 0;
9516 #endif
9517 }
9518 /*-----------------------------------------------------------------*/
9519 /* genCast - gen code for casting                                  */
9520 /*-----------------------------------------------------------------*/
9521 static void genCast (iCode *ic)
9522 {
9523     operand *result = IC_RESULT(ic);
9524     sym_link *ctype = operandType(IC_LEFT(ic));
9525     sym_link *rtype = operandType(IC_RIGHT(ic));
9526     operand *right = IC_RIGHT(ic);
9527     int size, offset ;
9528
9529     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9530     /* if they are equivalent then do nothing */
9531     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9532         return ;
9533
9534     aopOp(right,ic,FALSE) ;
9535     aopOp(result,ic,FALSE);
9536
9537     DEBUGpic14_AopType(__LINE__,NULL,right,result);
9538
9539     /* if the result is a bit */
9540     if (AOP_TYPE(result) == AOP_CRY) {
9541         /* if the right size is a literal then
9542         we know what the value is */
9543       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9544         if (AOP_TYPE(right) == AOP_LIT) {
9545
9546           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9547                       popGet(AOP(result),0));
9548
9549             if (((int) operandLitValue(right))) 
9550               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9551                        AOP(result)->aopu.aop_dir,
9552                        AOP(result)->aopu.aop_dir);
9553             else
9554               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9555                        AOP(result)->aopu.aop_dir,
9556                        AOP(result)->aopu.aop_dir);
9557
9558             goto release;
9559         }
9560
9561         /* the right is also a bit variable */
9562         if (AOP_TYPE(right) == AOP_CRY) {
9563
9564           emitCLRC;
9565           emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9566
9567           pic14_emitcode("clrc","");
9568           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9569                    AOP(right)->aopu.aop_dir,
9570                    AOP(right)->aopu.aop_dir);
9571             aopPut(AOP(result),"c",0);
9572             goto release ;
9573         }
9574
9575         /* we need to or */
9576         if (AOP_TYPE(right) == AOP_REG) {
9577           emitpcode(POC_BCF,    popGet(AOP(result),0));
9578           emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9579           emitpcode(POC_BSF,    popGet(AOP(result),0));
9580         }
9581         pic14_toBoolean(right);
9582         aopPut(AOP(result),"a",0);
9583         goto release ;
9584     }
9585
9586     if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9587       int offset = 1;
9588       size = AOP_SIZE(result);
9589
9590       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9591
9592       emitpcode(POC_CLRF,   popGet(AOP(result),0));
9593       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9594       emitpcode(POC_INCF,   popGet(AOP(result),0));
9595
9596       while (size--)
9597         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9598
9599       goto release;
9600     }
9601
9602     /* if they are the same size : or less */
9603     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9604
9605         /* if they are in the same place */
9606       if (pic14_sameRegs(AOP(right),AOP(result)))
9607         goto release;
9608
9609       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9610       if (IS_PTR_CONST(rtype))
9611         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9612       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9613         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9614
9615       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9616         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9617         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9618         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9619         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9620         if(AOP_SIZE(result) <2)
9621           fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9622
9623       } else {
9624
9625         /* if they in different places then copy */
9626         size = AOP_SIZE(result);
9627         offset = 0 ;
9628         while (size--) {
9629           emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9630           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9631
9632           //aopPut(AOP(result),
9633           // aopGet(AOP(right),offset,FALSE,FALSE),
9634           // offset);
9635
9636           offset++;
9637         }
9638       }
9639       goto release;
9640     }
9641
9642
9643     /* if the result is of type pointer */
9644     if (IS_PTR(ctype)) {
9645
9646         int p_type;
9647         sym_link *type = operandType(right);
9648         sym_link *etype = getSpec(type);
9649       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9650
9651         /* pointer to generic pointer */
9652         if (IS_GENPTR(ctype)) {
9653             char *l = zero;
9654             
9655             if (IS_PTR(type)) 
9656                 p_type = DCL_TYPE(type);
9657             else {
9658                 /* we have to go by the storage class */
9659                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9660
9661 /*              if (SPEC_OCLS(etype)->codesp )  */
9662 /*                  p_type = CPOINTER ;  */
9663 /*              else */
9664 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9665 /*                      p_type = FPOINTER ; */
9666 /*                  else */
9667 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9668 /*                          p_type = PPOINTER; */
9669 /*                      else */
9670 /*                          if (SPEC_OCLS(etype) == idata ) */
9671 /*                              p_type = IPOINTER ; */
9672 /*                          else */
9673 /*                              p_type = POINTER ; */
9674             }
9675                 
9676             /* the first two bytes are known */
9677       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9678             size = GPTRSIZE - 1; 
9679             offset = 0 ;
9680             while (size--) {
9681               if(offset < AOP_SIZE(right)) {
9682       DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9683                 if ((AOP_TYPE(right) == AOP_PCODE) && 
9684                     AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9685                   emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9686                   emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9687                 } else { 
9688                   aopPut(AOP(result),
9689                          aopGet(AOP(right),offset,FALSE,FALSE),
9690                          offset);
9691                 }
9692               } else 
9693                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9694               offset++;
9695             }
9696             /* the last byte depending on type */
9697             switch (p_type) {
9698             case IPOINTER:
9699             case POINTER:
9700                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9701                 break;
9702             case FPOINTER:
9703               pic14_emitcode(";BUG!? ","%d",__LINE__);
9704                 l = one;
9705                 break;
9706             case CPOINTER:
9707               pic14_emitcode(";BUG!? ","%d",__LINE__);
9708                 l = "#0x02";
9709                 break;                          
9710             case PPOINTER:
9711               pic14_emitcode(";BUG!? ","%d",__LINE__);
9712                 l = "#0x03";
9713                 break;
9714                 
9715             default:
9716                 /* this should never happen */
9717                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9718                        "got unknown pointer type");
9719                 exit(1);
9720             }
9721             //aopPut(AOP(result),l, GPTRSIZE - 1);          
9722             goto release ;
9723         }
9724         
9725         /* just copy the pointers */
9726         size = AOP_SIZE(result);
9727         offset = 0 ;
9728         while (size--) {
9729             aopPut(AOP(result),
9730                    aopGet(AOP(right),offset,FALSE,FALSE),
9731                    offset);
9732             offset++;
9733         }
9734         goto release ;
9735     }
9736     
9737
9738
9739     /* so we now know that the size of destination is greater
9740     than the size of the source.
9741     Now, if the next iCode is an operator then we might be
9742     able to optimize the operation without performing a cast.
9743     */
9744     if(genMixedOperation(ic))
9745       goto release;
9746
9747     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9748     
9749     /* we move to result for the size of source */
9750     size = AOP_SIZE(right);
9751     offset = 0 ;
9752     while (size--) {
9753       emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9754       emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9755       offset++;
9756     }
9757
9758     /* now depending on the sign of the destination */
9759     size = AOP_SIZE(result) - AOP_SIZE(right);
9760     /* if unsigned or not an integral type */
9761     if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9762       while (size--)
9763         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9764     } else {
9765       /* we need to extend the sign :{ */
9766
9767       if(size == 1) {
9768         /* Save one instruction of casting char to int */
9769         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9770         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9771         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9772       } else {
9773         emitpcodeNULLop(POC_CLRW);
9774
9775         if(offset)
9776           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9777         else
9778           emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9779         
9780         emitpcode(POC_MOVLW,   popGetLit(0xff));
9781
9782         while (size--)
9783           emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9784       }
9785     }
9786
9787 release:
9788     freeAsmop(right,NULL,ic,TRUE);
9789     freeAsmop(result,NULL,ic,TRUE);
9790
9791 }
9792
9793 /*-----------------------------------------------------------------*/
9794 /* genDjnz - generate decrement & jump if not zero instrucion      */
9795 /*-----------------------------------------------------------------*/
9796 static int genDjnz (iCode *ic, iCode *ifx)
9797 {
9798     symbol *lbl, *lbl1;
9799     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9800
9801     if (!ifx)
9802         return 0;
9803     
9804     /* if the if condition has a false label
9805        then we cannot save */
9806     if (IC_FALSE(ifx))
9807         return 0;
9808
9809     /* if the minus is not of the form 
9810        a = a - 1 */
9811     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9812         !IS_OP_LITERAL(IC_RIGHT(ic)))
9813         return 0;
9814
9815     if (operandLitValue(IC_RIGHT(ic)) != 1)
9816         return 0;
9817
9818     /* if the size of this greater than one then no
9819        saving */
9820     if (getSize(operandType(IC_RESULT(ic))) > 1)
9821         return 0;
9822
9823     /* otherwise we can save BIG */
9824     lbl = newiTempLabel(NULL);
9825     lbl1= newiTempLabel(NULL);
9826
9827     aopOp(IC_RESULT(ic),ic,FALSE);
9828     
9829     if (IS_AOP_PREG(IC_RESULT(ic))) {
9830         pic14_emitcode("dec","%s",
9831                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9832         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9833         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9834     } else {    
9835
9836
9837       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9838       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9839
9840       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9841       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9842
9843     }
9844 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9845 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9846 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9847 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9848
9849     
9850     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9851     ifx->generated = 1;
9852     return 1;
9853 }
9854
9855 /*-----------------------------------------------------------------*/
9856 /* genReceive - generate code for a receive iCode                  */
9857 /*-----------------------------------------------------------------*/
9858 static void genReceive (iCode *ic)
9859 {    
9860   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9861
9862   if (isOperandInFarSpace(IC_RESULT(ic)) && 
9863       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9864         IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9865
9866     int size = getSize(operandType(IC_RESULT(ic)));
9867     int offset =  fReturnSizePic - size;
9868     while (size--) {
9869       pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9870                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9871       offset++;
9872     }
9873     aopOp(IC_RESULT(ic),ic,FALSE);  
9874     size = AOP_SIZE(IC_RESULT(ic));
9875     offset = 0;
9876     while (size--) {
9877       pic14_emitcode ("pop","acc");
9878       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9879     }
9880         
9881   } else {
9882     _G.accInUse++;
9883     aopOp(IC_RESULT(ic),ic,FALSE);  
9884     _G.accInUse--;
9885     assignResultValue(IC_RESULT(ic));   
9886   }
9887
9888   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9889 }
9890
9891 /*-----------------------------------------------------------------*/
9892 /* genpic14Code - generate code for pic14 based controllers        */
9893 /*-----------------------------------------------------------------*/
9894 /*
9895  * At this point, ralloc.c has gone through the iCode and attempted
9896  * to optimize in a way suitable for a PIC. Now we've got to generate
9897  * PIC instructions that correspond to the iCode.
9898  *
9899  * Once the instructions are generated, we'll pass through both the
9900  * peep hole optimizer and the pCode optimizer.
9901  *-----------------------------------------------------------------*/
9902
9903 void genpic14Code (iCode *lic)
9904 {
9905     iCode *ic;
9906     int cln = 0;
9907
9908     lineHead = lineCurr = NULL;
9909
9910     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9911     addpBlock(pb);
9912
9913     /* if debug information required */
9914     if (options.debug && currFunc) { 
9915       if (currFunc) {
9916         debugFile->writeFunction(currFunc);
9917         _G.debugLine = 1;
9918         if (IS_STATIC(currFunc->etype)) {
9919           pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9920           //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9921         } else {
9922           pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9923           //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9924         }
9925         _G.debugLine = 0;
9926       }
9927     }
9928
9929
9930     for (ic = lic ; ic ; ic = ic->next ) {
9931
9932       DEBUGpic14_emitcode(";ic","");
9933         if ( cln != ic->lineno ) {
9934             if ( options.debug ) {
9935                 _G.debugLine = 1;
9936                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9937                          FileBaseName(ic->filename),ic->lineno,
9938                          ic->level,ic->block);
9939                 _G.debugLine = 0;
9940             }
9941             /*
9942               pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9943               pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9944               printCLine(ic->filename, ic->lineno));
9945             */
9946             if (!options.noCcodeInAsm) {
9947               addpCode2pBlock(pb,
9948                               newpCodeCSource(ic->lineno, 
9949                                               ic->filename, 
9950                                               printCLine(ic->filename, ic->lineno)));
9951             }
9952
9953             cln = ic->lineno ;
9954         }
9955
9956         // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9957
9958         /* if the result is marked as
9959            spilt and rematerializable or code for
9960            this has already been generated then
9961            do nothing */
9962         if (resultRemat(ic) || ic->generated ) 
9963             continue ;
9964         
9965         /* depending on the operation */
9966         switch (ic->op) {
9967         case '!' :
9968             genNot(ic);
9969             break;
9970             
9971         case '~' :
9972             genCpl(ic);
9973             break;
9974             
9975         case UNARYMINUS:
9976             genUminus (ic);
9977             break;
9978             
9979         case IPUSH:
9980             genIpush (ic);
9981             break;
9982             
9983         case IPOP:
9984             /* IPOP happens only when trying to restore a 
9985                spilt live range, if there is an ifx statement
9986                following this pop then the if statement might
9987                be using some of the registers being popped which
9988                would destory the contents of the register so
9989                we need to check for this condition and handle it */
9990             if (ic->next            && 
9991                 ic->next->op == IFX &&
9992                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9993                 genIfx (ic->next,ic);
9994             else
9995                 genIpop (ic);
9996             break; 
9997             
9998         case CALL:
9999             genCall (ic);
10000             break;
10001             
10002         case PCALL:
10003             genPcall (ic);
10004             break;
10005             
10006         case FUNCTION:
10007             genFunction (ic);
10008             break;
10009             
10010         case ENDFUNCTION:
10011             genEndFunction (ic);
10012             break;
10013             
10014         case RETURN:
10015             genRet (ic);
10016             break;
10017             
10018         case LABEL:
10019             genLabel (ic);
10020             break;
10021             
10022         case GOTO:
10023             genGoto (ic);
10024             break;
10025             
10026         case '+' :
10027             genPlus (ic) ;
10028             break;
10029             
10030         case '-' :
10031             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10032                 genMinus (ic);
10033             break;
10034             
10035         case '*' :
10036             genMult (ic);
10037             break;
10038             
10039         case '/' :
10040             genDiv (ic) ;
10041             break;
10042             
10043         case '%' :
10044             genMod (ic);
10045             break;
10046             
10047         case '>' :
10048             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
10049             break;
10050             
10051         case '<' :
10052             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10053             break;
10054             
10055         case LE_OP:
10056         case GE_OP:
10057         case NE_OP:
10058             
10059             /* note these two are xlated by algebraic equivalence
10060                during parsing SDCC.y */
10061             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10062                    "got '>=' or '<=' shouldn't have come here");
10063             break;      
10064             
10065         case EQ_OP:
10066             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10067             break;          
10068             
10069         case AND_OP:
10070             genAndOp (ic);
10071             break;
10072             
10073         case OR_OP:
10074             genOrOp (ic);
10075             break;
10076             
10077         case '^' :
10078             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10079             break;
10080             
10081         case '|' :
10082                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10083             break;
10084             
10085         case BITWISEAND:
10086             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10087             break;
10088             
10089         case INLINEASM:
10090             genInline (ic);
10091             break;
10092             
10093         case RRC:
10094             genRRC (ic);
10095             break;
10096             
10097         case RLC:
10098             genRLC (ic);
10099             break;
10100             
10101         case GETHBIT:
10102             genGetHbit (ic);
10103             break;
10104             
10105         case LEFT_OP:
10106             genLeftShift (ic);
10107             break;
10108             
10109         case RIGHT_OP:
10110             genRightShift (ic);
10111             break;
10112             
10113         case GET_VALUE_AT_ADDRESS:
10114             genPointerGet(ic);
10115             break;
10116             
10117         case '=' :
10118             if (POINTER_SET(ic))
10119                 genPointerSet(ic);
10120             else
10121                 genAssign(ic);
10122             break;
10123             
10124         case IFX:
10125             genIfx (ic,NULL);
10126             break;
10127             
10128         case ADDRESS_OF:
10129             genAddrOf (ic);
10130             break;
10131             
10132         case JUMPTABLE:
10133             genJumpTab (ic);
10134             break;
10135             
10136         case CAST:
10137             genCast (ic);
10138             break;
10139             
10140         case RECEIVE:
10141             genReceive(ic);
10142             break;
10143             
10144         case SEND:
10145             addSet(&_G.sendSet,ic);
10146             break;
10147
10148         default :
10149             ic = ic;
10150         }
10151     }
10152     
10153
10154     /* now we are ready to call the 
10155        peep hole optimizer */
10156     if (!options.nopeep) {
10157       peepHole (&lineHead);
10158     }
10159     /* now do the actual printing */
10160     printLine (lineHead,codeOutFile);
10161
10162 #ifdef PCODE_DEBUG
10163     DFPRINTF((stderr,"printing pBlock\n\n"));
10164     printpBlock(stdout,pb);
10165 #endif
10166
10167     return;
10168 }