13b47648c4c6363be853222b1782af46f3922eda
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   SDCCgen51.c - source file for code generation for 8051
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
29                 Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
41 #else
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
44 #else
45 #ifdef HAVE_ENDIAN_H
46 #include <endian.h>
47 #else
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
51 #endif
52 #endif
53 #endif
54 #endif
55
56 #include "common.h"
57 #include "SDCCpeeph.h"
58 #include "ralloc.h"
59 #include "pcode.h"
60 #include "gen.h"
61
62 /*
63   if(IC_RESULT(ic) && AOP(IC_RESULT(ic)))
64     DEBUGpic14_emitcode ("; ","result %s",
65                          AopType(AOP_TYPE(IC_RESULT(ic))));
66
67   if(IC_LEFT(ic) && AOP(IC_LEFT(ic)))
68     DEBUGpic14_emitcode ("; ","left %s",
69                        AopType(AOP_TYPE(IC_LEFT(ic))));
70
71   if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic)))
72     DEBUGpic14_emitcode ("; ","right %s",
73                        AopType(AOP_TYPE(IC_RIGHT(ic))));
74 */
75
76
77 static int labelOffset=0;
78 static int debug_verbose=1;
79 static int optimized_for_speed = 0;
80
81 /* max_key keeps track of the largest label number used in 
82    a function. This is then used to adjust the label offset
83    for the next function.
84 */
85 static int max_key=0;
86 static int GpsuedoStkPtr=0;
87
88 unsigned int pic14aopLiteral (value *val, int offset);
89 const char *AopType(short type);
90
91 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
92
93 /* this is the down and dirty file with all kinds of 
94    kludgy & hacky stuff. This is what it is all about
95    CODE GENERATION for a specific MCU . some of the
96    routines may be reusable, will have to see */
97
98 static char *zero = "#0x00";
99 static char *one  = "#0x01";
100 static char *spname = "sp";
101
102 char *fReturnpic14[] = {"FSR","dph","b","a" };
103 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
104 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
105 static char **fReturn = fReturnpic14;
106
107 static char *accUse[] = {"a","b"};
108
109 //static short rbank = -1;
110
111 static struct {
112     short r0Pushed;
113     short r1Pushed;
114     short accInUse;
115     short inLine;
116     short debugLine;
117     short nRegsSaved;
118     set *sendSet;
119 } _G;
120
121 /* Resolved ifx structure. This structure stores information
122    about an iCode ifx that makes it easier to generate code.
123 */
124 typedef struct resolvedIfx {
125   symbol *lbl;     /* pointer to a label */
126   int condition;   /* true or false ifx */
127   int generated;   /* set true when the code associated with the ifx
128                     * is generated */
129 } resolvedIfx;
130
131 extern int pic14_ptrRegReq ;
132 extern int pic14_nRegs;
133 extern FILE *codeOutFile;
134 static void saverbank (int, iCode *,bool);
135
136 static lineNode *lineHead = NULL;
137 static lineNode *lineCurr = NULL;
138
139 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
140 0xE0, 0xC0, 0x80, 0x00};
141 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
142 0x07, 0x03, 0x01, 0x00};
143
144 static  pBlock *pb;
145
146 /*-----------------------------------------------------------------*/
147 /*  my_powof2(n) - If `n' is an integaer power of 2, then the      */
148 /*                 exponent of 2 is returned, otherwise -1 is      */
149 /*                 returned.                                       */
150 /* note that this is similar to the function `powof2' in SDCCsymt  */
151 /* if(n == 2^y)                                                    */
152 /*   return y;                                                     */
153 /* return -1;                                                      */
154 /*-----------------------------------------------------------------*/
155 static int my_powof2 (unsigned long num)
156 {
157   if(num) {
158     if( (num & (num-1)) == 0) {
159       int nshifts = -1;
160       while(num) {
161         num>>=1;
162         nshifts++;
163       }
164       return nshifts;
165     }
166   }
167
168   return -1;
169 }
170
171 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
172 {
173     va_list ap;
174     char lb[INITIAL_INLINEASM];  
175     char *lbp = lb;
176
177     if(!debug_verbose)
178       return;
179
180     va_start(ap,fmt);   
181
182     if (inst && *inst) {
183         if (fmt && *fmt)
184             sprintf(lb,"%s\t",inst);
185         else
186             sprintf(lb,"%s",inst);
187         vsprintf(lb+(strlen(lb)),fmt,ap);
188     }  else
189         vsprintf(lb,fmt,ap);
190
191     while (isspace(*lbp)) lbp++;
192
193     if (lbp && *lbp) 
194         lineCurr = (lineCurr ?
195                     connectLine(lineCurr,newLineNode(lb)) :
196                     (lineHead = newLineNode(lb)));
197     lineCurr->isInline = _G.inLine;
198     lineCurr->isDebug  = _G.debugLine;
199
200     addpCode2pBlock(pb,newpCodeCharP(lb));
201
202     va_end(ap);
203 }
204
205
206 static void emitpLabel(int key)
207 {
208   addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
209 }
210
211 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
212 {
213
214   if(pcop)
215     addpCode2pBlock(pb,newpCode(poc,pcop));
216   else
217     DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
218 }
219
220 void emitpcodeNULLop(PIC_OPCODE poc)
221 {
222
223   addpCode2pBlock(pb,newpCode(poc,NULL));
224
225 }
226
227 /*-----------------------------------------------------------------*/
228 /* pic14_emitcode - writes the code into a file : for now it is simple    */
229 /*-----------------------------------------------------------------*/
230 void pic14_emitcode (char *inst,char *fmt, ...)
231 {
232     va_list ap;
233     char lb[INITIAL_INLINEASM];  
234     char *lbp = lb;
235
236     va_start(ap,fmt);   
237
238     if (inst && *inst) {
239         if (fmt && *fmt)
240             sprintf(lb,"%s\t",inst);
241         else
242             sprintf(lb,"%s",inst);
243         vsprintf(lb+(strlen(lb)),fmt,ap);
244     }  else
245         vsprintf(lb,fmt,ap);
246
247     while (isspace(*lbp)) lbp++;
248
249     if (lbp && *lbp) 
250         lineCurr = (lineCurr ?
251                     connectLine(lineCurr,newLineNode(lb)) :
252                     (lineHead = newLineNode(lb)));
253     lineCurr->isInline = _G.inLine;
254     lineCurr->isDebug  = _G.debugLine;
255
256     if(debug_verbose)
257       addpCode2pBlock(pb,newpCodeCharP(lb));
258
259     va_end(ap);
260 }
261
262
263 /*-----------------------------------------------------------------*/
264 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
265 /*-----------------------------------------------------------------*/
266 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
267 {
268     bool r0iu = FALSE , r1iu = FALSE;
269     bool r0ou = FALSE , r1ou = FALSE;
270
271     /* the logic: if r0 & r1 used in the instruction
272     then we are in trouble otherwise */
273
274     /* first check if r0 & r1 are used by this
275     instruction, in which case we are in trouble */
276     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
277         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
278     {
279         goto endOfWorld;      
280     }
281
282     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
283     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
284
285     /* if no usage of r0 then return it */
286     if (!r0iu && !r0ou) {
287         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
288         (*aopp)->type = AOP_R0;
289         
290         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
291     }
292
293     /* if no usage of r1 then return it */
294     if (!r1iu && !r1ou) {
295         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
296         (*aopp)->type = AOP_R1;
297
298         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
299     }    
300
301     /* now we know they both have usage */
302     /* if r0 not used in this instruction */
303     if (!r0iu) {
304         /* push it if not already pushed */
305         if (!_G.r0Pushed) {
306             pic14_emitcode ("push","%s",
307                       pic14_regWithIdx(R0_IDX)->dname);
308             _G.r0Pushed++ ;
309         }
310         
311         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
312         (*aopp)->type = AOP_R0;
313
314         return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
315     }
316
317     /* if r1 not used then */
318
319     if (!r1iu) {
320         /* push it if not already pushed */
321         if (!_G.r1Pushed) {
322             pic14_emitcode ("push","%s",
323                       pic14_regWithIdx(R1_IDX)->dname);
324             _G.r1Pushed++ ;
325         }
326         
327         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
328         (*aopp)->type = AOP_R1;
329         return pic14_regWithIdx(R1_IDX);
330     }
331
332 endOfWorld :
333     /* I said end of world but not quite end of world yet */
334     /* if this is a result then we can push it on the stack*/
335     if (result) {
336         (*aopp)->type = AOP_STK;    
337         return NULL;
338     }
339
340     /* other wise this is true end of the world */
341     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
342            "getFreePtr should never reach here");
343     exit(0);
344 }
345
346 /*-----------------------------------------------------------------*/
347 /* newAsmop - creates a new asmOp                                  */
348 /*-----------------------------------------------------------------*/
349 asmop *newAsmop (short type)
350 {
351     asmop *aop;
352
353     aop = Safe_calloc(1,sizeof(asmop));
354     aop->type = type;
355     return aop;
356 }
357
358 static void genSetDPTR(int n)
359 {
360     if (!n)
361     {
362         pic14_emitcode(";", "Select standard DPTR");
363         pic14_emitcode("mov", "dps, #0x00");
364     }
365     else
366     {
367         pic14_emitcode(";", "Select alternate DPTR");
368         pic14_emitcode("mov", "dps, #0x01");
369     }
370 }
371
372 /*-----------------------------------------------------------------*/
373 /* resolveIfx - converts an iCode ifx into a form more useful for  */
374 /*              generating code                                    */
375 /*-----------------------------------------------------------------*/
376 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
377 {
378   if(!resIfx) 
379     return;
380
381   DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
382
383   resIfx->condition = 1;    /* assume that the ifx is true */
384   resIfx->generated = 0;    /* indicate that the ifx has not been used */
385
386   if(!ifx) {
387     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
388     DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
389                         __FUNCTION__,__LINE__,resIfx->lbl->key);
390   } else {
391     if(IC_TRUE(ifx)) {
392       resIfx->lbl = IC_TRUE(ifx);
393     } else {
394       resIfx->lbl = IC_FALSE(ifx);
395       resIfx->condition = 0;
396     }
397     if(IC_TRUE(ifx)) 
398       DEBUGpic14_emitcode("; ***","ifx true is non-null");
399     if(IC_FALSE(ifx)) 
400       DEBUGpic14_emitcode("; ***","ifx false is non-null");
401   }
402
403   DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
404
405 }
406 /*-----------------------------------------------------------------*/
407 /* pointerCode - returns the code for a pointer type               */
408 /*-----------------------------------------------------------------*/
409 static int pointerCode (sym_link *etype)
410 {
411
412     return PTR_TYPE(SPEC_OCLS(etype));
413
414 }
415
416 /*-----------------------------------------------------------------*/
417 /* aopForSym - for a true symbol                                   */
418 /*-----------------------------------------------------------------*/
419 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
420 {
421     asmop *aop;
422     memmap *space= SPEC_OCLS(sym->etype);
423
424     DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
425     /* if already has one */
426     if (sym->aop)
427         return sym->aop;
428
429     /* assign depending on the storage class */
430     /* if it is on the stack or indirectly addressable */
431     /* space we need to assign either r0 or r1 to it   */    
432     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
433         sym->aop = aop = newAsmop(0);
434         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
435         aop->size = getSize(sym->type);
436
437         /* now assign the address of the variable to 
438         the pointer register */
439         if (aop->type != AOP_STK) {
440
441             if (sym->onStack) {
442                     if ( _G.accInUse )
443                         pic14_emitcode("push","acc");
444
445                     pic14_emitcode("mov","a,_bp");
446                     pic14_emitcode("add","a,#0x%02x",
447                              ((sym->stack < 0) ?
448                               ((char)(sym->stack - _G.nRegsSaved )) :
449                               ((char)sym->stack)) & 0xff);
450                     pic14_emitcode("mov","%s,a",
451                              aop->aopu.aop_ptr->name);
452
453                     if ( _G.accInUse )
454                         pic14_emitcode("pop","acc");
455             } else
456                 pic14_emitcode("mov","%s,#%s",
457                          aop->aopu.aop_ptr->name,
458                          sym->rname);
459             aop->paged = space->paged;
460         } else
461             aop->aopu.aop_stk = sym->stack;
462         return aop;
463     }
464     
465     if (sym->onStack && options.stack10bit)
466     {
467         /* It's on the 10 bit stack, which is located in
468          * far data space.
469          */
470          
471       //DEBUGpic14_emitcode(";","%d",__LINE__);
472
473         if ( _G.accInUse )
474                 pic14_emitcode("push","acc");
475
476         pic14_emitcode("mov","a,_bp");
477         pic14_emitcode("add","a,#0x%02x",
478                  ((sym->stack < 0) ?
479                    ((char)(sym->stack - _G.nRegsSaved )) :
480                    ((char)sym->stack)) & 0xff);
481         
482         genSetDPTR(1);
483         pic14_emitcode ("mov","dpx1,#0x40");
484         pic14_emitcode ("mov","dph1,#0x00");
485         pic14_emitcode ("mov","dpl1, a");
486         genSetDPTR(0);
487         
488         if ( _G.accInUse )
489             pic14_emitcode("pop","acc");
490             
491         sym->aop = aop = newAsmop(AOP_DPTR2);
492         aop->size = getSize(sym->type); 
493         return aop;
494     }
495
496     //DEBUGpic14_emitcode(";","%d",__LINE__);
497     /* if in bit space */
498     if (IN_BITSPACE(space)) {
499         sym->aop = aop = newAsmop (AOP_CRY);
500         aop->aopu.aop_dir = sym->rname ;
501         aop->size = getSize(sym->type);
502         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
503         return aop;
504     }
505     /* if it is in direct space */
506     if (IN_DIRSPACE(space)) {
507         sym->aop = aop = newAsmop (AOP_DIR);
508         aop->aopu.aop_dir = sym->rname ;
509         aop->size = getSize(sym->type);
510         DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
511         return aop;
512     }
513
514     /* special case for a function */
515     if (IS_FUNC(sym->type)) {   
516         sym->aop = aop = newAsmop(AOP_IMMD);    
517         //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
518         aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
519         strcpy(aop->aopu.aop_immd,sym->rname);
520         aop->size = FPTRSIZE; 
521         return aop;
522     }
523
524
525     /* only remaining is far space */
526     /* in which case DPTR gets the address */
527     sym->aop = aop = newAsmop(AOP_DPTR);
528     pic14_emitcode ("mov","dptr,#%s", sym->rname);
529     aop->size = getSize(sym->type);
530
531     DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
532     /* if it is in code space */
533     if (IN_CODESPACE(space))
534         aop->code = 1;
535
536     return aop;     
537 }
538
539 /*-----------------------------------------------------------------*/
540 /* aopForRemat - rematerialzes an object                           */
541 /*-----------------------------------------------------------------*/
542 static asmop *aopForRemat (symbol *sym)
543 {
544     iCode *ic = sym->rematiCode;
545     asmop *aop = newAsmop(AOP_IMMD);
546     int val = 0;
547     DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
548     for (;;) {
549         if (ic->op == '+')
550             val += (int) operandLitValue(IC_RIGHT(ic));
551         else if (ic->op == '-')
552             val -= (int) operandLitValue(IC_RIGHT(ic));
553         else
554             break;
555         
556         ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
557     }
558
559     if (val)
560         sprintf(buffer,"(%s %c 0x%04x)",
561                 OP_SYMBOL(IC_LEFT(ic))->rname, 
562                 val >= 0 ? '+' : '-',
563                 abs(val) & 0xffff);
564     else
565         strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
566
567     //DEBUGpic14_emitcode(";","%s",buffer);
568     aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
569     strcpy(aop->aopu.aop_immd,buffer);    
570     return aop;        
571 }
572
573 int aopIdx (asmop *aop, int offset)
574 {
575   if(!aop)
576     return -1;
577
578   if(aop->type !=  AOP_REG)
579     return -2;
580         
581   return aop->aopu.aop_reg[offset]->rIdx;
582
583 }
584 /*-----------------------------------------------------------------*/
585 /* regsInCommon - two operands have some registers in common       */
586 /*-----------------------------------------------------------------*/
587 static bool regsInCommon (operand *op1, operand *op2)
588 {
589     symbol *sym1, *sym2;
590     int i;
591
592     /* if they have registers in common */
593     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
594         return FALSE ;
595
596     sym1 = OP_SYMBOL(op1);
597     sym2 = OP_SYMBOL(op2);
598
599     if (sym1->nRegs == 0 || sym2->nRegs == 0)
600         return FALSE ;
601
602     for (i = 0 ; i < sym1->nRegs ; i++) {
603         int j;
604         if (!sym1->regs[i])
605             continue ;
606
607         for (j = 0 ; j < sym2->nRegs ;j++ ) {
608             if (!sym2->regs[j])
609                 continue ;
610
611             if (sym2->regs[j] == sym1->regs[i])
612                 return TRUE ;
613         }
614     }
615
616     return FALSE ;
617 }
618
619 /*-----------------------------------------------------------------*/
620 /* operandsEqu - equivalent                                        */
621 /*-----------------------------------------------------------------*/
622 static bool operandsEqu ( operand *op1, operand *op2)
623 {
624     symbol *sym1, *sym2;
625
626     /* if they not symbols */
627     if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
628         return FALSE;
629
630     sym1 = OP_SYMBOL(op1);
631     sym2 = OP_SYMBOL(op2);
632
633     /* if both are itemps & one is spilt
634        and the other is not then false */
635     if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
636         sym1->isspilt != sym2->isspilt )
637         return FALSE ;
638
639     /* if they are the same */
640     if (sym1 == sym2)
641         return TRUE ;
642
643     if (strcmp(sym1->rname,sym2->rname) == 0)
644         return TRUE;
645
646
647     /* if left is a tmp & right is not */
648     if (IS_ITEMP(op1)  && 
649         !IS_ITEMP(op2) &&
650         sym1->isspilt  &&
651         (sym1->usl.spillLoc == sym2))
652         return TRUE;
653
654     if (IS_ITEMP(op2)  && 
655         !IS_ITEMP(op1) &&
656         sym2->isspilt  &&
657         sym1->level > 0 &&
658         (sym2->usl.spillLoc == sym1))
659         return TRUE ;
660
661     return FALSE ;
662 }
663
664 /*-----------------------------------------------------------------*/
665 /* pic14_sameRegs - two asmops have the same registers                   */
666 /*-----------------------------------------------------------------*/
667 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
668 {
669     int i;
670
671     if (aop1 == aop2)
672         return TRUE ;
673
674     if (aop1->type != AOP_REG ||
675         aop2->type != AOP_REG )
676         return FALSE ;
677
678     if (aop1->size != aop2->size )
679         return FALSE ;
680
681     for (i = 0 ; i < aop1->size ; i++ )
682         if (aop1->aopu.aop_reg[i] !=
683             aop2->aopu.aop_reg[i] )
684             return FALSE ;
685
686     return TRUE ;
687 }
688
689 /*-----------------------------------------------------------------*/
690 /* aopOp - allocates an asmop for an operand  :                    */
691 /*-----------------------------------------------------------------*/
692 void aopOp (operand *op, iCode *ic, bool result)
693 {
694     asmop *aop;
695     symbol *sym;
696     int i;
697
698     if (!op)
699         return ;
700
701     DEBUGpic14_emitcode(";","%d",__LINE__);
702     /* if this a literal */
703     if (IS_OP_LITERAL(op)) {
704         op->aop = aop = newAsmop(AOP_LIT);
705         aop->aopu.aop_lit = op->operand.valOperand;
706         aop->size = getSize(operandType(op));
707       DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
708         return;
709     }
710
711     /* if already has a asmop then continue */
712     if (op->aop)
713         return ;
714
715     /* if the underlying symbol has a aop */
716     if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
717       DEBUGpic14_emitcode(";","%d",__LINE__);
718         op->aop = OP_SYMBOL(op)->aop;
719         return;
720     }
721
722     /* if this is a true symbol */
723     if (IS_TRUE_SYMOP(op)) {    
724       DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
725         op->aop = aopForSym(ic,OP_SYMBOL(op),result);
726         return ;
727     }
728
729     /* this is a temporary : this has
730     only four choices :
731     a) register
732     b) spillocation
733     c) rematerialize 
734     d) conditional   
735     e) can be a return use only */
736
737     sym = OP_SYMBOL(op);
738
739
740     /* if the type is a conditional */
741     if (sym->regType == REG_CND) {
742       DEBUGpic14_emitcode(";","%d",__LINE__);
743         aop = op->aop = sym->aop = newAsmop(AOP_CRY);
744         aop->size = 0;
745         return;
746     }
747
748     /* if it is spilt then two situations
749     a) is rematerialize 
750     b) has a spill location */
751     if (sym->isspilt || sym->nRegs == 0) {
752
753       DEBUGpic14_emitcode(";","%d",__LINE__);
754         /* rematerialize it NOW */
755         if (sym->remat) {
756             sym->aop = op->aop = aop =
757                                       aopForRemat (sym);
758             aop->size = getSize(sym->type);
759             DEBUGpic14_emitcode(";","%d",__LINE__);
760             return;
761         }
762
763         if (sym->accuse) {
764             int i;
765             aop = op->aop = sym->aop = newAsmop(AOP_ACC);
766             aop->size = getSize(sym->type);
767             for ( i = 0 ; i < 2 ; i++ )
768                 aop->aopu.aop_str[i] = accUse[i];
769             DEBUGpic14_emitcode(";","%d",__LINE__);
770             return;  
771         }
772
773         if (sym->ruonly ) {
774             unsigned i;
775             aop = op->aop = sym->aop = newAsmop(AOP_STR);
776             aop->size = getSize(sym->type);
777             for ( i = 0 ; i < fReturnSizePic ; i++ )
778               aop->aopu.aop_str[i] = fReturn[i];
779             DEBUGpic14_emitcode(";","%d",__LINE__);
780             return;
781         }
782
783         /* else spill location  */
784         DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
785         sym->aop = op->aop = aop = 
786                                   aopForSym(ic,sym->usl.spillLoc,result);
787         aop->size = getSize(sym->type);
788         return;
789     }
790
791     /* must be in a register */
792     sym->aop = op->aop = aop = newAsmop(AOP_REG);
793     aop->size = sym->nRegs;
794     for ( i = 0 ; i < sym->nRegs ;i++)
795         aop->aopu.aop_reg[i] = sym->regs[i];
796 }
797
798 /*-----------------------------------------------------------------*/
799 /* freeAsmop - free up the asmop given to an operand               */
800 /*----------------------------------------------------------------*/
801 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
802 {   
803     asmop *aop ;
804
805     if (!op)
806         aop = aaop;
807     else 
808         aop = op->aop;
809
810     if (!aop)
811         return ;
812
813     if (aop->freed)
814         goto dealloc; 
815
816     aop->freed = 1;
817
818     /* depending on the asmop type only three cases need work AOP_RO
819        , AOP_R1 && AOP_STK */
820     switch (aop->type) {
821         case AOP_R0 :
822             if (_G.r0Pushed ) {
823                 if (pop) {
824                     pic14_emitcode ("pop","ar0");     
825                     _G.r0Pushed--;
826                 }
827             }
828             bitVectUnSetBit(ic->rUsed,R0_IDX);
829             break;
830
831         case AOP_R1 :
832             if (_G.r1Pushed ) {
833                 if (pop) {
834                     pic14_emitcode ("pop","ar1");
835                     _G.r1Pushed--;
836                 }
837             }
838             bitVectUnSetBit(ic->rUsed,R1_IDX);          
839             break;
840
841         case AOP_STK :
842         {
843             int sz = aop->size;    
844             int stk = aop->aopu.aop_stk + aop->size;
845             bitVectUnSetBit(ic->rUsed,R0_IDX);
846             bitVectUnSetBit(ic->rUsed,R1_IDX);          
847
848             getFreePtr(ic,&aop,FALSE);
849             
850             if (options.stack10bit)
851             {
852                 /* I'm not sure what to do here yet... */
853                 /* #STUB */
854                 fprintf(stderr, 
855                         "*** Warning: probably generating bad code for "
856                         "10 bit stack mode.\n");
857             }
858             
859             if (stk) {
860                 pic14_emitcode ("mov","a,_bp");
861                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
862                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
863             } else {
864                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
865             }
866
867             while (sz--) {
868                 pic14_emitcode("pop","acc");
869                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
870                 if (!sz) break;
871                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
872             }
873             op->aop = aop;
874             freeAsmop(op,NULL,ic,TRUE);
875             if (_G.r0Pushed) {
876                 pic14_emitcode("pop","ar0");
877                 _G.r0Pushed--;
878             }
879
880             if (_G.r1Pushed) {
881                 pic14_emitcode("pop","ar1");
882                 _G.r1Pushed--;
883             }       
884         }
885     }
886
887 dealloc:
888     /* all other cases just dealloc */
889     if (op ) {
890         op->aop = NULL;
891         if (IS_SYMOP(op)) {
892             OP_SYMBOL(op)->aop = NULL;    
893             /* if the symbol has a spill */
894             if (SPIL_LOC(op))
895                 SPIL_LOC(op)->aop = NULL;
896         }
897     }
898 }
899
900 /*-----------------------------------------------------------------*/
901 /* aopGet - for fetching value of the aop                          */
902 /*-----------------------------------------------------------------*/
903 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
904 {
905     char *s = buffer ;
906     char *rs;
907
908     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
909     /* offset is greater than
910     size then zero */
911     if (offset > (aop->size - 1) &&
912         aop->type != AOP_LIT)
913         return zero;
914
915     /* depending on type */
916     switch (aop->type) {
917         
918     case AOP_R0:
919     case AOP_R1:
920         DEBUGpic14_emitcode(";","%d",__LINE__);
921         /* if we need to increment it */       
922         while (offset > aop->coff) {        
923             pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);  
924             aop->coff++;
925         }
926         
927         while (offset < aop->coff) {
928             pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
929             aop->coff--;
930         }
931         
932         aop->coff = offset ;
933         if (aop->paged) {
934             pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
935             return (dname ? "acc" : "a");
936         }       
937         sprintf(s,"@%s",aop->aopu.aop_ptr->name);
938         rs = Safe_calloc(1,strlen(s)+1);
939         strcpy(rs,s);   
940         return rs;
941         
942     case AOP_DPTR:
943     case AOP_DPTR2:
944         DEBUGpic14_emitcode(";","%d",__LINE__);
945     if (aop->type == AOP_DPTR2)
946     {
947         genSetDPTR(1);
948     }
949     
950         while (offset > aop->coff) {
951             pic14_emitcode ("inc","dptr");
952             aop->coff++;
953         }
954         
955         while (offset < aop->coff) {        
956             pic14_emitcode("lcall","__decdptr");
957             aop->coff--;
958         }
959         
960         aop->coff = offset;
961         if (aop->code) {
962             pic14_emitcode("clr","a");
963             pic14_emitcode("movc","a,@a+dptr");
964         }
965     else {
966             pic14_emitcode("movx","a,@dptr");
967     }
968             
969     if (aop->type == AOP_DPTR2)
970     {
971         genSetDPTR(0);
972     }
973             
974     return (dname ? "acc" : "a");
975         
976         
977     case AOP_IMMD:
978       DEBUGpic14_emitcode(";","%d",__LINE__);
979         if (bit16) 
980             sprintf (s,"%s",aop->aopu.aop_immd);
981         else
982             if (offset) 
983                 sprintf(s,"(%s >> %d)",
984                         aop->aopu.aop_immd,
985                         offset*8);
986             else
987                 sprintf(s,"%s",
988                         aop->aopu.aop_immd);
989         rs = Safe_calloc(1,strlen(s)+1);
990         strcpy(rs,s);   
991         return rs;
992         
993     case AOP_DIR:
994         if (offset)
995             sprintf(s,"(%s + %d)",
996                     aop->aopu.aop_dir,
997                     offset);
998         else
999             sprintf(s,"%s",aop->aopu.aop_dir);
1000         rs = Safe_calloc(1,strlen(s)+1);
1001         strcpy(rs,s);   
1002         return rs;
1003         
1004     case AOP_REG:
1005       DEBUGpic14_emitcode(";","%d",__LINE__);
1006         if (dname) 
1007             return aop->aopu.aop_reg[offset]->dname;
1008         else
1009             return aop->aopu.aop_reg[offset]->name;
1010         
1011     case AOP_CRY:
1012       pic14_emitcode(";","%d",__LINE__);
1013       //pic14_emitcode("clr","a");
1014       //pic14_emitcode("mov","c,%s",aop->aopu.aop_dir);
1015       //pic14_emitcode("rlc","a") ;
1016       //return (dname ? "acc" : "a");
1017       return aop->aopu.aop_dir;
1018         
1019     case AOP_ACC:
1020         DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1021         //if (!offset && dname)
1022         //    return "acc";
1023         //return aop->aopu.aop_str[offset];
1024         return "AOP_accumulator_bug";
1025
1026     case AOP_LIT:
1027         DEBUGpic14_emitcode(";","%d",__LINE__);
1028         sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1029         rs = Safe_calloc(1,strlen(s)+1);
1030         strcpy(rs,s);   
1031         return rs;
1032         
1033     case AOP_STR:
1034         DEBUGpic14_emitcode(";","%d",__LINE__);
1035         aop->coff = offset ;
1036         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1037             dname)
1038             return "acc";
1039         
1040         return aop->aopu.aop_str[offset];
1041         
1042     }
1043
1044     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1045            "aopget got unsupported aop->type");
1046     exit(0);
1047 }
1048
1049 /*-----------------------------------------------------------------*/
1050 /* popGetLabel - create a new pCodeOp of type PO_LABEL             */
1051 /*-----------------------------------------------------------------*/
1052 pCodeOp *popGetLabel(unsigned int key)
1053 {
1054
1055   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1056
1057   if(key>max_key)
1058     max_key = key;
1059
1060   return newpCodeOpLabel(key+100+labelOffset);
1061 }
1062
1063 /*-----------------------------------------------------------------*/
1064 /* popCopyReg - copy a pcode operator                              */
1065 /*-----------------------------------------------------------------*/
1066 pCodeOp *popCopyReg(pCodeOpReg *pc)
1067 {
1068   pCodeOpReg *pcor;
1069
1070   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1071   pcor->pcop.type = pc->pcop.type;
1072   if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1073     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1074   pcor->r = pc->r;
1075   pcor->rIdx = pc->rIdx;
1076
1077
1078   return PCOP(pcor);
1079 }
1080
1081 /*-----------------------------------------------------------------*/
1082 /* popCopy - copy a pcode operator                                 */
1083 /*-----------------------------------------------------------------*/
1084 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
1085 {
1086   pCodeOp *pcop;
1087
1088   pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
1089   pcop->type = PO_BIT;
1090   if(!(pcop->name = Safe_strdup(pc->name)))
1091     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1092   ((pCodeOpBit *)pcop)->bit = bitval;
1093
1094   ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
1095
1096   return pcop;
1097 }
1098
1099 /*-----------------------------------------------------------------*/
1100 /* popGet - asm operator to pcode operator conversion              */
1101 /*-----------------------------------------------------------------*/
1102 pCodeOp *popGetLit(unsigned int lit)
1103 {
1104
1105   return newpCodeOpLit(lit);
1106 }
1107
1108
1109 /*-----------------------------------------------------------------*/
1110 /* popGet - asm operator to pcode operator conversion              */
1111 /*-----------------------------------------------------------------*/
1112 pCodeOp *popGetWithString(char *str)
1113 {
1114   pCodeOp *pcop;
1115
1116
1117   if(!str) {
1118     fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1119     exit (1);
1120   }
1121
1122   pcop = newpCodeOp(str,PO_STR);
1123
1124   return pcop;
1125 }
1126
1127 pCodeOp *popRegFromString(char *str)
1128 {
1129
1130   pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1131   pcop->type = PO_GPR_REGISTER;
1132
1133   PCOR(pcop)->rIdx = -1;
1134   PCOR(pcop)->r = NULL;
1135
1136   DEBUGpic14_emitcode(";","%d",__LINE__);
1137   pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1138
1139   return pcop;
1140 }
1141
1142 pCodeOp *popRegFromIdx(int rIdx)
1143 {
1144   pCodeOp *pcop;
1145
1146   DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1147                        __FUNCTION__,__LINE__,rIdx);
1148
1149   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1150
1151   PCOR(pcop)->rIdx = rIdx;
1152   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1153   PCOR(pcop)->r->isFree = 0;
1154   PCOR(pcop)->r->wasUsed = 1;
1155
1156   pcop->type = PCOR(pcop)->r->pc_type;
1157
1158
1159   return pcop;
1160 }
1161 /*-----------------------------------------------------------------*/
1162 /* popGet - asm operator to pcode operator conversion              */
1163 /*-----------------------------------------------------------------*/
1164 pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
1165 {
1166     char *s = buffer ;
1167     char *rs;
1168
1169     pCodeOp *pcop;
1170
1171     //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1172     /* offset is greater than
1173     size then zero */
1174
1175     if (offset > (aop->size - 1) &&
1176         aop->type != AOP_LIT)
1177       return NULL;  //zero;
1178
1179     /* depending on type */
1180     switch (aop->type) {
1181         
1182     case AOP_R0:
1183     case AOP_R1:
1184     case AOP_DPTR:
1185     case AOP_DPTR2:
1186     case AOP_ACC:
1187         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1188         //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1189         //pcop->type = PO_SFR_REGISTER;
1190
1191         //PCOR(pcop)->rIdx = -1;
1192         //PCOR(pcop)->r = NULL;
1193         // Really nasty hack to check for temporary registers
1194
1195         //pcop->name = Safe_strdup("BAD_REGISTER");
1196
1197         return NULL;
1198         
1199     case AOP_IMMD:
1200       DEBUGpic14_emitcode(";","%d",__LINE__);
1201         pcop = Safe_calloc(1,sizeof(pCodeOp) );
1202         pcop->type = PO_IMMEDIATE;
1203         if (bit16) 
1204             sprintf (s,"%s",aop->aopu.aop_immd);
1205         else
1206             if (offset) 
1207                 sprintf(s,"(%s >> %d)",
1208                         aop->aopu.aop_immd,
1209                         offset*8);
1210             else
1211                 sprintf(s,"%s",
1212                         aop->aopu.aop_immd);
1213         pcop->name = Safe_calloc(1,strlen(s)+1);
1214         strcpy(pcop->name,s);   
1215         return pcop;
1216         
1217     case AOP_DIR:
1218         pcop = Safe_calloc(1,sizeof(pCodeOp) );
1219         pcop->type = PO_DIR;
1220         if (offset)
1221             sprintf(s,"(%s + %d)",
1222                     aop->aopu.aop_dir,
1223                     offset);
1224         else
1225             sprintf(s,"%s",aop->aopu.aop_dir);
1226         pcop->name = Safe_calloc(1,strlen(s)+1);
1227         strcpy(pcop->name,s);   
1228         return pcop;
1229         
1230     case AOP_REG:
1231       {
1232         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1233
1234         DEBUGpic14_emitcode(";","%d, rIdx=0x%x",__LINE__,rIdx);
1235         if(bit16)
1236           pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
1237         else
1238           pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1239         //pcop->type = PO_GPR_REGISTER;
1240         PCOR(pcop)->rIdx = rIdx;
1241         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1242         pcop->type = PCOR(pcop)->r->pc_type;
1243
1244         if (dname)
1245           rs = aop->aopu.aop_reg[offset]->dname;
1246         else 
1247           rs = aop->aopu.aop_reg[offset]->name;
1248
1249         DEBUGpic14_emitcode(";","%d  %s",__LINE__,rs);
1250
1251         return pcop;
1252       }
1253
1254     case AOP_CRY:
1255       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1256       return pcop;
1257         
1258     case AOP_LIT:
1259       DEBUGpic14_emitcode(";","%d",__LINE__);
1260       return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1261
1262     case AOP_STR:
1263       DEBUGpic14_emitcode(";","%d",__LINE__);
1264
1265       pcop = Safe_calloc(1,sizeof(pCodeOp) );
1266       pcop->type = PO_STR;
1267
1268       //aop->coff = offset ;
1269         if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
1270           sprintf(s,"%s","acc");
1271         else
1272           sprintf(s,"%s",aop->aopu.aop_str[offset]);
1273         pcop->name = Safe_calloc(1,strlen(s)+1);
1274         strcpy(pcop->name,s);   
1275         return pcop;
1276         
1277     }
1278
1279     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1280            "popGet got unsupported aop->type");
1281     exit(0);
1282 }
1283 /*-----------------------------------------------------------------*/
1284 /* aopPut - puts a string for a aop                                */
1285 /*-----------------------------------------------------------------*/
1286 void aopPut (asmop *aop, char *s, int offset)
1287 {
1288     char *d = buffer ;
1289     symbol *lbl ;
1290
1291     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1292
1293     if (aop->size && offset > ( aop->size - 1)) {
1294         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1295                "aopPut got offset > aop->size");
1296         exit(0);
1297     }
1298
1299     /* will assign value to value */
1300     /* depending on where it is ofcourse */
1301     switch (aop->type) {
1302     case AOP_DIR:
1303         if (offset)
1304             sprintf(d,"(%s + %d)",
1305                     aop->aopu.aop_dir,offset);
1306         else
1307             sprintf(d,"%s",aop->aopu.aop_dir);
1308         
1309         if (strcmp(d,s)) {
1310           DEBUGpic14_emitcode(";","%d",__LINE__);
1311           if(strcmp(s,"W"))
1312             pic14_emitcode("movf","%s,w",s);
1313           pic14_emitcode("movwf","%s",d);
1314
1315           if(strcmp(s,"W"))
1316             pic14_emitcode(";BUG! should have this:movf","%s,w   %d",s,__LINE__);
1317           emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1318
1319
1320         }
1321         break;
1322         
1323     case AOP_REG:
1324         if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
1325             strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1326           /*
1327             if (*s == '@'           ||
1328                 strcmp(s,"r0") == 0 ||
1329                 strcmp(s,"r1") == 0 ||
1330                 strcmp(s,"r2") == 0 ||
1331                 strcmp(s,"r3") == 0 ||
1332                 strcmp(s,"r4") == 0 ||
1333                 strcmp(s,"r5") == 0 ||
1334                 strcmp(s,"r6") == 0 || 
1335                 strcmp(s,"r7") == 0 )
1336                 pic14_emitcode("mov","%s,%s  ; %d",
1337                          aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1338             else
1339           */
1340
1341           if(strcmp(s,"W"))
1342             pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1343
1344           pic14_emitcode("movwf","%s",
1345                    aop->aopu.aop_reg[offset]->name);
1346
1347           if(strcmp(s,"W")) {
1348             pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1349             pcop->type = PO_GPR_REGISTER;
1350
1351             PCOR(pcop)->rIdx = -1;
1352             PCOR(pcop)->r = NULL;
1353
1354             DEBUGpic14_emitcode(";","%d",__LINE__);
1355             pcop->name = Safe_strdup(s);
1356             emitpcode(POC_MOVFW,pcop);
1357           }
1358           emitpcode(POC_MOVWF,popGet(aop,offset,FALSE,FALSE));
1359
1360         }
1361         break;
1362         
1363     case AOP_DPTR:
1364     case AOP_DPTR2:
1365     
1366     if (aop->type == AOP_DPTR2)
1367     {
1368         genSetDPTR(1);
1369     }
1370     
1371         if (aop->code) {
1372             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1373                    "aopPut writting to code space");
1374             exit(0);
1375         }
1376         
1377         while (offset > aop->coff) {
1378             aop->coff++;
1379             pic14_emitcode ("inc","dptr");
1380         }
1381         
1382         while (offset < aop->coff) {
1383             aop->coff-- ;
1384             pic14_emitcode("lcall","__decdptr");
1385         }
1386         
1387         aop->coff = offset;
1388         
1389         /* if not in accumulater */
1390         MOVA(s);        
1391         
1392         pic14_emitcode ("movx","@dptr,a");
1393         
1394     if (aop->type == AOP_DPTR2)
1395     {
1396         genSetDPTR(0);
1397     }
1398         break;
1399         
1400     case AOP_R0:
1401     case AOP_R1:
1402         while (offset > aop->coff) {
1403             aop->coff++;
1404             pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1405         }
1406         while (offset < aop->coff) {
1407             aop->coff-- ;
1408             pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1409         }
1410         aop->coff = offset;
1411         
1412         if (aop->paged) {
1413             MOVA(s);           
1414             pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1415             
1416         } else
1417             if (*s == '@') {
1418                 MOVA(s);
1419                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1420             } else
1421                 if (strcmp(s,"r0") == 0 ||
1422                     strcmp(s,"r1") == 0 ||
1423                     strcmp(s,"r2") == 0 ||
1424                     strcmp(s,"r3") == 0 ||
1425                     strcmp(s,"r4") == 0 ||
1426                     strcmp(s,"r5") == 0 ||
1427                     strcmp(s,"r6") == 0 || 
1428                     strcmp(s,"r7") == 0 ) {
1429                     char buffer[10];
1430                     sprintf(buffer,"a%s",s);
1431                     pic14_emitcode("mov","@%s,%s",
1432                              aop->aopu.aop_ptr->name,buffer);
1433                 } else
1434                     pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1435         
1436         break;
1437         
1438     case AOP_STK:
1439         if (strcmp(s,"a") == 0)
1440             pic14_emitcode("push","acc");
1441         else
1442             pic14_emitcode("push","%s",s);
1443         
1444         break;
1445         
1446     case AOP_CRY:
1447         /* if bit variable */
1448         if (!aop->aopu.aop_dir) {
1449             pic14_emitcode("clr","a");
1450             pic14_emitcode("rlc","a");
1451         } else {
1452             if (s == zero) 
1453                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1454             else
1455                 if (s == one)
1456                     pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1457                 else
1458                     if (!strcmp(s,"c"))
1459                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1460                     else {
1461                         lbl = newiTempLabel(NULL);
1462                         
1463                         if (strcmp(s,"a")) {
1464                             MOVA(s);
1465                         }
1466                         pic14_emitcode("clr","c");
1467                         pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1468                         pic14_emitcode("cpl","c");
1469                         pic14_emitcode("","%05d_DS_:",lbl->key+100);
1470                         pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1471                     }
1472         }
1473         break;
1474         
1475     case AOP_STR:
1476         aop->coff = offset;
1477         if (strcmp(aop->aopu.aop_str[offset],s))
1478             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1479         break;
1480         
1481     case AOP_ACC:
1482         aop->coff = offset;
1483         if (!offset && (strcmp(s,"acc") == 0))
1484             break;
1485         
1486         if (strcmp(aop->aopu.aop_str[offset],s))
1487             pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1488         break;
1489
1490     default :
1491         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1492                "aopPut got unsupported aop->type");
1493         exit(0);    
1494     }    
1495
1496 }
1497
1498 /*-----------------------------------------------------------------*/
1499 /* reAdjustPreg - points a register back to where it should        */
1500 /*-----------------------------------------------------------------*/
1501 static void reAdjustPreg (asmop *aop)
1502 {
1503     int size ;
1504
1505     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1506     aop->coff = 0;
1507     if ((size = aop->size) <= 1)
1508         return ;
1509     size-- ;
1510     switch (aop->type) {
1511         case AOP_R0 :
1512         case AOP_R1 :
1513             while (size--)
1514                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1515             break;          
1516         case AOP_DPTR :
1517         case AOP_DPTR2:
1518             if (aop->type == AOP_DPTR2)
1519             {
1520                 genSetDPTR(1);
1521             } 
1522             while (size--)
1523             {
1524                 pic14_emitcode("lcall","__decdptr");
1525             }
1526                 
1527             if (aop->type == AOP_DPTR2)
1528             {
1529                 genSetDPTR(0);
1530             }                
1531             break;  
1532
1533     }   
1534
1535 }
1536
1537 /*-----------------------------------------------------------------*/
1538 /* genNotFloat - generates not for float operations              */
1539 /*-----------------------------------------------------------------*/
1540 static void genNotFloat (operand *op, operand *res)
1541 {
1542     int size, offset;
1543     char *l;
1544     symbol *tlbl ;
1545
1546     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1547     /* we will put 127 in the first byte of 
1548     the result */
1549     aopPut(AOP(res),"#127",0);
1550     size = AOP_SIZE(op) - 1;
1551     offset = 1;
1552
1553     l = aopGet(op->aop,offset++,FALSE,FALSE);
1554     MOVA(l);    
1555
1556     while(size--) {
1557         pic14_emitcode("orl","a,%s",
1558                  aopGet(op->aop,
1559                         offset++,FALSE,FALSE));
1560     }
1561     tlbl = newiTempLabel(NULL);
1562
1563     tlbl = newiTempLabel(NULL);
1564     aopPut(res->aop,one,1);
1565     pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1566     aopPut(res->aop,zero,1);
1567     pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1568
1569     size = res->aop->size - 2;
1570     offset = 2;    
1571     /* put zeros in the rest */
1572     while (size--) 
1573         aopPut(res->aop,zero,offset++);
1574 }
1575
1576 #if 0
1577 /*-----------------------------------------------------------------*/
1578 /* opIsGptr: returns non-zero if the passed operand is             */   
1579 /* a generic pointer type.                                         */
1580 /*-----------------------------------------------------------------*/ 
1581 static int opIsGptr(operand *op)
1582 {
1583     sym_link *type = operandType(op);
1584     
1585     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1586     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1587     {
1588         return 1;
1589     }
1590     return 0;        
1591 }
1592 #endif
1593
1594 /*-----------------------------------------------------------------*/
1595 /* pic14_getDataSize - get the operand data size                         */
1596 /*-----------------------------------------------------------------*/
1597 int pic14_getDataSize(operand *op)
1598 {
1599     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1600
1601
1602     return AOP_SIZE(op);
1603
1604     // tsd- in the pic port, the genptr size is 1, so this code here
1605     // fails. ( in the 8051 port, the size was 4).
1606 #if 0
1607     int size;
1608     size = AOP_SIZE(op);
1609     if (size == GPTRSIZE)
1610     {
1611         sym_link *type = operandType(op);
1612         if (IS_GENPTR(type))
1613         {
1614             /* generic pointer; arithmetic operations
1615              * should ignore the high byte (pointer type).
1616              */
1617             size--;
1618     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1619         }
1620     }
1621     return size;
1622 #endif
1623 }
1624
1625 /*-----------------------------------------------------------------*/
1626 /* pic14_outAcc - output Acc                                             */
1627 /*-----------------------------------------------------------------*/
1628 void pic14_outAcc(operand *result)
1629 {
1630
1631     DEBUGpic14_emitcode ("; ***","%s  %d - Warning no code will be generated here",__FUNCTION__,__LINE__);
1632
1633 #if 0
1634     size = pic14_getDataSize(result);
1635     if(size){
1636         aopPut(AOP(result),"a",0);
1637         size--;
1638         offset = 1;
1639         /* unsigned or positive */
1640         while(size--){
1641             aopPut(AOP(result),zero,offset++);
1642         }
1643     }
1644 #endif
1645 }
1646
1647 /*-----------------------------------------------------------------*/
1648 /* pic14_outBitC - output a bit C                                        */
1649 /*-----------------------------------------------------------------*/
1650 void pic14_outBitC(operand *result)
1651 {
1652
1653     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1654     /* if the result is bit */
1655     if (AOP_TYPE(result) == AOP_CRY) 
1656         aopPut(AOP(result),"c",0);
1657     else {
1658         pic14_emitcode("clr","a  ; %d", __LINE__);
1659         pic14_emitcode("rlc","a");
1660         pic14_outAcc(result);
1661     }
1662 }
1663
1664 /*-----------------------------------------------------------------*/
1665 /* pic14_toBoolean - emit code for orl a,operator(sizeop)                */
1666 /*-----------------------------------------------------------------*/
1667 void pic14_toBoolean(operand *oper)
1668 {
1669     int size = AOP_SIZE(oper) - 1;
1670     int offset = 1;
1671
1672     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1673
1674     if ( AOP_TYPE(oper) != AOP_ACC) {
1675       emitpcode(POC_MOVFW,popGet(AOP(oper),0,FALSE,FALSE));
1676       pic14_emitcode("movf","%s,w",aopGet(AOP(oper),0,FALSE,FALSE));
1677     }
1678     while (size--) {
1679       pic14_emitcode("iorwf","%s,w",aopGet(AOP(oper),offset,FALSE,FALSE));
1680       emitpcode(POC_IORFW, popGet(AOP(oper),offset++,FALSE,FALSE));
1681     }
1682 }
1683
1684
1685 /*-----------------------------------------------------------------*/
1686 /* genNot - generate code for ! operation                          */
1687 /*-----------------------------------------------------------------*/
1688 static void genNot (iCode *ic)
1689 {
1690     symbol *tlbl;
1691     sym_link *optype = operandType(IC_LEFT(ic));
1692
1693     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1694     /* assign asmOps to operand & result */
1695     aopOp (IC_LEFT(ic),ic,FALSE);
1696     aopOp (IC_RESULT(ic),ic,TRUE);
1697
1698     /* if in bit space then a special case */
1699     if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1700       pic14_emitcode("movlw","1<<%s");
1701       //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1702       //pic14_emitcode("cpl","c"); 
1703       //pic14_outBitC(IC_RESULT(ic));
1704       goto release;
1705     }
1706
1707     /* if type float then do float */
1708     if (IS_FLOAT(optype)) {
1709         genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1710         goto release;
1711     }
1712
1713     pic14_toBoolean(IC_LEFT(ic));
1714
1715     tlbl = newiTempLabel(NULL);
1716     pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1717     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1718     pic14_outBitC(IC_RESULT(ic));
1719
1720 release:    
1721     /* release the aops */
1722     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1723     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1724 }
1725
1726
1727 /*-----------------------------------------------------------------*/
1728 /* genCpl - generate code for complement                           */
1729 /*-----------------------------------------------------------------*/
1730 static void genCpl (iCode *ic)
1731 {
1732     int offset = 0;
1733     int size ;
1734
1735
1736     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1737     /* assign asmOps to operand & result */
1738     aopOp (IC_LEFT(ic),ic,FALSE);
1739     aopOp (IC_RESULT(ic),ic,TRUE);
1740
1741     /* if both are in bit space then 
1742     a special case */
1743     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1744         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1745
1746         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1747         pic14_emitcode("cpl","c"); 
1748         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1749         goto release; 
1750     } 
1751
1752     size = AOP_SIZE(IC_RESULT(ic));
1753     while (size--) {
1754         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1755         MOVA(l);       
1756         pic14_emitcode("cpl","a");
1757         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1758     }
1759
1760
1761 release:
1762     /* release the aops */
1763     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1764     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1765 }
1766
1767 /*-----------------------------------------------------------------*/
1768 /* genUminusFloat - unary minus for floating points                */
1769 /*-----------------------------------------------------------------*/
1770 static void genUminusFloat(operand *op,operand *result)
1771 {
1772     int size ,offset =0 ;
1773     char *l;
1774
1775     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1776     /* for this we just need to flip the 
1777     first it then copy the rest in place */
1778     size = AOP_SIZE(op) - 1;
1779     l = aopGet(AOP(op),3,FALSE,FALSE);
1780
1781     MOVA(l);    
1782
1783     pic14_emitcode("cpl","acc.7");
1784     aopPut(AOP(result),"a",3);    
1785
1786     while(size--) {
1787         aopPut(AOP(result),
1788                aopGet(AOP(op),offset,FALSE,FALSE),
1789                offset);
1790         offset++;
1791     }          
1792 }
1793
1794 /*-----------------------------------------------------------------*/
1795 /* genUminus - unary minus code generation                         */
1796 /*-----------------------------------------------------------------*/
1797 static void genUminus (iCode *ic)
1798 {
1799     int offset ,size ;
1800     sym_link *optype, *rtype;
1801
1802
1803     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1804     /* assign asmops */
1805     aopOp(IC_LEFT(ic),ic,FALSE);
1806     aopOp(IC_RESULT(ic),ic,TRUE);
1807
1808     /* if both in bit space then special
1809     case */
1810     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1811         AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1812
1813         pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
1814         pic14_emitcode("cpl","c"); 
1815         pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
1816         goto release; 
1817     } 
1818
1819     optype = operandType(IC_LEFT(ic));
1820     rtype = operandType(IC_RESULT(ic));
1821
1822     /* if float then do float stuff */
1823     if (IS_FLOAT(optype)) {
1824         genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1825         goto release;
1826     }
1827
1828     /* otherwise subtract from zero */
1829     size = AOP_SIZE(IC_LEFT(ic));
1830     offset = 0 ;
1831     CLRC ;
1832     while(size--) {
1833         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1834         if (!strcmp(l,"a")) {
1835             pic14_emitcode("cpl","a");
1836             pic14_emitcode("inc","a");
1837         } else {
1838             pic14_emitcode("clr","a");
1839             pic14_emitcode("subb","a,%s",l);
1840         }       
1841         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1842     }
1843
1844     /* if any remaining bytes in the result */
1845     /* we just need to propagate the sign   */
1846     if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic))))) {
1847         pic14_emitcode("rlc","a");
1848         pic14_emitcode("subb","a,acc");
1849         while (size--) 
1850             aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1851     }       
1852
1853 release:
1854     /* release the aops */
1855     freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1856     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);    
1857 }
1858
1859 /*-----------------------------------------------------------------*/
1860 /* saveRegisters - will look for a call and save the registers     */
1861 /*-----------------------------------------------------------------*/
1862 static void saveRegisters(iCode *lic) 
1863 {
1864     int i;
1865     iCode *ic;
1866     bitVect *rsave;
1867     sym_link *dtype;
1868
1869     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1870     /* look for call */
1871     for (ic = lic ; ic ; ic = ic->next) 
1872         if (ic->op == CALL || ic->op == PCALL)
1873             break;
1874
1875     if (!ic) {
1876         fprintf(stderr,"found parameter push with no function call\n");
1877         return ;
1878     }
1879
1880     /* if the registers have been saved already then
1881     do nothing */
1882     if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1883         return ;
1884
1885     /* find the registers in use at this time 
1886     and push them away to safety */
1887     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1888                           ic->rUsed);
1889
1890     ic->regsSaved = 1;
1891     if (options.useXstack) {
1892         if (bitVectBitValue(rsave,R0_IDX))
1893             pic14_emitcode("mov","b,r0");
1894         pic14_emitcode("mov","r0,%s",spname);
1895         for (i = 0 ; i < pic14_nRegs ; i++) {
1896             if (bitVectBitValue(rsave,i)) {
1897                 if (i == R0_IDX)
1898                     pic14_emitcode("mov","a,b");
1899                 else
1900                     pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
1901                 pic14_emitcode("movx","@r0,a");
1902                 pic14_emitcode("inc","r0");
1903             }
1904         }
1905         pic14_emitcode("mov","%s,r0",spname);
1906         if (bitVectBitValue(rsave,R0_IDX))
1907             pic14_emitcode("mov","r0,b");           
1908     } else
1909         for (i = 0 ; i < pic14_nRegs ; i++) {
1910             if (bitVectBitValue(rsave,i))
1911                 pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
1912         }
1913
1914     dtype = operandType(IC_LEFT(ic));
1915     if (dtype        && 
1916         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
1917         IFFUNC_ISISR(currFunc->type) &&
1918         !ic->bankSaved) 
1919
1920         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
1921
1922 }
1923 /*-----------------------------------------------------------------*/
1924 /* unsaveRegisters - pop the pushed registers                      */
1925 /*-----------------------------------------------------------------*/
1926 static void unsaveRegisters (iCode *ic)
1927 {
1928     int i;
1929     bitVect *rsave;
1930
1931     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1932     /* find the registers in use at this time 
1933     and push them away to safety */
1934     rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1935                           ic->rUsed);
1936     
1937     if (options.useXstack) {
1938         pic14_emitcode("mov","r0,%s",spname);   
1939         for (i =  pic14_nRegs ; i >= 0 ; i--) {
1940             if (bitVectBitValue(rsave,i)) {
1941                 pic14_emitcode("dec","r0");
1942                 pic14_emitcode("movx","a,@r0");
1943                 if (i == R0_IDX)
1944                     pic14_emitcode("mov","b,a");
1945                 else
1946                     pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
1947             }       
1948
1949         }
1950         pic14_emitcode("mov","%s,r0",spname);
1951         if (bitVectBitValue(rsave,R0_IDX))
1952             pic14_emitcode("mov","r0,b");
1953     } else
1954         for (i =  pic14_nRegs ; i >= 0 ; i--) {
1955             if (bitVectBitValue(rsave,i))
1956                 pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
1957         }
1958
1959 }  
1960
1961
1962 /*-----------------------------------------------------------------*/
1963 /* pushSide -                                                      */
1964 /*-----------------------------------------------------------------*/
1965 static void pushSide(operand * oper, int size)
1966 {
1967 #if 0
1968         int offset = 0;
1969     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1970         while (size--) {
1971                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
1972                 if (AOP_TYPE(oper) != AOP_REG &&
1973                     AOP_TYPE(oper) != AOP_DIR &&
1974                     strcmp(l,"a") ) {
1975                         pic14_emitcode("mov","a,%s",l);
1976                         pic14_emitcode("push","acc");
1977                 } else
1978                         pic14_emitcode("push","%s",l);
1979         }
1980 #endif
1981 }
1982
1983 /*-----------------------------------------------------------------*/
1984 /* assignResultValue -                                             */
1985 /*-----------------------------------------------------------------*/
1986 static void assignResultValue(operand * oper)
1987 {
1988   int offset = 0;
1989   int size = AOP_SIZE(oper);
1990
1991   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1992
1993   if(!GpsuedoStkPtr) {
1994     /* The last byte in the assignment is in W */
1995     //aopPut(AOP(oper),"W",size-1);
1996     emitpcode(POC_MOVWF, popGet(AOP(oper),0,FALSE,FALSE));
1997     GpsuedoStkPtr++;
1998     if(size == 1)
1999       return;
2000     size--;
2001     offset++;
2002   }
2003
2004   while (size--) {
2005     emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2006     emitpcode(POC_MOVWF, popGet(AOP(oper),offset,FALSE,FALSE));
2007     offset++;
2008     GpsuedoStkPtr++;
2009
2010   }
2011 }
2012
2013
2014 /*-----------------------------------------------------------------*/
2015 /* genXpush - pushes onto the external stack                       */
2016 /*-----------------------------------------------------------------*/
2017 static void genXpush (iCode *ic)
2018 {
2019     asmop *aop = newAsmop(0);
2020     regs *r ;
2021     int size,offset = 0;
2022
2023     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2024     aopOp(IC_LEFT(ic),ic,FALSE);
2025     r = getFreePtr(ic,&aop,FALSE);
2026
2027     
2028     pic14_emitcode("mov","%s,_spx",r->name);
2029
2030     size = AOP_SIZE(IC_LEFT(ic));
2031     while(size--) {
2032
2033         char *l = aopGet(AOP(IC_LEFT(ic)),
2034                          offset++,FALSE,FALSE); 
2035         MOVA(l);            
2036         pic14_emitcode("movx","@%s,a",r->name); 
2037         pic14_emitcode("inc","%s",r->name);
2038
2039     }
2040
2041         
2042     pic14_emitcode("mov","_spx,%s",r->name);
2043
2044     freeAsmop(NULL,aop,ic,TRUE);
2045     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2046 }
2047
2048 /*-----------------------------------------------------------------*/
2049 /* genIpush - genrate code for pushing this gets a little complex  */
2050 /*-----------------------------------------------------------------*/
2051 static void genIpush (iCode *ic)
2052 {
2053     int size, offset = 0 ;
2054     char *l;
2055
2056
2057     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2058     /* if this is not a parm push : ie. it is spill push 
2059     and spill push is always done on the local stack */
2060     if (!ic->parmPush) {
2061
2062         /* and the item is spilt then do nothing */
2063         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2064             return ;
2065
2066         aopOp(IC_LEFT(ic),ic,FALSE);
2067         size = AOP_SIZE(IC_LEFT(ic));
2068         /* push it on the stack */
2069         while(size--) {
2070             l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2071             if (*l == '#') {
2072                 MOVA(l);
2073                 l = "acc";
2074             }
2075             pic14_emitcode("push","%s",l);
2076         }
2077         return ;        
2078     }
2079
2080     /* this is a paramter push: in this case we call
2081     the routine to find the call and save those
2082     registers that need to be saved */   
2083     saveRegisters(ic);
2084
2085     /* if use external stack then call the external
2086     stack pushing routine */
2087     if (options.useXstack) {
2088         genXpush(ic);
2089         return ;
2090     }
2091
2092     /* then do the push */
2093     aopOp(IC_LEFT(ic),ic,FALSE);
2094
2095
2096         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2097     size = AOP_SIZE(IC_LEFT(ic));
2098
2099     while (size--) {
2100         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2101         if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2102             AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2103             strcmp(l,"a") ) {
2104             pic14_emitcode("mov","a,%s",l);
2105             pic14_emitcode("push","acc");
2106         } else
2107             pic14_emitcode("push","%s",l);
2108     }       
2109
2110     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2111 }
2112
2113 /*-----------------------------------------------------------------*/
2114 /* genIpop - recover the registers: can happen only for spilling   */
2115 /*-----------------------------------------------------------------*/
2116 static void genIpop (iCode *ic)
2117 {
2118     int size,offset ;
2119
2120
2121     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2122     /* if the temp was not pushed then */
2123     if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2124         return ;
2125
2126     aopOp(IC_LEFT(ic),ic,FALSE);
2127     size = AOP_SIZE(IC_LEFT(ic));
2128     offset = (size-1);
2129     while (size--) 
2130         pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2131                                    FALSE,TRUE));
2132
2133     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2134 }
2135
2136 /*-----------------------------------------------------------------*/
2137 /* unsaverbank - restores the resgister bank from stack            */
2138 /*-----------------------------------------------------------------*/
2139 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2140 {
2141     int i;
2142     asmop *aop ;
2143     regs *r = NULL;
2144
2145     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2146     if (popPsw) {
2147         if (options.useXstack) {
2148             aop = newAsmop(0);
2149             r = getFreePtr(ic,&aop,FALSE);
2150             
2151             
2152             pic14_emitcode("mov","%s,_spx",r->name);
2153             pic14_emitcode("movx","a,@%s",r->name);
2154             pic14_emitcode("mov","psw,a");
2155             pic14_emitcode("dec","%s",r->name);
2156             
2157         }else
2158             pic14_emitcode ("pop","psw");
2159     }
2160
2161     for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2162         if (options.useXstack) {       
2163             pic14_emitcode("movx","a,@%s",r->name);
2164             //pic14_emitcode("mov","(%s+%d),a",
2165             //       regspic14[i].base,8*bank+regspic14[i].offset);
2166             pic14_emitcode("dec","%s",r->name);
2167
2168         } else 
2169           pic14_emitcode("pop",""); //"(%s+%d)",
2170         //regspic14[i].base,8*bank); //+regspic14[i].offset);
2171     }
2172
2173     if (options.useXstack) {
2174
2175         pic14_emitcode("mov","_spx,%s",r->name);
2176         freeAsmop(NULL,aop,ic,TRUE);
2177
2178     } 
2179 }
2180
2181 /*-----------------------------------------------------------------*/
2182 /* saverbank - saves an entire register bank on the stack          */
2183 /*-----------------------------------------------------------------*/
2184 static void saverbank (int bank, iCode *ic, bool pushPsw)
2185 {
2186     int i;
2187     asmop *aop ;
2188     regs *r = NULL;
2189
2190     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2191     if (options.useXstack) {
2192
2193         aop = newAsmop(0);
2194         r = getFreePtr(ic,&aop,FALSE);  
2195         pic14_emitcode("mov","%s,_spx",r->name);
2196
2197     }
2198
2199     for (i = 0 ; i < pic14_nRegs ;i++) {
2200         if (options.useXstack) {
2201             pic14_emitcode("inc","%s",r->name);
2202             //pic14_emitcode("mov","a,(%s+%d)",
2203             //         regspic14[i].base,8*bank+regspic14[i].offset);
2204             pic14_emitcode("movx","@%s,a",r->name);           
2205         } else 
2206           pic14_emitcode("push","");// "(%s+%d)",
2207                      //regspic14[i].base,8*bank+regspic14[i].offset);
2208     }
2209     
2210     if (pushPsw) {
2211         if (options.useXstack) {
2212             pic14_emitcode("mov","a,psw");
2213             pic14_emitcode("movx","@%s,a",r->name);     
2214             pic14_emitcode("inc","%s",r->name);
2215             pic14_emitcode("mov","_spx,%s",r->name);       
2216             freeAsmop (NULL,aop,ic,TRUE);
2217             
2218         } else
2219             pic14_emitcode("push","psw");
2220         
2221         pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2222     }
2223     ic->bankSaved = 1;
2224
2225 }
2226
2227 /*-----------------------------------------------------------------*/
2228 /* genCall - generates a call statement                            */
2229 /*-----------------------------------------------------------------*/
2230 static void genCall (iCode *ic)
2231 {
2232   sym_link *dtype;   
2233
2234   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2235
2236   /* if caller saves & we have not saved then */
2237   if (!ic->regsSaved)
2238     saveRegisters(ic);
2239
2240   /* if we are calling a function that is not using
2241      the same register bank then we need to save the
2242      destination registers on the stack */
2243   dtype = operandType(IC_LEFT(ic));
2244   if (dtype        && 
2245       (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2246       IFFUNC_ISISR(currFunc->type) &&
2247       !ic->bankSaved) 
2248
2249     saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2250
2251   /* if send set is not empty the assign */
2252   if (_G.sendSet) {
2253     iCode *sic;
2254     /* For the Pic port, there is no data stack.
2255      * So parameters passed to functions are stored
2256      * in registers. (The pCode optimizer will get
2257      * rid of most of these :).
2258      */
2259     int psuedoStkPtr=0; 
2260     int firstTimeThruLoop = 1;
2261
2262     for (sic = setFirstItem(_G.sendSet) ; sic ; 
2263          sic = setNextItem(_G.sendSet)) {
2264       int size, offset = 0;
2265
2266       aopOp(IC_LEFT(sic),sic,FALSE);
2267       size = AOP_SIZE(IC_LEFT(sic));
2268
2269
2270       while (size--) {
2271         char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2272                          FALSE,FALSE);
2273         DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2274                              AopType(AOP_TYPE(IC_LEFT(sic))));
2275
2276         if(!firstTimeThruLoop) {
2277           /* If is not the first time we've been through the loop
2278            * then we need to save the parameter in a temporary
2279            * register. The last byte of the last parameter is
2280            * passed in W. */
2281           pic14_emitcode("movwf","%s",fReturn[offset]);
2282           emitpcode(POC_MOVWF,popRegFromIdx(psuedoStkPtr + Gstack_base_addr));
2283           psuedoStkPtr++;
2284           DEBUGpic14_emitcode ("; ","%d save param in %d",__LINE__,
2285                                psuedoStkPtr+Gstack_base_addr);
2286         }
2287         firstTimeThruLoop=0;
2288
2289         if (strcmp(l,fReturn[offset])) {
2290
2291           if ( ((AOP(IC_LEFT(sic))->type) == AOP_IMMD) ||
2292                ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2293             emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2294           //pic14_emitcode("movlw","%s",l);
2295           else
2296             emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),size,FALSE,FALSE));
2297           //pic14_emitcode("movf","%s,w",l);
2298
2299           /* The last one is passed in W but all others are passed on 
2300              the psuedo stack */
2301           /*
2302           if(size) {
2303             pic14_emitcode("movwf","%s",fReturn[offset]);
2304             emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2305           }
2306           */
2307         }
2308         offset++;
2309       }
2310       freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2311     }
2312     _G.sendSet = NULL;
2313   }
2314   /* make the call */
2315   emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2316                                       OP_SYMBOL(IC_LEFT(ic))->rname :
2317                                       OP_SYMBOL(IC_LEFT(ic))->name));
2318
2319   GpsuedoStkPtr=0;
2320   /* if we need assign a result value */
2321   if ((IS_ITEMP(IC_RESULT(ic)) && 
2322        (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2323         OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2324       IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2325
2326     _G.accInUse++;
2327     aopOp(IC_RESULT(ic),ic,FALSE);
2328     _G.accInUse--;
2329
2330     assignResultValue(IC_RESULT(ic));
2331
2332     DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2333                          AopType(AOP_TYPE(IC_RESULT(ic))));
2334                 
2335     freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2336   }
2337
2338   /* adjust the stack for parameters if 
2339      required */
2340   if (ic->parmBytes) {
2341     int i;
2342     if (ic->parmBytes > 3) {
2343       pic14_emitcode("mov","a,%s",spname);
2344       pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2345       pic14_emitcode("mov","%s,a",spname);
2346     } else 
2347       for ( i = 0 ; i <  ic->parmBytes ;i++)
2348         pic14_emitcode("dec","%s",spname);
2349
2350   }
2351
2352   /* if register bank was saved then pop them */
2353   if (ic->bankSaved)
2354     unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2355
2356   /* if we hade saved some registers then unsave them */
2357   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2358     unsaveRegisters (ic);
2359
2360
2361 }
2362
2363 /*-----------------------------------------------------------------*/
2364 /* genPcall - generates a call by pointer statement                */
2365 /*-----------------------------------------------------------------*/
2366 static void genPcall (iCode *ic)
2367 {
2368     sym_link *dtype;
2369     symbol *rlbl = newiTempLabel(NULL);
2370
2371
2372     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2373     /* if caller saves & we have not saved then */
2374     if (!ic->regsSaved)
2375         saveRegisters(ic);
2376
2377     /* if we are calling a function that is not using
2378     the same register bank then we need to save the
2379     destination registers on the stack */
2380     dtype = operandType(IC_LEFT(ic));
2381     if (dtype        && 
2382         IFFUNC_ISISR(currFunc->type) &&
2383         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2384         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2385
2386
2387     /* push the return address on to the stack */
2388     pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2389     pic14_emitcode("push","acc");    
2390     pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2391     pic14_emitcode("push","acc");
2392     
2393     if (options.model == MODEL_FLAT24)
2394     {
2395         pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2396         pic14_emitcode("push","acc");    
2397     }
2398
2399     /* now push the calling address */
2400     aopOp(IC_LEFT(ic),ic,FALSE);
2401
2402     pushSide(IC_LEFT(ic), FPTRSIZE);
2403
2404     freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2405
2406     /* if send set is not empty the assign */
2407     if (_G.sendSet) {
2408         iCode *sic ;
2409
2410         for (sic = setFirstItem(_G.sendSet) ; sic ; 
2411              sic = setNextItem(_G.sendSet)) {
2412             int size, offset = 0;
2413             aopOp(IC_LEFT(sic),sic,FALSE);
2414             size = AOP_SIZE(IC_LEFT(sic));
2415             while (size--) {
2416                 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2417                                 FALSE,FALSE);
2418                 if (strcmp(l,fReturn[offset]))
2419                     pic14_emitcode("mov","%s,%s",
2420                              fReturn[offset],
2421                              l);
2422                 offset++;
2423             }
2424             freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2425         }
2426         _G.sendSet = NULL;
2427     }
2428
2429     pic14_emitcode("ret","");
2430     pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2431
2432
2433     /* if we need assign a result value */
2434     if ((IS_ITEMP(IC_RESULT(ic)) &&
2435          (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2436           OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2437         IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2438
2439         _G.accInUse++;
2440         aopOp(IC_RESULT(ic),ic,FALSE);
2441         _G.accInUse--;
2442         
2443         assignResultValue(IC_RESULT(ic));
2444
2445         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2446     }
2447
2448     /* adjust the stack for parameters if 
2449     required */
2450     if (ic->parmBytes) {
2451         int i;
2452         if (ic->parmBytes > 3) {
2453             pic14_emitcode("mov","a,%s",spname);
2454             pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2455             pic14_emitcode("mov","%s,a",spname);
2456         } else 
2457             for ( i = 0 ; i <  ic->parmBytes ;i++)
2458                 pic14_emitcode("dec","%s",spname);
2459
2460     }
2461
2462     /* if register bank was saved then unsave them */
2463     if (dtype        && 
2464         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2465         unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2466
2467     /* if we hade saved some registers then
2468     unsave them */
2469     if (ic->regsSaved)
2470         unsaveRegisters (ic);
2471
2472 }
2473
2474 /*-----------------------------------------------------------------*/
2475 /* resultRemat - result  is rematerializable                       */
2476 /*-----------------------------------------------------------------*/
2477 static int resultRemat (iCode *ic)
2478 {
2479     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2480     if (SKIP_IC(ic) || ic->op == IFX)
2481         return 0;
2482
2483     if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2484         symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2485         if (sym->remat && !POINTER_SET(ic)) 
2486             return 1;
2487     }
2488
2489     return 0;
2490 }
2491
2492 #if defined(__BORLANDC__) || defined(_MSC_VER)
2493 #define STRCASECMP stricmp
2494 #else
2495 #define STRCASECMP strcasecmp
2496 #endif
2497
2498 /*-----------------------------------------------------------------*/
2499 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2500 /*-----------------------------------------------------------------*/
2501 static bool inExcludeList(char *s)
2502 {
2503     int i =0;
2504     
2505     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2506     if (options.excludeRegs[i] &&
2507     STRCASECMP(options.excludeRegs[i],"none") == 0)
2508         return FALSE ;
2509
2510     for ( i = 0 ; options.excludeRegs[i]; i++) {
2511         if (options.excludeRegs[i] &&
2512         STRCASECMP(s,options.excludeRegs[i]) == 0)
2513             return TRUE;
2514     }
2515     return FALSE ;
2516 }
2517
2518 /*-----------------------------------------------------------------*/
2519 /* genFunction - generated code for function entry                 */
2520 /*-----------------------------------------------------------------*/
2521 static void genFunction (iCode *ic)
2522 {
2523     symbol *sym;
2524     sym_link *ftype;
2525
2526     DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2527
2528     labelOffset += (max_key+4);
2529     max_key=0;
2530     GpsuedoStkPtr=0;
2531     _G.nRegsSaved = 0;
2532     /* create the function header */
2533     pic14_emitcode(";","-----------------------------------------");
2534     pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2535     pic14_emitcode(";","-----------------------------------------");
2536
2537     pic14_emitcode("","%s:",sym->rname);
2538     addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2539
2540     ftype = operandType(IC_LEFT(ic));
2541
2542     /* if critical function then turn interrupts off */
2543     if (IFFUNC_ISCRITICAL(ftype))
2544         pic14_emitcode("clr","ea");
2545
2546     /* here we need to generate the equates for the
2547        register bank if required */
2548 #if 0
2549     if (FUNC_REGBANK(ftype) != rbank) {
2550         int i ;
2551
2552         rbank = FUNC_REGBANK(ftype);
2553         for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2554             if (strcmp(regspic14[i].base,"0") == 0)
2555                 pic14_emitcode("","%s = 0x%02x",
2556                          regspic14[i].dname,
2557                          8*rbank+regspic14[i].offset);
2558             else
2559                 pic14_emitcode ("","%s = %s + 0x%02x",
2560                           regspic14[i].dname,
2561                           regspic14[i].base,
2562                           8*rbank+regspic14[i].offset);
2563         }
2564     }
2565 #endif
2566
2567     /* if this is an interrupt service routine then
2568     save acc, b, dpl, dph  */
2569     if (IFFUNC_ISISR(sym->type)) {
2570         
2571         if (!inExcludeList("acc"))          
2572             pic14_emitcode ("push","acc");      
2573         if (!inExcludeList("b"))
2574             pic14_emitcode ("push","b");
2575         if (!inExcludeList("dpl"))
2576             pic14_emitcode ("push","dpl");
2577         if (!inExcludeList("dph"))
2578             pic14_emitcode ("push","dph");
2579         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2580         {
2581             pic14_emitcode ("push", "dpx");
2582             /* Make sure we're using standard DPTR */
2583             pic14_emitcode ("push", "dps");
2584             pic14_emitcode ("mov", "dps, #0x00");
2585             if (options.stack10bit)
2586             {   
2587                 /* This ISR could conceivably use DPTR2. Better save it. */
2588                 pic14_emitcode ("push", "dpl1");
2589                 pic14_emitcode ("push", "dph1");
2590                 pic14_emitcode ("push", "dpx1");
2591             }
2592         }
2593         /* if this isr has no bank i.e. is going to
2594            run with bank 0 , then we need to save more
2595            registers :-) */
2596         if (!FUNC_REGBANK(sym->type)) {
2597
2598             /* if this function does not call any other
2599                function then we can be economical and
2600                save only those registers that are used */
2601             if (! IFFUNC_HASFCALL(sym->type)) {
2602                 int i;
2603
2604                 /* if any registers used */
2605                 if (sym->regsUsed) {
2606                     /* save the registers used */
2607                     for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2608                         if (bitVectBitValue(sym->regsUsed,i) ||
2609                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2610                             pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);                         
2611                     }
2612                 }
2613                 
2614             } else {
2615                 /* this function has  a function call cannot
2616                    determines register usage so we will have the
2617                    entire bank */
2618                 saverbank(0,ic,FALSE);
2619             }       
2620         }
2621     } else {
2622         /* if callee-save to be used for this function
2623            then save the registers being used in this function */
2624         if (IFFUNC_CALLEESAVES(sym->type)) {
2625             int i;
2626             
2627             /* if any registers used */
2628             if (sym->regsUsed) {
2629                 /* save the registers used */
2630                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2631                     if (bitVectBitValue(sym->regsUsed,i) ||
2632                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2633                         pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2634                         _G.nRegsSaved++;
2635                     }
2636                 }
2637             }
2638         }
2639     }
2640
2641     /* set the register bank to the desired value */
2642     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2643         pic14_emitcode("push","psw");
2644         pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
2645     }
2646
2647     if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2648
2649         if (options.useXstack) {
2650             pic14_emitcode("mov","r0,%s",spname);
2651             pic14_emitcode("mov","a,_bp");
2652             pic14_emitcode("movx","@r0,a");
2653             pic14_emitcode("inc","%s",spname);
2654         }
2655         else
2656         {
2657             /* set up the stack */
2658             pic14_emitcode ("push","_bp");     /* save the callers stack  */
2659         }
2660         pic14_emitcode ("mov","_bp,%s",spname);
2661     }
2662
2663     /* adjust the stack for the function */
2664     if (sym->stack) {
2665
2666         int i = sym->stack;
2667         if (i > 256 ) 
2668             werror(W_STACK_OVERFLOW,sym->name);
2669
2670         if (i > 3 && sym->recvSize < 4) {              
2671
2672             pic14_emitcode ("mov","a,sp");
2673             pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2674             pic14_emitcode ("mov","sp,a");
2675            
2676         }
2677         else
2678             while(i--)
2679                 pic14_emitcode("inc","sp");
2680     }
2681
2682      if (sym->xstack) {
2683
2684         pic14_emitcode ("mov","a,_spx");
2685         pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2686         pic14_emitcode ("mov","_spx,a");
2687     }    
2688
2689 }
2690
2691 /*-----------------------------------------------------------------*/
2692 /* genEndFunction - generates epilogue for functions               */
2693 /*-----------------------------------------------------------------*/
2694 static void genEndFunction (iCode *ic)
2695 {
2696     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2697
2698     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2699
2700     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2701     {
2702         pic14_emitcode ("mov","%s,_bp",spname);
2703     }
2704
2705     /* if use external stack but some variables were
2706     added to the local stack then decrement the
2707     local stack */
2708     if (options.useXstack && sym->stack) {      
2709         pic14_emitcode("mov","a,sp");
2710         pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2711         pic14_emitcode("mov","sp,a");
2712     }
2713
2714
2715     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2716         if (options.useXstack) {
2717             pic14_emitcode("mov","r0,%s",spname);
2718             pic14_emitcode("movx","a,@r0");
2719             pic14_emitcode("mov","_bp,a");
2720             pic14_emitcode("dec","%s",spname);
2721         }
2722         else
2723         {
2724             pic14_emitcode ("pop","_bp");
2725         }
2726     }
2727
2728     /* restore the register bank  */    
2729     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2730         pic14_emitcode ("pop","psw");
2731
2732     if (IFFUNC_ISISR(sym->type)) {
2733
2734         /* now we need to restore the registers */
2735         /* if this isr has no bank i.e. is going to
2736            run with bank 0 , then we need to save more
2737            registers :-) */
2738         if (!FUNC_REGBANK(sym->type)) {
2739             
2740             /* if this function does not call any other
2741                function then we can be economical and
2742                save only those registers that are used */
2743             if (! IFFUNC_HASFCALL(sym->type)) {
2744                 int i;
2745                 
2746                 /* if any registers used */
2747                 if (sym->regsUsed) {
2748                     /* save the registers used */
2749                     for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2750                         if (bitVectBitValue(sym->regsUsed,i) ||
2751                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2752                             pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2753                     }
2754                 }
2755                 
2756             } else {
2757                 /* this function has  a function call cannot
2758                    determines register usage so we will have the
2759                    entire bank */
2760                 unsaverbank(0,ic,FALSE);
2761             }       
2762         }
2763
2764         if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2765         {
2766             if (options.stack10bit)
2767             {
2768                 pic14_emitcode ("pop", "dpx1");
2769                 pic14_emitcode ("pop", "dph1");
2770                 pic14_emitcode ("pop", "dpl1");
2771             }   
2772             pic14_emitcode ("pop", "dps");
2773             pic14_emitcode ("pop", "dpx");
2774         }
2775         if (!inExcludeList("dph"))
2776             pic14_emitcode ("pop","dph");
2777         if (!inExcludeList("dpl"))
2778             pic14_emitcode ("pop","dpl");
2779         if (!inExcludeList("b"))
2780             pic14_emitcode ("pop","b");
2781         if (!inExcludeList("acc"))
2782             pic14_emitcode ("pop","acc");
2783
2784         if (IFFUNC_ISCRITICAL(sym->type))
2785             pic14_emitcode("setb","ea");
2786
2787         /* if debug then send end of function */
2788 /*      if (options.debug && currFunc) { */
2789         if (currFunc) {
2790             _G.debugLine = 1;
2791             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2792                      FileBaseName(ic->filename),currFunc->lastLine,
2793                      ic->level,ic->block); 
2794             if (IS_STATIC(currFunc->etype))         
2795                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2796             else
2797                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2798             _G.debugLine = 0;
2799         }
2800         
2801         pic14_emitcode ("reti","");
2802     }
2803     else {
2804         if (IFFUNC_ISCRITICAL(sym->type))
2805             pic14_emitcode("setb","ea");
2806         
2807         if (IFFUNC_CALLEESAVES(sym->type)) {
2808             int i;
2809             
2810             /* if any registers used */
2811             if (sym->regsUsed) {
2812                 /* save the registers used */
2813                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2814                     if (bitVectBitValue(sym->regsUsed,i) ||
2815                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2816                         pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2817                 }
2818             }
2819             
2820         }
2821
2822         /* if debug then send end of function */
2823         if (currFunc) {
2824             _G.debugLine = 1;
2825             pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2826                      FileBaseName(ic->filename),currFunc->lastLine,
2827                      ic->level,ic->block); 
2828             if (IS_STATIC(currFunc->etype))         
2829                 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
2830             else
2831                 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2832             _G.debugLine = 0;
2833         }
2834
2835         pic14_emitcode ("return","");
2836         emitpcodeNULLop(POC_RETURN);
2837
2838         /* Mark the end of a function */
2839         addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2840     }
2841
2842 }
2843
2844 /*-----------------------------------------------------------------*/
2845 /* genRet - generate code for return statement                     */
2846 /*-----------------------------------------------------------------*/
2847 static void genRet (iCode *ic)
2848 {
2849   int size,offset = 0 , pushed = 0;
2850     
2851   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2852   /* if we have no return value then
2853      just generate the "ret" */
2854   if (!IC_LEFT(ic)) 
2855     goto jumpret;       
2856     
2857   /* we have something to return then
2858      move the return value into place */
2859   aopOp(IC_LEFT(ic),ic,FALSE);
2860   size = AOP_SIZE(IC_LEFT(ic));
2861     
2862   while (size--) {
2863     char *l ;
2864     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2865       /* #NOCHANGE */
2866       l = aopGet(AOP(IC_LEFT(ic)),offset++,
2867                  FALSE,TRUE);
2868       pic14_emitcode("push","%s",l);
2869       pushed++;
2870     } else {
2871       l = aopGet(AOP(IC_LEFT(ic)),offset,
2872                  FALSE,FALSE);
2873       if (strcmp(fReturn[offset],l)) {
2874         if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2875             ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2876           emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
2877           pic14_emitcode("movlw","%s",l);
2878         }else {
2879           emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE));
2880           pic14_emitcode("movf","%s,w",l);
2881         }
2882         if(size) {
2883           emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2884           pic14_emitcode("movwf","%s",fReturn[offset]);
2885         }
2886         offset++;
2887       }
2888     }
2889   }    
2890
2891   if (pushed) {
2892     while(pushed) {
2893       pushed--;
2894       if (strcmp(fReturn[pushed],"a"))
2895         pic14_emitcode("pop",fReturn[pushed]);
2896       else
2897         pic14_emitcode("pop","acc");
2898     }
2899   }
2900   freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2901     
2902  jumpret:
2903   /* generate a jump to the return label
2904      if the next is not the return statement */
2905   if (!(ic->next && ic->next->op == LABEL &&
2906         IC_LABEL(ic->next) == returnLabel)) {
2907         
2908     emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2909     pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2910   }
2911     
2912 }
2913
2914 /*-----------------------------------------------------------------*/
2915 /* genLabel - generates a label                                    */
2916 /*-----------------------------------------------------------------*/
2917 static void genLabel (iCode *ic)
2918 {
2919     /* special case never generate */
2920     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2921     if (IC_LABEL(ic) == entryLabel)
2922         return ;
2923
2924     emitpLabel(IC_LABEL(ic)->key);
2925     pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
2926 }
2927
2928 /*-----------------------------------------------------------------*/
2929 /* genGoto - generates a goto                                      */
2930 /*-----------------------------------------------------------------*/
2931 //tsd
2932 static void genGoto (iCode *ic)
2933 {
2934   emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
2935   pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
2936 }
2937
2938 /*-----------------------------------------------------------------*/
2939 /* findLabelBackwards: walks back through the iCode chain looking  */
2940 /* for the given label. Returns number of iCode instructions       */
2941 /* between that label and given ic.                                */
2942 /* Returns zero if label not found.                                */
2943 /*-----------------------------------------------------------------*/
2944 #if 0
2945 static int findLabelBackwards(iCode *ic, int key)
2946 {
2947     int count = 0;
2948     
2949     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2950     while (ic->prev)
2951     {
2952         ic = ic->prev;
2953         count++;
2954         
2955         if (ic->op == LABEL && IC_LABEL(ic)->key == key)
2956         {
2957             /* printf("findLabelBackwards = %d\n", count); */
2958             return count;
2959         }
2960     }
2961     
2962     return 0;
2963 }
2964 #endif
2965
2966 /*-----------------------------------------------------------------*/
2967 /* genMultbits :- multiplication of bits                           */
2968 /*-----------------------------------------------------------------*/
2969 static void genMultbits (operand *left, 
2970                          operand *right, 
2971                          operand *result)
2972 {
2973     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2974
2975     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
2976     pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
2977     pic14_outBitC(result);
2978 }
2979
2980
2981 /*-----------------------------------------------------------------*/
2982 /* genMultOneByte : 8 bit multiplication & division                */
2983 /*-----------------------------------------------------------------*/
2984 static void genMultOneByte (operand *left,
2985                             operand *right,
2986                             operand *result)
2987 {
2988     sym_link *opetype = operandType(result);
2989     char *l ;
2990     symbol *lbl ;
2991     int size,offset;
2992
2993     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2994     /* (if two literals, the value is computed before) */
2995     /* if one literal, literal on the right */
2996     if (AOP_TYPE(left) == AOP_LIT){
2997         operand *t = right;
2998         right = left;
2999         left = t;
3000     }
3001
3002     size = AOP_SIZE(result);
3003     /* signed or unsigned */
3004     pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3005     l = aopGet(AOP(left),0,FALSE,FALSE);
3006     MOVA(l);       
3007     pic14_emitcode("mul","ab");
3008     /* if result size = 1, mul signed = mul unsigned */
3009     aopPut(AOP(result),"a",0);
3010     if (size > 1){
3011         if (SPEC_USIGN(opetype)){
3012             aopPut(AOP(result),"b",1);
3013             if (size > 2)
3014                 /* for filling the MSBs */
3015                 pic14_emitcode("clr","a");
3016         }
3017         else{
3018             pic14_emitcode("mov","a,b");
3019
3020             /* adjust the MSB if left or right neg */
3021
3022             /* if one literal */
3023             if (AOP_TYPE(right) == AOP_LIT){
3024                 /* AND literal negative */
3025                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3026                     /* adjust MSB (c==0 after mul) */
3027                     pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3028                 }
3029             }
3030             else{
3031                 lbl = newiTempLabel(NULL);
3032                 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3033                 pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
3034                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3035                 pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3036                 lbl = newiTempLabel(NULL);      
3037                 pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
3038                 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3039                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3040             }
3041
3042             lbl = newiTempLabel(NULL);
3043             pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
3044             pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
3045             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3046             pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
3047             lbl = newiTempLabel(NULL);      
3048             pic14_emitcode("jc","%05d_DS_",(lbl->key+100));          
3049             pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
3050             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3051
3052             aopPut(AOP(result),"a",1);
3053             if(size > 2){
3054                 /* get the sign */
3055                 pic14_emitcode("rlc","a");
3056                 pic14_emitcode("subb","a,acc");
3057             }
3058         }
3059         size -= 2;   
3060         offset = 2;
3061         if (size > 0)
3062             while (size--)
3063                 aopPut(AOP(result),"a",offset++);
3064     }
3065 }
3066
3067 /*-----------------------------------------------------------------*/
3068 /* genMult - generates code for multiplication                     */
3069 /*-----------------------------------------------------------------*/
3070 static void genMult (iCode *ic)
3071 {
3072     operand *left = IC_LEFT(ic);
3073     operand *right = IC_RIGHT(ic);
3074     operand *result= IC_RESULT(ic);   
3075
3076     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3077     /* assign the amsops */
3078     aopOp (left,ic,FALSE);
3079     aopOp (right,ic,FALSE);
3080     aopOp (result,ic,TRUE);
3081
3082     /* special cases first */
3083     /* both are bits */
3084     if (AOP_TYPE(left) == AOP_CRY &&
3085         AOP_TYPE(right)== AOP_CRY) {
3086         genMultbits(left,right,result);
3087         goto release ;
3088     }
3089
3090     /* if both are of size == 1 */
3091     if (AOP_SIZE(left) == 1 &&
3092         AOP_SIZE(right) == 1 ) {
3093         genMultOneByte(left,right,result);
3094         goto release ;
3095     }
3096
3097     /* should have been converted to function call */       
3098     assert(0) ;
3099
3100 release :
3101     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3102     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3103     freeAsmop(result,NULL,ic,TRUE); 
3104 }
3105
3106 /*-----------------------------------------------------------------*/
3107 /* genDivbits :- division of bits                                  */
3108 /*-----------------------------------------------------------------*/
3109 static void genDivbits (operand *left, 
3110                         operand *right, 
3111                         operand *result)
3112 {
3113
3114     char *l;
3115
3116     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3117     /* the result must be bit */    
3118     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3119     l = aopGet(AOP(left),0,FALSE,FALSE);
3120
3121     MOVA(l);    
3122
3123     pic14_emitcode("div","ab");
3124     pic14_emitcode("rrc","a");
3125     aopPut(AOP(result),"c",0);
3126 }
3127
3128 /*-----------------------------------------------------------------*/
3129 /* genDivOneByte : 8 bit division                                  */
3130 /*-----------------------------------------------------------------*/
3131 static void genDivOneByte (operand *left,
3132                            operand *right,
3133                            operand *result)
3134 {
3135     sym_link *opetype = operandType(result);
3136     char *l ;
3137     symbol *lbl ;
3138     int size,offset;
3139
3140     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3141     size = AOP_SIZE(result) - 1;
3142     offset = 1;
3143     /* signed or unsigned */
3144     if (SPEC_USIGN(opetype)) {
3145         /* unsigned is easy */
3146         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3147         l = aopGet(AOP(left),0,FALSE,FALSE);
3148         MOVA(l);        
3149         pic14_emitcode("div","ab");
3150         aopPut(AOP(result),"a",0);
3151         while (size--)
3152             aopPut(AOP(result),zero,offset++);
3153         return ;
3154     }
3155
3156     /* signed is a little bit more difficult */
3157
3158     /* save the signs of the operands */
3159     l = aopGet(AOP(left),0,FALSE,FALSE);    
3160     MOVA(l);    
3161     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3162     pic14_emitcode("push","acc"); /* save it on the stack */
3163
3164     /* now sign adjust for both left & right */
3165     l =  aopGet(AOP(right),0,FALSE,FALSE);    
3166     MOVA(l);       
3167     lbl = newiTempLabel(NULL);
3168     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3169     pic14_emitcode("cpl","a");   
3170     pic14_emitcode("inc","a");
3171     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3172     pic14_emitcode("mov","b,a");
3173
3174     /* sign adjust left side */
3175     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3176     MOVA(l);
3177
3178     lbl = newiTempLabel(NULL);
3179     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3180     pic14_emitcode("cpl","a");
3181     pic14_emitcode("inc","a");
3182     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3183
3184     /* now the division */
3185     pic14_emitcode("div","ab");
3186     /* we are interested in the lower order
3187     only */
3188     pic14_emitcode("mov","b,a");
3189     lbl = newiTempLabel(NULL);
3190     pic14_emitcode("pop","acc");   
3191     /* if there was an over flow we don't 
3192     adjust the sign of the result */
3193     pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3194     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3195     CLRC;
3196     pic14_emitcode("clr","a");
3197     pic14_emitcode("subb","a,b");
3198     pic14_emitcode("mov","b,a");
3199     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3200
3201     /* now we are done */
3202     aopPut(AOP(result),"b",0);
3203     if(size > 0){
3204         pic14_emitcode("mov","c,b.7");
3205         pic14_emitcode("subb","a,acc");   
3206     }
3207     while (size--)
3208         aopPut(AOP(result),"a",offset++);
3209
3210 }
3211
3212 /*-----------------------------------------------------------------*/
3213 /* genDiv - generates code for division                            */
3214 /*-----------------------------------------------------------------*/
3215 static void genDiv (iCode *ic)
3216 {
3217     operand *left = IC_LEFT(ic);
3218     operand *right = IC_RIGHT(ic);
3219     operand *result= IC_RESULT(ic);   
3220
3221     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3222     /* assign the amsops */
3223     aopOp (left,ic,FALSE);
3224     aopOp (right,ic,FALSE);
3225     aopOp (result,ic,TRUE);
3226
3227     /* special cases first */
3228     /* both are bits */
3229     if (AOP_TYPE(left) == AOP_CRY &&
3230         AOP_TYPE(right)== AOP_CRY) {
3231         genDivbits(left,right,result);
3232         goto release ;
3233     }
3234
3235     /* if both are of size == 1 */
3236     if (AOP_SIZE(left) == 1 &&
3237         AOP_SIZE(right) == 1 ) {
3238         genDivOneByte(left,right,result);
3239         goto release ;
3240     }
3241
3242     /* should have been converted to function call */
3243     assert(0);
3244 release :
3245     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3246     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3247     freeAsmop(result,NULL,ic,TRUE); 
3248 }
3249
3250 /*-----------------------------------------------------------------*/
3251 /* genModbits :- modulus of bits                                   */
3252 /*-----------------------------------------------------------------*/
3253 static void genModbits (operand *left, 
3254                         operand *right, 
3255                         operand *result)
3256 {
3257
3258     char *l;
3259
3260     /* the result must be bit */    
3261     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3262     l = aopGet(AOP(left),0,FALSE,FALSE);
3263
3264     MOVA(l);       
3265
3266     pic14_emitcode("div","ab");
3267     pic14_emitcode("mov","a,b");
3268     pic14_emitcode("rrc","a");
3269     aopPut(AOP(result),"c",0);
3270 }
3271
3272 /*-----------------------------------------------------------------*/
3273 /* genModOneByte : 8 bit modulus                                   */
3274 /*-----------------------------------------------------------------*/
3275 static void genModOneByte (operand *left,
3276                            operand *right,
3277                            operand *result)
3278 {
3279     sym_link *opetype = operandType(result);
3280     char *l ;
3281     symbol *lbl ;
3282
3283     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3284     /* signed or unsigned */
3285     if (SPEC_USIGN(opetype)) {
3286         /* unsigned is easy */
3287         pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3288         l = aopGet(AOP(left),0,FALSE,FALSE);
3289         MOVA(l);    
3290         pic14_emitcode("div","ab");
3291         aopPut(AOP(result),"b",0);
3292         return ;
3293     }
3294
3295     /* signed is a little bit more difficult */
3296
3297     /* save the signs of the operands */
3298     l = aopGet(AOP(left),0,FALSE,FALSE);    
3299     MOVA(l);
3300
3301     pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
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
3308     lbl = newiTempLabel(NULL);
3309     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3310     pic14_emitcode("cpl","a");   
3311     pic14_emitcode("inc","a");
3312     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3313     pic14_emitcode("mov","b,a"); 
3314
3315     /* sign adjust left side */
3316     l =  aopGet(AOP(left),0,FALSE,FALSE);    
3317     MOVA(l);
3318
3319     lbl = newiTempLabel(NULL);
3320     pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3321     pic14_emitcode("cpl","a");   
3322     pic14_emitcode("inc","a");
3323     pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3324
3325     /* now the multiplication */
3326     pic14_emitcode("div","ab");
3327     /* we are interested in the lower order
3328     only */
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
3344 }
3345
3346 /*-----------------------------------------------------------------*/
3347 /* genMod - generates code for division                            */
3348 /*-----------------------------------------------------------------*/
3349 static void genMod (iCode *ic)
3350 {
3351     operand *left = IC_LEFT(ic);
3352     operand *right = IC_RIGHT(ic);
3353     operand *result= IC_RESULT(ic);  
3354
3355     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3356     /* assign the amsops */
3357     aopOp (left,ic,FALSE);
3358     aopOp (right,ic,FALSE);
3359     aopOp (result,ic,TRUE);
3360
3361     /* special cases first */
3362     /* both are bits */
3363     if (AOP_TYPE(left) == AOP_CRY &&
3364         AOP_TYPE(right)== AOP_CRY) {
3365         genModbits(left,right,result);
3366         goto release ;
3367     }
3368
3369     /* if both are of size == 1 */
3370     if (AOP_SIZE(left) == 1 &&
3371         AOP_SIZE(right) == 1 ) {
3372         genModOneByte(left,right,result);
3373         goto release ;
3374     }
3375
3376     /* should have been converted to function call */
3377     assert(0);
3378
3379 release :
3380     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3381     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3382     freeAsmop(result,NULL,ic,TRUE); 
3383 }
3384
3385 /*-----------------------------------------------------------------*/
3386 /* genIfxJump :- will create a jump depending on the ifx           */
3387 /*-----------------------------------------------------------------*/
3388 /*
3389   note: May need to add parameter to indicate when a variable is in bit space.
3390 */
3391 static void genIfxJump (iCode *ic, char *jval)
3392 {
3393
3394     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3395     /* if true label then we jump if condition
3396     supplied is true */
3397     if ( IC_TRUE(ic) ) {
3398
3399         if(strcmp(jval,"a") == 0)
3400           emitSKPZ;
3401         else if (strcmp(jval,"c") == 0)
3402           emitSKPC;
3403         else {
3404           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3405           emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
3406         }
3407
3408         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3409         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3410
3411     }
3412     else {
3413         /* false label is present */
3414         if(strcmp(jval,"a") == 0)
3415           emitSKPNZ;
3416         else if (strcmp(jval,"c") == 0)
3417           emitSKPNC;
3418         else {
3419           DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
3420           emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
3421         }
3422
3423         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3424         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3425
3426     }
3427
3428
3429     /* mark the icode as generated */
3430     ic->generated = 1;
3431 }
3432
3433 /*-----------------------------------------------------------------*/
3434 /* genSkip                                                         */
3435 /*-----------------------------------------------------------------*/
3436 static void genSkip(iCode *ifx,int status_bit)
3437 {
3438   if(!ifx)
3439     return;
3440
3441   if ( IC_TRUE(ifx) ) {
3442     switch(status_bit) {
3443     case 'z':
3444       emitSKPNZ;
3445       break;
3446
3447     case 'c':
3448       emitSKPNC;
3449       break;
3450
3451     case 'd':
3452       emitSKPDC;
3453       break;
3454
3455     }
3456
3457     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3458     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3459
3460   } else {
3461
3462     switch(status_bit) {
3463
3464     case 'z':
3465       emitSKPZ;
3466       break;
3467
3468     case 'c':
3469       emitSKPC;
3470       break;
3471
3472     case 'd':
3473       emitSKPDC;
3474       break;
3475     }
3476     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3477     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3478
3479   }
3480
3481 }
3482
3483 /*-----------------------------------------------------------------*/
3484 /* genSkipc                                                        */
3485 /*-----------------------------------------------------------------*/
3486 static void genSkipc(resolvedIfx *rifx)
3487 {
3488   if(!rifx)
3489     return;
3490
3491   if(rifx->condition)
3492     emitSKPC;
3493   else
3494     emitSKPNC;
3495
3496   emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3497   rifx->generated = 1;
3498 }
3499
3500 /*-----------------------------------------------------------------*/
3501 /* genSkipz                                                        */
3502 /*-----------------------------------------------------------------*/
3503 static void genSkipz(iCode *ifx, int condition)
3504 {
3505   if(!ifx)
3506     return;
3507
3508   if(condition)
3509     emitSKPNZ;
3510   else
3511     emitSKPZ;
3512
3513   if ( IC_TRUE(ifx) )
3514     emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3515   else
3516     emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3517
3518   if ( IC_TRUE(ifx) )
3519     pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3520   else
3521     pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3522
3523 }
3524 /*-----------------------------------------------------------------*/
3525 /* genCmp :- greater or less than comparison                       */
3526 /*-----------------------------------------------------------------*/
3527 static void genCmp (operand *left,operand *right,
3528                     operand *result, iCode *ifx, int sign)
3529 {
3530   int size, offset = 0 ;
3531   unsigned long lit = 0L,i = 0;
3532   resolvedIfx rIfx;
3533
3534   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3535   if(ifx) {
3536   DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3537   DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3538   }
3539
3540   resolveIfx(&rIfx,ifx);
3541
3542   /* if left & right are bit variables */
3543   if (AOP_TYPE(left) == AOP_CRY &&
3544       AOP_TYPE(right) == AOP_CRY ) {
3545     pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3546     pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3547   } else {
3548     /* subtract right from left if at the
3549        end the carry flag is set then we know that
3550        left is greater than right */
3551     size = max(AOP_SIZE(left),AOP_SIZE(right));
3552
3553     /* if unsigned char cmp with lit, do cjne left,#right,zz */
3554     if((size == 1) && !sign &&
3555        (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3556       symbol *lbl  = newiTempLabel(NULL);
3557       pic14_emitcode("cjne","%s,%s,%05d_DS_",
3558                aopGet(AOP(left),offset,FALSE,FALSE),
3559                aopGet(AOP(right),offset,FALSE,FALSE),
3560                lbl->key+100);
3561       pic14_emitcode("","%05d_DS_:",lbl->key+100);
3562     } else {
3563
3564       if(AOP_TYPE(right) == AOP_LIT) {
3565         symbol *lbl = newiTempLabel(NULL);
3566
3567         lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3568
3569         DEBUGpic14_emitcode(";right lit","lit = %d,sign=%d",lit,sign);
3570
3571         size--;
3572         i = (lit >> (size*8)) & 0xff;
3573         if(sign) {
3574           if(i & 0x80) {
3575             emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3576           } else {
3577             emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3578           }
3579           emitpcode(POC_GOTO,popGetLabel(lbl->key));
3580         }
3581
3582         emitpcode(POC_MOVLW, popGetLit(i));
3583         emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3584         while(size--) {
3585           i = (lit >> (size*8)) & 0xff;
3586           emitpcode(POC_MOVLW, popGetLit(i));
3587           emitSKPNC;
3588           emitpcode(POC_SUBFW, popGet(AOP(left),size,FALSE,FALSE));
3589         }
3590
3591         if(ifx) {
3592           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3593           //genSkipc(ifx,0,1); //IC_TRUE(ifx) == NULL);
3594           genSkipc(&rIfx);
3595           //if(sign)
3596             emitpLabel(lbl->key);
3597
3598           ifx->generated = 1;
3599         }
3600         return;
3601       }
3602
3603       if(AOP_TYPE(left) == AOP_LIT) {
3604         //symbol *lbl = newiTempLabel(NULL);
3605
3606         lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3607
3608         DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3609
3610         if(size==1) {
3611           if(sign) {
3612             if(lit & 0x80) {
3613               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3614             } else {
3615               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
3616             }
3617             if(ifx) {
3618               if(IC_TRUE(ifx) != NULL)
3619                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3620               else
3621                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3622             }
3623           }
3624           emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
3625           emitpcode(POC_SUBFW, popGet(AOP(right),0,FALSE,FALSE));
3626           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3627           rIfx.condition ^= 1;
3628           genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,1,1);//IC_TRUE(ifx)!=NULL);
3629         } else {
3630           size--;
3631           //lit++;
3632           i = (lit >> (size*8)) & 0xff;
3633
3634           if(sign) {
3635             if(i & 0x80) {
3636               emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3637             } else {
3638               emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
3639             }
3640             if(ifx) {
3641               if(IC_TRUE(ifx) != NULL)
3642                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3643               else
3644                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3645             }
3646           }
3647
3648           emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3649           emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3650           while(size--) {
3651             i = (lit >> (size*8)) & 0xff;
3652             emitpcode(POC_MOVFW, popGet(AOP(right),size,FALSE,FALSE));
3653             emitSKPNC;
3654             emitpcode(POC_SUBLW, popGetLit((i)&0xff));
3655           }
3656   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3657           genSkipc(&rIfx);//      if(ifx) genSkipc(ifx,0,1);  //IC_TRUE(ifx) == NULL);
3658
3659         }
3660 /*
3661         if(sign)
3662           emitpLabel(lbl->key);
3663 */
3664         if(ifx) ifx->generated = 1;
3665         return;
3666       }
3667
3668
3669       // CLRC;
3670       DEBUGpic14_emitcode(";sign","%d",sign);
3671
3672       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3673       pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));//++
3674
3675       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
3676       emitpcode(POC_SUBFW, popGet(AOP(left),offset++,FALSE,FALSE));
3677
3678       size--;
3679       while (size--) {
3680
3681         emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
3682         emitSKPC;
3683         emitpcode(POC_INCFSZW, popGet(AOP(right),offset,FALSE,FALSE));
3684         emitpcode(POC_SUBFW,   popGet(AOP(left),offset,FALSE,FALSE));
3685
3686 /*
3687         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3688         emitSKPC;
3689         pic14_emitcode("incfsz","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
3690         pic14_emitcode("subwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3691 */
3692         offset++;
3693       }
3694     }
3695   }
3696
3697   //release:
3698   if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
3699     pic14_outBitC(result);
3700   } else {
3701     /* if the result is used in the next
3702        ifx conditional branch then generate
3703        code a little differently */
3704     if (ifx )
3705       genIfxJump (ifx,"c");
3706     else
3707       pic14_outBitC(result);
3708     /* leave the result in acc */
3709   }
3710
3711 }
3712
3713 /*-----------------------------------------------------------------*/
3714 /* genCmpGt :- greater than comparison                             */
3715 /*-----------------------------------------------------------------*/
3716 static void genCmpGt (iCode *ic, iCode *ifx)
3717 {
3718     operand *left, *right, *result;
3719     sym_link *letype , *retype;
3720     int sign ;
3721
3722     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3723     left = IC_LEFT(ic);
3724     right= IC_RIGHT(ic);
3725     result = IC_RESULT(ic);
3726
3727     letype = getSpec(operandType(left));
3728     retype =getSpec(operandType(right));
3729     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3730     /* assign the amsops */
3731     aopOp (left,ic,FALSE);
3732     aopOp (right,ic,FALSE);
3733     aopOp (result,ic,TRUE);
3734
3735     genCmp(right, left, result, ifx, sign);
3736
3737     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3738     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3739     freeAsmop(result,NULL,ic,TRUE); 
3740 }
3741
3742 /*-----------------------------------------------------------------*/
3743 /* genCmpLt - less than comparisons                                */
3744 /*-----------------------------------------------------------------*/
3745 static void genCmpLt (iCode *ic, iCode *ifx)
3746 {
3747     operand *left, *right, *result;
3748     sym_link *letype , *retype;
3749     int sign ;
3750
3751     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3752     left = IC_LEFT(ic);
3753     right= IC_RIGHT(ic);
3754     result = IC_RESULT(ic);
3755
3756     letype = getSpec(operandType(left));
3757     retype =getSpec(operandType(right));
3758     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
3759
3760     /* assign the amsops */
3761     aopOp (left,ic,FALSE);
3762     aopOp (right,ic,FALSE);
3763     aopOp (result,ic,TRUE);
3764
3765     genCmp(left, right, result, ifx, sign);
3766
3767     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3768     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3769     freeAsmop(result,NULL,ic,TRUE); 
3770 }
3771
3772 /*-----------------------------------------------------------------*/
3773 /* genc16bit2lit - compare a 16 bit value to a literal             */
3774 /*-----------------------------------------------------------------*/
3775 static void genc16bit2lit(operand *op, int lit, int offset)
3776 {
3777   int i;
3778
3779   DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
3780   if( (lit&0xff) == 0) 
3781     i=1;
3782   else
3783     i=0;
3784
3785   switch( BYTEofLONG(lit,i)) { 
3786   case 0:
3787     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3788     break;
3789   case 1:
3790     emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3791     break;
3792   case 0xff:
3793     emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3794     break;
3795   default:
3796     emitpcode(POC_MOVFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3797     emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
3798   }
3799
3800   i ^= 1;
3801
3802   switch( BYTEofLONG(lit,i)) { 
3803   case 0:
3804     emitpcode(POC_IORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3805     break;
3806   case 1:
3807     emitSKPNZ;
3808     emitpcode(POC_DECFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3809     break;
3810   case 0xff:
3811     emitSKPNZ;
3812     emitpcode(POC_INCFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3813     break;
3814   default:
3815     emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
3816     emitSKPNZ;
3817     emitpcode(POC_XORFW,popGet(AOP(op),offset+i,FALSE,FALSE));
3818
3819   }
3820
3821 }
3822
3823 /*-----------------------------------------------------------------*/
3824 /* gencjneshort - compare and jump if not equal                    */
3825 /*-----------------------------------------------------------------*/
3826 static void gencjne(operand *left, operand *right, iCode *ifx)
3827 {
3828   int size = max(AOP_SIZE(left),AOP_SIZE(right));
3829   int offset = 0;
3830   resolvedIfx rIfx;
3831   symbol *lbl;
3832
3833   unsigned long lit = 0L;
3834   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3835   DEBUGpic14_emitcode ("; ","left %s=%s, right %s=%s, size = %d",
3836                        AopType(AOP_TYPE(left)),
3837                        aopGet(AOP(left),0,TRUE,FALSE),
3838                        AopType(AOP_TYPE(right)),
3839                        aopGet(AOP(right),0,FALSE,FALSE),
3840                        size);
3841
3842   resolveIfx(&rIfx,ifx);
3843   lbl =  newiTempLabel(NULL);
3844
3845
3846   /* if the left side is a literal or 
3847      if the right is in a pointer register and left 
3848      is not */
3849   if ((AOP_TYPE(left) == AOP_LIT) || 
3850       (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
3851     operand *t = right;
3852     right = left;
3853     left = t;
3854   }
3855   if(AOP_TYPE(right) == AOP_LIT)
3856     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3857
3858   /* if the right side is a literal then anything goes */
3859   if (AOP_TYPE(right) == AOP_LIT &&
3860       AOP_TYPE(left) != AOP_DIR ) {
3861     switch(size) {
3862     case 2:
3863       genc16bit2lit(left, lit, 0);
3864       emitSKPNZ;
3865       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3866       emitpcode(POC_GOTO,popGetLabel(lbl->key));
3867       break;
3868     default:
3869       while (size--) {
3870         if(lit & 0xff) {
3871           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3872           emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3873           pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
3874           pic14_emitcode("xorlw","0x%x",lit & 0xff);
3875         } else {
3876           emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3877           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3878         }
3879
3880         emitSKPNZ;
3881         pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3882         emitpcode(POC_GOTO,popGetLabel(lbl->key));
3883         offset++;
3884         lit >>= 8;
3885       }
3886       break;
3887     }
3888   }
3889
3890   /* if the right side is in a register or in direct space or
3891      if the left is a pointer register & right is not */    
3892   else if (AOP_TYPE(right) == AOP_REG ||
3893            AOP_TYPE(right) == AOP_DIR || 
3894            (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
3895            (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
3896     switch(size) {
3897     case 2:
3898       genc16bit2lit(left, lit, 0);
3899       emitSKPNZ;
3900       pic14_emitcode("goto","_%05d_DS_",lbl->key+100+labelOffset);
3901       emitpcode(POC_GOTO,popGetLabel(lbl->key));
3902       break;
3903     default:
3904       while (size--) {
3905         int emit_skip=1;
3906         if((AOP_TYPE(left) == AOP_DIR) && 
3907            ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
3908
3909           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3910           emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3911
3912         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
3913             
3914           switch (lit & 0xff) {
3915           case 0:
3916             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3917             break;
3918           case 1:
3919             emitpcode(POC_DECFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3920             emitpcode(POC_GOTO,popGetLabel(lbl->key));
3921             emit_skip=0;
3922             break;
3923           case 0xff:
3924             emitpcode(POC_INCFSZ,popGet(AOP(left),offset,FALSE,FALSE));
3925             emitpcode(POC_GOTO,popGetLabel(lbl->key));
3926             emit_skip=0;
3927             break;
3928           default:
3929             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3930             emitpcode(POC_XORLW,popGetLit(lit & 0xff));
3931           }
3932           lit >>= 8;
3933
3934         } else {
3935           emitpcode(POC_MOVF,popGet(AOP(left),offset,FALSE,FALSE));
3936           pic14_emitcode("movf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
3937         }
3938         if(emit_skip) {
3939           pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
3940           if(rIfx.condition)
3941             emitSKPNZ;
3942           else
3943             emitSKPZ;
3944           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3945           if(ifx)
3946             ifx->generated=1;
3947         }
3948         emit_skip++;
3949         offset++;
3950       }
3951       break;
3952     }
3953   } else if(AOP_TYPE(right) == AOP_REG &&
3954             AOP_TYPE(left) != AOP_DIR){
3955
3956     while(size--) {
3957       emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
3958       emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
3959       pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
3960       if(rIfx.condition)
3961         emitSKPNZ;
3962       else
3963         emitSKPZ;
3964       emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
3965       offset++;
3966     }
3967       
3968   }else{
3969     /* right is a pointer reg need both a & b */
3970     while(size--) {
3971       char *l = aopGet(AOP(left),offset,FALSE,FALSE);
3972       if(strcmp(l,"b"))
3973         pic14_emitcode("mov","b,%s",l);
3974       MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
3975       pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
3976       offset++;
3977     }
3978   }
3979   emitpLabel(lbl->key);
3980
3981   if(ifx)
3982     ifx->generated = 1;
3983 }
3984
3985 #if 0
3986 /*-----------------------------------------------------------------*/
3987 /* gencjne - compare and jump if not equal                         */
3988 /*-----------------------------------------------------------------*/
3989 static void gencjne(operand *left, operand *right, iCode *ifx)
3990 {
3991     symbol *tlbl  = newiTempLabel(NULL);
3992
3993     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3994     gencjneshort(left, right, lbl);
3995
3996     pic14_emitcode("mov","a,%s",one);
3997     pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
3998     pic14_emitcode("","%05d_DS_:",lbl->key+100);
3999     pic14_emitcode("clr","a");
4000     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4001
4002     emitpLabel(lbl->key);
4003     emitpLabel(tlbl->key);
4004
4005 }
4006 #endif
4007
4008 /*-----------------------------------------------------------------*/
4009 /* genCmpEq - generates code for equal to                          */
4010 /*-----------------------------------------------------------------*/
4011 static void genCmpEq (iCode *ic, iCode *ifx)
4012 {
4013     operand *left, *right, *result;
4014     unsigned long lit = 0L;
4015     int size,offset=0;
4016
4017     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4018
4019     if(ifx)
4020       DEBUGpic14_emitcode ("; ifx is non-null","");
4021     else
4022       DEBUGpic14_emitcode ("; ifx is null","");
4023
4024     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4025     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4026     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4027
4028 /*
4029     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4030                          AopType(AOP_TYPE(IC_RESULT(ic))),
4031                          AopType(AOP_TYPE(IC_LEFT(ic))),
4032                          AopType(AOP_TYPE(IC_RIGHT(ic))));
4033 */
4034     size = max(AOP_SIZE(left),AOP_SIZE(right));
4035     DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
4036                          AopType(AOP_TYPE(result)),
4037                          aopGet(AOP(result),0,TRUE,FALSE),
4038                          AopType(AOP_TYPE(left)),
4039                          aopGet(AOP(left),0,TRUE,FALSE),
4040                          AopType(AOP_TYPE(right)),
4041                          aopGet(AOP(right),0,FALSE,FALSE),
4042                          size);
4043
4044
4045     /* if literal, literal on the right or 
4046     if the right is in a pointer register and left 
4047     is not */
4048     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4049         (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4050         operand *t = IC_RIGHT(ic);
4051         IC_RIGHT(ic) = IC_LEFT(ic);
4052         IC_LEFT(ic) = t;
4053     }
4054
4055     if(ifx && !AOP_SIZE(result)){
4056         symbol *tlbl;
4057         /* if they are both bit variables */
4058         if (AOP_TYPE(left) == AOP_CRY &&
4059             ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4060             if(AOP_TYPE(right) == AOP_LIT){
4061                 unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4062                 if(lit == 0L){
4063                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4064                     pic14_emitcode("cpl","c");
4065                 } else if(lit == 1L) {
4066                     pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4067                 } else {
4068                     pic14_emitcode("clr","c");
4069                 }
4070                 /* AOP_TYPE(right) == AOP_CRY */
4071             } else {
4072                 symbol *lbl = newiTempLabel(NULL);
4073                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4074                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4075                 pic14_emitcode("cpl","c");
4076                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4077             }
4078             /* if true label then we jump if condition
4079             supplied is true */
4080             tlbl = newiTempLabel(NULL);
4081             if ( IC_TRUE(ifx) ) {
4082                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4083                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4084             } else {
4085                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4086                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4087             }
4088             pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4089         } else {
4090
4091           /* They're not both bit variables. Is the right a literal? */
4092           if(AOP_TYPE(right) == AOP_LIT) {
4093             lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4094             
4095
4096             switch(size) {
4097
4098             case 1:
4099               switch(lit & 0xff) {
4100               case 1:
4101                 if ( IC_TRUE(ifx) ) {
4102                   emitpcode(POC_DECFW,popGet(AOP(left),offset,FALSE,FALSE));
4103                   emitSKPNZ;
4104                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4105                 } else {
4106                   emitpcode(POC_DECFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4107                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4108                 }
4109                 break;
4110               case 0xff:
4111                 if ( IC_TRUE(ifx) ) {
4112                   emitpcode(POC_INCFW,popGet(AOP(left),offset,FALSE,FALSE));
4113                   emitSKPNZ;
4114                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4115                 } else {
4116                   emitpcode(POC_INCFSZW,popGet(AOP(left),offset,FALSE,FALSE));
4117                   emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4118                 }
4119                 break;
4120               default:
4121                 emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4122                 if(lit)
4123                   emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4124                 genSkip(ifx,'z');
4125               }
4126
4127
4128               /* end of size == 1 */
4129               break;
4130               
4131             case 2:
4132               genc16bit2lit(left,lit,offset);
4133               genSkip(ifx,'z');
4134               break;
4135               /* end of size == 2 */
4136
4137             default:
4138               /* size is 4 */
4139               if(lit==0) {
4140                 emitpcode(POC_MOVFW,popGet(AOP(left),0,FALSE,FALSE));
4141                 emitpcode(POC_IORFW,popGet(AOP(left),1,FALSE,FALSE));
4142                 emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4143                 emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4144
4145               } else {
4146
4147                 /* search for patterns that can be optimized */
4148
4149                 genc16bit2lit(left,lit,0);
4150                 lit >>= 16;
4151                 if(lit) {
4152                   genSkipz(ifx,IC_TRUE(ifx) == NULL);
4153                   //genSkip(ifx,'z');
4154                   genc16bit2lit(left,lit,2);
4155                 } else {
4156                   emitpcode(POC_IORFW,popGet(AOP(left),2,FALSE,FALSE));
4157                   emitpcode(POC_IORFW,popGet(AOP(left),3,FALSE,FALSE));
4158
4159                 }
4160                 
4161               }
4162
4163               genSkip(ifx,'z');
4164             }
4165           
4166             ifx->generated = 1;
4167             goto release ;
4168             
4169
4170           } else if(AOP_TYPE(right) == AOP_CRY ) {
4171             /* we know the left is not a bit, but that the right is */
4172             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4173             emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4174                       popGet(AOP(right),offset,FALSE,FALSE));
4175             emitpcode(POC_XORLW,popGetLit(1));
4176
4177             pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4178             if ( IC_TRUE(ifx) )
4179               pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4180                        AOP(right)->aopu.aop_dir,
4181                        AOP(right)->aopu.aop_dir);
4182             else
4183               pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4184                        AOP(right)->aopu.aop_dir,
4185                        AOP(right)->aopu.aop_dir);
4186
4187             pic14_emitcode("xorlw","1");
4188
4189             /* if the two are equal, then W will be 0 and the Z bit is set
4190              * we could test Z now, or go ahead and check the high order bytes if
4191              * the variable we're comparing is larger than a byte. */
4192
4193             while(--size)
4194               emitpcode(POC_IORFW,popGet(AOP(left),offset,FALSE,FALSE));
4195             //pic14_emitcode("iorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4196
4197             if ( IC_TRUE(ifx) ) {
4198               emitSKPNZ;
4199               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4200               pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4201             } else {
4202               emitSKPZ;
4203               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4204               pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4205             }
4206
4207           } else {
4208             /* They're both variables that are larger than bits */
4209             int s = size;
4210
4211             tlbl = newiTempLabel(NULL);
4212
4213             while(size--) {
4214               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4215               emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
4216
4217               pic14_emitcode("movf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
4218               pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4219
4220               if ( IC_TRUE(ifx) ) {
4221                 if(size) {
4222                   emitSKPZ;
4223                   emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4224                   pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4225                 } else {
4226                   emitSKPNZ;
4227                   emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4228                   pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4229                 }
4230               } else {
4231                 emitSKPZ;
4232                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4233                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4234               }
4235               offset++;
4236             }
4237             if(s>1 && IC_TRUE(ifx)) {
4238               emitpLabel(tlbl->key);
4239               pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4240             }
4241           }
4242         }
4243         /* mark the icode as generated */
4244         ifx->generated = 1;
4245         goto release ;
4246     }
4247
4248     /* if they are both bit variables */
4249     if (AOP_TYPE(left) == AOP_CRY &&
4250         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4251         if(AOP_TYPE(right) == AOP_LIT){
4252             unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
4253             if(lit == 0L){
4254                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4255                 pic14_emitcode("cpl","c");
4256             } else if(lit == 1L) {
4257                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4258             } else {
4259                 pic14_emitcode("clr","c");
4260             }
4261             /* AOP_TYPE(right) == AOP_CRY */
4262         } else {
4263             symbol *lbl = newiTempLabel(NULL);
4264             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4265             pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4266             pic14_emitcode("cpl","c");
4267             pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4268         }
4269         /* c = 1 if egal */
4270         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4271             pic14_outBitC(result);
4272             goto release ;
4273         }
4274         if (ifx) {
4275             genIfxJump (ifx,"c");
4276             goto release ;
4277         }
4278         /* if the result is used in an arithmetic operation
4279         then put the result in place */
4280         pic14_outBitC(result);
4281     } else {
4282       
4283       gencjne(left,right,ifx);
4284 /*
4285       if(ifx) 
4286         gencjne(left,right,newiTempLabel(NULL));
4287       else {
4288         if(IC_TRUE(ifx)->key)
4289           gencjne(left,right,IC_TRUE(ifx)->key);
4290         else
4291           gencjne(left,right,IC_FALSE(ifx)->key);
4292         ifx->generated = 1;
4293         goto release ;
4294       }
4295       if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4296         aopPut(AOP(result),"a",0);
4297         goto release ;
4298       }
4299
4300       if (ifx) {
4301         genIfxJump (ifx,"a");
4302         goto release ;
4303       }
4304 */
4305       /* if the result is used in an arithmetic operation
4306          then put the result in place */
4307       if (AOP_TYPE(result) != AOP_CRY) 
4308         pic14_outAcc(result);
4309       /* leave the result in acc */
4310     }
4311
4312 release:
4313     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4314     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4315     freeAsmop(result,NULL,ic,TRUE);
4316 }
4317
4318 /*-----------------------------------------------------------------*/
4319 /* ifxForOp - returns the icode containing the ifx for operand     */
4320 /*-----------------------------------------------------------------*/
4321 static iCode *ifxForOp ( operand *op, iCode *ic )
4322 {
4323     /* if true symbol then needs to be assigned */
4324     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4325     if (IS_TRUE_SYMOP(op))
4326         return NULL ;
4327
4328     /* if this has register type condition and
4329     the next instruction is ifx with the same operand
4330     and live to of the operand is upto the ifx only then */
4331     if (ic->next &&
4332         ic->next->op == IFX &&
4333         IC_COND(ic->next)->key == op->key &&
4334         OP_SYMBOL(op)->liveTo <= ic->next->seq )
4335         return ic->next;
4336
4337     if (ic->next &&
4338         ic->next->op == IFX &&
4339         IC_COND(ic->next)->key == op->key) {
4340       DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4341       return ic->next;
4342     }
4343
4344     DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4345     if (ic->next &&
4346         ic->next->op == IFX)
4347       DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4348
4349     if (ic->next &&
4350         ic->next->op == IFX &&
4351         IC_COND(ic->next)->key == op->key) {
4352       DEBUGpic14_emitcode ("; "," key is okay");
4353       DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4354                            OP_SYMBOL(op)->liveTo,
4355                            ic->next->seq);
4356     }
4357
4358
4359     return NULL;
4360 }
4361 /*-----------------------------------------------------------------*/
4362 /* genAndOp - for && operation                                     */
4363 /*-----------------------------------------------------------------*/
4364 static void genAndOp (iCode *ic)
4365 {
4366     operand *left,*right, *result;
4367     symbol *tlbl;
4368
4369     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4370     /* note here that && operations that are in an
4371     if statement are taken away by backPatchLabels
4372     only those used in arthmetic operations remain */
4373     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4374     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4375     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4376
4377     /* if both are bit variables */
4378     if (AOP_TYPE(left) == AOP_CRY &&
4379         AOP_TYPE(right) == AOP_CRY ) {
4380         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4381         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4382         pic14_outBitC(result);
4383     } else {
4384         tlbl = newiTempLabel(NULL);
4385         pic14_toBoolean(left);    
4386         pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4387         pic14_toBoolean(right);
4388         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4389         pic14_outBitAcc(result);
4390     }
4391
4392     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4393     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4394     freeAsmop(result,NULL,ic,TRUE);
4395 }
4396
4397
4398 /*-----------------------------------------------------------------*/
4399 /* genOrOp - for || operation                                      */
4400 /*-----------------------------------------------------------------*/
4401 /*
4402   tsd pic port -
4403   modified this code, but it doesn't appear to ever get called
4404 */
4405
4406 static void genOrOp (iCode *ic)
4407 {
4408     operand *left,*right, *result;
4409     symbol *tlbl;
4410
4411     /* note here that || operations that are in an
4412     if statement are taken away by backPatchLabels
4413     only those used in arthmetic operations remain */
4414     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4415     aopOp((left=IC_LEFT(ic)),ic,FALSE);
4416     aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4417     aopOp((result=IC_RESULT(ic)),ic,FALSE);
4418
4419     /* if both are bit variables */
4420     if (AOP_TYPE(left) == AOP_CRY &&
4421         AOP_TYPE(right) == AOP_CRY ) {
4422       pic14_emitcode("clrc","");
4423       pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4424                AOP(left)->aopu.aop_dir,
4425                AOP(left)->aopu.aop_dir);
4426       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4427                AOP(right)->aopu.aop_dir,
4428                AOP(right)->aopu.aop_dir);
4429       pic14_emitcode("setc","");
4430
4431     } else {
4432         tlbl = newiTempLabel(NULL);
4433         pic14_toBoolean(left);
4434         emitSKPZ;
4435         pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4436         pic14_toBoolean(right);
4437         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4438
4439         pic14_outBitAcc(result);
4440     }
4441
4442     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4443     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4444     freeAsmop(result,NULL,ic,TRUE);            
4445 }
4446
4447 /*-----------------------------------------------------------------*/
4448 /* isLiteralBit - test if lit == 2^n                               */
4449 /*-----------------------------------------------------------------*/
4450 static int isLiteralBit(unsigned long lit)
4451 {
4452     unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4453     0x100L,0x200L,0x400L,0x800L,
4454     0x1000L,0x2000L,0x4000L,0x8000L,
4455     0x10000L,0x20000L,0x40000L,0x80000L,
4456     0x100000L,0x200000L,0x400000L,0x800000L,
4457     0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4458     0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4459     int idx;
4460     
4461     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4462     for(idx = 0; idx < 32; idx++)
4463         if(lit == pw[idx])
4464             return idx+1;
4465     return 0;
4466 }
4467
4468 /*-----------------------------------------------------------------*/
4469 /* continueIfTrue -                                                */
4470 /*-----------------------------------------------------------------*/
4471 static void continueIfTrue (iCode *ic)
4472 {
4473     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4474     if(IC_TRUE(ic))
4475         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4476     ic->generated = 1;
4477 }
4478
4479 /*-----------------------------------------------------------------*/
4480 /* jmpIfTrue -                                                     */
4481 /*-----------------------------------------------------------------*/
4482 static void jumpIfTrue (iCode *ic)
4483 {
4484     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4485     if(!IC_TRUE(ic))
4486         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4487     ic->generated = 1;
4488 }
4489
4490 /*-----------------------------------------------------------------*/
4491 /* jmpTrueOrFalse -                                                */
4492 /*-----------------------------------------------------------------*/
4493 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
4494 {
4495     // ugly but optimized by peephole
4496     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4497     if(IC_TRUE(ic)){
4498         symbol *nlbl = newiTempLabel(NULL);
4499         pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
4500         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4501         pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4502         pic14_emitcode("","%05d_DS_:",nlbl->key+100);
4503     }
4504     else{
4505         pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4506         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4507     }
4508     ic->generated = 1;
4509 }
4510
4511 /*-----------------------------------------------------------------*/
4512 /* genAnd  - code for and                                          */
4513 /*-----------------------------------------------------------------*/
4514 static void genAnd (iCode *ic, iCode *ifx)
4515 {
4516   operand *left, *right, *result;
4517   int size, offset=0;  
4518   unsigned long lit = 0L;
4519   int bytelit = 0;
4520   resolvedIfx rIfx;
4521
4522
4523   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4524   aopOp((left = IC_LEFT(ic)),ic,FALSE);
4525   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4526   aopOp((result=IC_RESULT(ic)),ic,TRUE);
4527
4528   resolveIfx(&rIfx,ifx);
4529
4530   /* if left is a literal & right is not then exchange them */
4531   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4532       AOP_NEEDSACC(left)) {
4533     operand *tmp = right ;
4534     right = left;
4535     left = tmp;
4536   }
4537
4538   /* if result = right then exchange them */
4539   if(pic14_sameRegs(AOP(result),AOP(right))){
4540     operand *tmp = right ;
4541     right = left;
4542     left = tmp;
4543   }
4544
4545   /* if right is bit then exchange them */
4546   if (AOP_TYPE(right) == AOP_CRY &&
4547       AOP_TYPE(left) != AOP_CRY){
4548     operand *tmp = right ;
4549     right = left;
4550     left = tmp;
4551   }
4552   if(AOP_TYPE(right) == AOP_LIT)
4553     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4554
4555   size = AOP_SIZE(result);
4556
4557   DEBUGpic14_emitcode ("; ","result %s=%s, left %s=%s, right %s=%s, size = %d",
4558                        AopType(AOP_TYPE(result)),
4559                        aopGet(AOP(result),0,TRUE,FALSE),
4560                        AopType(AOP_TYPE(left)),
4561                        aopGet(AOP(left),0,TRUE,FALSE),
4562                        AopType(AOP_TYPE(right)),
4563                        aopGet(AOP(right),0,FALSE,FALSE),
4564                        size);
4565   // if(bit & yy)
4566   // result = bit & yy;
4567   if (AOP_TYPE(left) == AOP_CRY){
4568     // c = bit & literal;
4569     if(AOP_TYPE(right) == AOP_LIT){
4570       if(lit & 1) {
4571         if(size && pic14_sameRegs(AOP(result),AOP(left)))
4572           // no change
4573           goto release;
4574         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4575       } else {
4576         // bit(result) = 0;
4577         if(size && (AOP_TYPE(result) == AOP_CRY)){
4578           pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
4579           goto release;
4580         }
4581         if((AOP_TYPE(result) == AOP_CRY) && ifx){
4582           jumpIfTrue(ifx);
4583           goto release;
4584         }
4585         pic14_emitcode("clr","c");
4586       }
4587     } else {
4588       if (AOP_TYPE(right) == AOP_CRY){
4589         // c = bit & bit;
4590         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4591         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4592       } else {
4593         // c = bit & val;
4594         MOVA(aopGet(AOP(right),0,FALSE,FALSE));
4595         // c = lsb
4596         pic14_emitcode("rrc","a");
4597         pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
4598       }
4599     }
4600     // bit = c
4601     // val = c
4602     if(size)
4603       pic14_outBitC(result);
4604     // if(bit & ...)
4605     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4606       genIfxJump(ifx, "c");           
4607     goto release ;
4608   }
4609
4610   // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
4611   // bit = val & 0xZZ     - size = 1, ifx = FALSE -
4612   if((AOP_TYPE(right) == AOP_LIT) &&
4613      (AOP_TYPE(result) == AOP_CRY) &&
4614      (AOP_TYPE(left) != AOP_CRY)){
4615     int posbit = isLiteralBit(lit);
4616     /* left &  2^n */
4617     if(posbit){
4618       posbit--;
4619       //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
4620       // bit = left & 2^n
4621       if(size)
4622         pic14_emitcode("mov","c,acc.%d",posbit&0x07);
4623       // if(left &  2^n)
4624       else{
4625         if(ifx){
4626 /*
4627           if(IC_TRUE(ifx)) {
4628             emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4629             emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
4630           } else {
4631             emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4632             emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
4633           }
4634 */
4635           emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
4636                     newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
4637           emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4638           
4639           ifx->generated = 1;
4640         }
4641         goto release;
4642       }
4643     } else {
4644       symbol *tlbl = newiTempLabel(NULL);
4645       int sizel = AOP_SIZE(left);
4646       if(size)
4647         pic14_emitcode("setb","c");
4648       while(sizel--){
4649         if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
4650           MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
4651           // byte ==  2^n ?
4652           if((posbit = isLiteralBit(bytelit)) != 0)
4653             pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
4654           else{
4655             if(bytelit != 0x0FFL)
4656               pic14_emitcode("anl","a,%s",
4657                              aopGet(AOP(right),offset,FALSE,TRUE));
4658             pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4659           }
4660         }
4661         offset++;
4662       }
4663       // bit = left & literal
4664       if(size){
4665         pic14_emitcode("clr","c");
4666         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4667       }
4668       // if(left & literal)
4669       else{
4670         if(ifx)
4671           jmpTrueOrFalse(ifx, tlbl);
4672         goto release ;
4673       }
4674     }
4675     pic14_outBitC(result);
4676     goto release ;
4677   }
4678
4679   /* if left is same as result */
4680   if(pic14_sameRegs(AOP(result),AOP(left))){
4681     int know_W = -1;
4682     for(;size--; offset++,lit>>=8) {
4683       if(AOP_TYPE(right) == AOP_LIT){
4684         switch(lit & 0xff) {
4685         case 0x00:
4686           /*  and'ing with 0 has clears the result */
4687           pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4688           emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4689           break;
4690         case 0xff:
4691           /* and'ing with 0xff is a nop when the result and left are the same */
4692           break;
4693
4694         default:
4695           {
4696             int p = my_powof2( (~lit) & 0xff );
4697             if(p>=0) {
4698               /* only one bit is set in the literal, so use a bcf instruction */
4699               pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
4700               //emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
4701               emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
4702
4703             } else {
4704               pic14_emitcode("movlw","0x%x", (lit & 0xff));
4705               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
4706               if(know_W != (lit&0xff))
4707                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
4708               know_W = lit &0xff;
4709               emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
4710             }
4711           }    
4712         }
4713       } else {
4714         if (AOP_TYPE(left) == AOP_ACC) {
4715           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4716         } else {                    
4717           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4718           emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,FALSE));
4719
4720         }
4721       }
4722     }
4723
4724   } else {
4725     // left & result in different registers
4726     if(AOP_TYPE(result) == AOP_CRY){
4727       // result = bit
4728       // if(size), result in bit
4729       // if(!size && ifx), conditional oper: if(left & right)
4730       symbol *tlbl = newiTempLabel(NULL);
4731       int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
4732       if(size)
4733         pic14_emitcode("setb","c");
4734       while(sizer--){
4735         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4736         pic14_emitcode("anl","a,%s",
4737                        aopGet(AOP(left),offset,FALSE,FALSE));
4738         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
4739         offset++;
4740       }
4741       if(size){
4742         CLRC;
4743         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4744         pic14_outBitC(result);
4745       } else if(ifx)
4746         jmpTrueOrFalse(ifx, tlbl);
4747     } else {
4748       for(;(size--);offset++) {
4749         // normal case
4750         // result = left & right
4751         if(AOP_TYPE(right) == AOP_LIT){
4752           int t = (lit >> (offset*8)) & 0x0FFL;
4753           switch(t) { 
4754           case 0x00:
4755             pic14_emitcode("clrf","%s",
4756                            aopGet(AOP(result),offset,FALSE,FALSE));
4757             emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
4758             break;
4759           case 0xff:
4760             pic14_emitcode("movf","%s,w",
4761                            aopGet(AOP(left),offset,FALSE,FALSE));
4762             pic14_emitcode("movwf","%s",
4763                            aopGet(AOP(result),offset,FALSE,FALSE));
4764             emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
4765             emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4766             break;
4767           default:
4768             pic14_emitcode("movlw","0x%x",t);
4769             pic14_emitcode("andwf","%s,w",
4770                            aopGet(AOP(left),offset,FALSE,FALSE));
4771             pic14_emitcode("movwf","%s",
4772                            aopGet(AOP(result),offset,FALSE,FALSE));
4773               
4774             emitpcode(POC_MOVLW, popGetLit(t));
4775             emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4776             emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4777           }
4778           continue;
4779         }
4780
4781         if (AOP_TYPE(left) == AOP_ACC) {
4782           pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4783           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
4784         } else {
4785           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
4786           pic14_emitcode("andwf","%s,w",
4787                          aopGet(AOP(left),offset,FALSE,FALSE));
4788           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
4789           emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
4790         }
4791         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
4792         emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
4793       }
4794     }
4795   }
4796
4797   release :
4798     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4799   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4800   freeAsmop(result,NULL,ic,TRUE);     
4801 }
4802
4803 /*-----------------------------------------------------------------*/
4804 /* genOr  - code for or                                            */
4805 /*-----------------------------------------------------------------*/
4806 static void genOr (iCode *ic, iCode *ifx)
4807 {
4808     operand *left, *right, *result;
4809     int size, offset=0;
4810     unsigned long lit = 0L;
4811
4812     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4813
4814     aopOp((left = IC_LEFT(ic)),ic,FALSE);
4815     aopOp((right= IC_RIGHT(ic)),ic,FALSE);
4816     aopOp((result=IC_RESULT(ic)),ic,TRUE);
4817
4818
4819     /* if left is a literal & right is not then exchange them */
4820     if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
4821         AOP_NEEDSACC(left)) {
4822         operand *tmp = right ;
4823         right = left;
4824         left = tmp;
4825     }
4826
4827     /* if result = right then exchange them */
4828     if(pic14_sameRegs(AOP(result),AOP(right))){
4829         operand *tmp = right ;
4830         right = left;
4831         left = tmp;
4832     }
4833
4834     /* if right is bit then exchange them */
4835     if (AOP_TYPE(right) == AOP_CRY &&
4836         AOP_TYPE(left) != AOP_CRY){
4837         operand *tmp = right ;
4838         right = left;
4839         left = tmp;
4840     }
4841
4842     DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
4843                          AopType(AOP_TYPE(result)),
4844                          AopType(AOP_TYPE(left)),
4845                          AopType(AOP_TYPE(right)));
4846
4847     if(AOP_TYPE(right) == AOP_LIT)
4848         lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
4849
4850     size = AOP_SIZE(result);
4851
4852     // if(bit | yy)
4853     // xx = bit | yy;
4854     if (AOP_TYPE(left) == AOP_CRY){
4855         if(AOP_TYPE(right) == AOP_LIT){
4856             // c = bit & literal;
4857             if(lit){
4858                 // lit != 0 => result = 1
4859                 if(AOP_TYPE(result) == AOP_CRY){
4860                   if(size)
4861                     emitpcode(POC_BSF, popGet(AOP(result),0,FALSE,FALSE));
4862                   //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4863                   //     AOP(result)->aopu.aop_dir,
4864                   //     AOP(result)->aopu.aop_dir);
4865                     else if(ifx)
4866                         continueIfTrue(ifx);
4867                     goto release;
4868                 }
4869             } else {
4870                 // lit == 0 => result = left
4871                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
4872                     goto release;
4873                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
4874             }
4875         } else {
4876             if (AOP_TYPE(right) == AOP_CRY){
4877               if(pic14_sameRegs(AOP(result),AOP(left))){
4878                 // c = bit | bit;
4879                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4880                 emitpcode(POC_BTFSC, popGet(AOP(right),0,FALSE,FALSE));
4881                 emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4882
4883                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4884                          AOP(result)->aopu.aop_dir,
4885                          AOP(result)->aopu.aop_dir);
4886                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4887                          AOP(right)->aopu.aop_dir,
4888                          AOP(right)->aopu.aop_dir);
4889                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4890                          AOP(result)->aopu.aop_dir,
4891                          AOP(result)->aopu.aop_dir);
4892               } else {
4893                 if( AOP_TYPE(result) == AOP_ACC) {
4894                   emitpcode(POC_MOVLW, popGetLit(0));
4895                   emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4896                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4897                   emitpcode(POC_MOVLW, popGetLit(1));
4898
4899                 } else {
4900
4901                   emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4902                   emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
4903                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4904                   emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4905
4906                   pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
4907                                  AOP(result)->aopu.aop_dir,
4908                                  AOP(result)->aopu.aop_dir);
4909                   pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4910                                  AOP(right)->aopu.aop_dir,
4911                                  AOP(right)->aopu.aop_dir);
4912                   pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4913                                  AOP(left)->aopu.aop_dir,
4914                                  AOP(left)->aopu.aop_dir);
4915                   pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
4916                                  AOP(result)->aopu.aop_dir,
4917                                  AOP(result)->aopu.aop_dir);
4918                 }
4919               }
4920             } else {
4921                 // c = bit | val;
4922                 symbol *tlbl = newiTempLabel(NULL);
4923                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4924
4925
4926                 emitpcode(POC_BCF,   popGet(AOP(result),0,FALSE,FALSE));
4927                 if( AOP_TYPE(right) == AOP_ACC) {
4928                   emitpcode(POC_IORLW, popGetLit(0));
4929                   emitSKPNZ;
4930                   emitpcode(POC_BTFSC, popGet(AOP(left),0,FALSE,FALSE));
4931                   emitpcode(POC_BSF,   popGet(AOP(result),0,FALSE,FALSE));
4932                 }
4933
4934
4935
4936                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
4937                     pic14_emitcode(";XXX setb","c");
4938                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
4939                          AOP(left)->aopu.aop_dir,tlbl->key+100);
4940                 pic14_toBoolean(right);
4941                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4942                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
4943                     jmpTrueOrFalse(ifx, tlbl);
4944                     goto release;
4945                 } else {
4946                     CLRC;
4947                     pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4948                 }
4949             }
4950         }
4951         // bit = c
4952         // val = c
4953         if(size)
4954             pic14_outBitC(result);
4955         // if(bit | ...)
4956         else if((AOP_TYPE(result) == AOP_CRY) && ifx)
4957             genIfxJump(ifx, "c");           
4958         goto release ;
4959     }
4960
4961     // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
4962     // bit = val | 0xZZ     - size = 1, ifx = FALSE -
4963     if((AOP_TYPE(right) == AOP_LIT) &&
4964        (AOP_TYPE(result) == AOP_CRY) &&
4965        (AOP_TYPE(left) != AOP_CRY)){
4966         if(lit){
4967           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4968             // result = 1
4969             if(size)
4970                 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
4971             else 
4972                 continueIfTrue(ifx);
4973             goto release;
4974         } else {
4975           pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
4976             // lit = 0, result = boolean(left)
4977             if(size)
4978                 pic14_emitcode(";XXX setb","c");
4979             pic14_toBoolean(right);
4980             if(size){
4981                 symbol *tlbl = newiTempLabel(NULL);
4982                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
4983                 CLRC;
4984                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4985             } else {
4986                 genIfxJump (ifx,"a");
4987                 goto release;
4988             }
4989         }
4990         pic14_outBitC(result);
4991         goto release ;
4992     }
4993
4994     /* if left is same as result */
4995     if(pic14_sameRegs(AOP(result),AOP(left))){
4996       int know_W = -1;
4997       for(;size--; offset++,lit>>=8) {
4998         if(AOP_TYPE(right) == AOP_LIT){
4999           if((lit & 0xff) == 0)
5000             /*  or'ing with 0 has no effect */
5001             continue;
5002           else {
5003             int p = my_powof2(lit & 0xff);
5004             if(p>=0) {
5005               /* only one bit is set in the literal, so use a bsf instruction */
5006               emitpcode(POC_BSF,
5007                         newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5008             } else {
5009               if(know_W != (lit & 0xff))
5010                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5011               know_W = lit & 0xff;
5012               emitpcode(POC_IORWF, popGet(AOP(left),offset,FALSE,FALSE));
5013             }
5014                     
5015           }
5016         } else {
5017           if (AOP_TYPE(left) == AOP_ACC) {
5018             emitpcode(POC_IORFW,  popGet(AOP(right),offset,FALSE,FALSE));
5019             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5020           } else {                  
5021             emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
5022             emitpcode(POC_IORWF,  popGet(AOP(left),offset,FALSE,FALSE));
5023
5024             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5025             pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5026
5027           }
5028         }
5029       }
5030     } else {
5031         // left & result in different registers
5032         if(AOP_TYPE(result) == AOP_CRY){
5033             // result = bit
5034             // if(size), result in bit
5035             // if(!size && ifx), conditional oper: if(left | right)
5036             symbol *tlbl = newiTempLabel(NULL);
5037             int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5038             pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5039
5040
5041             if(size)
5042                 pic14_emitcode(";XXX setb","c");
5043             while(sizer--){
5044                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5045                 pic14_emitcode(";XXX orl","a,%s",
5046                          aopGet(AOP(left),offset,FALSE,FALSE));
5047                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5048                 offset++;
5049             }
5050             if(size){
5051                 CLRC;
5052                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5053                 pic14_outBitC(result);
5054             } else if(ifx)
5055                 jmpTrueOrFalse(ifx, tlbl);
5056         } else for(;(size--);offset++){
5057           // normal case
5058           // result = left & right
5059           if(AOP_TYPE(right) == AOP_LIT){
5060             int t = (lit >> (offset*8)) & 0x0FFL;
5061             switch(t) { 
5062             case 0x00:
5063               emitpcode(POC_MOVFW,  popGet(AOP(left),offset,FALSE,FALSE));
5064               emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5065
5066               pic14_emitcode("movf","%s,w",
5067                        aopGet(AOP(left),offset,FALSE,FALSE));
5068               pic14_emitcode("movwf","%s",
5069                        aopGet(AOP(result),offset,FALSE,FALSE));
5070               break;
5071             default:
5072               emitpcode(POC_MOVLW,  popGetLit(t));
5073               emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
5074               emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5075
5076               pic14_emitcode("movlw","0x%x",t);
5077               pic14_emitcode("iorwf","%s,w",
5078                        aopGet(AOP(left),offset,FALSE,FALSE));
5079               pic14_emitcode("movwf","%s",
5080                        aopGet(AOP(result),offset,FALSE,FALSE));
5081               
5082             }
5083             continue;
5084           }
5085
5086           // faster than result <- left, anl result,right
5087           // and better if result is SFR
5088           if (AOP_TYPE(left) == AOP_ACC) {
5089             emitpcode(POC_IORWF,  popGet(AOP(right),offset,FALSE,FALSE));
5090             pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5091           } else {
5092             emitpcode(POC_MOVFW,  popGet(AOP(right),offset,FALSE,FALSE));
5093             emitpcode(POC_IORFW,  popGet(AOP(left),offset,FALSE,FALSE));
5094
5095             pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5096             pic14_emitcode("iorwf","%s,w",
5097                      aopGet(AOP(left),offset,FALSE,FALSE));
5098           }
5099           emitpcode(POC_MOVWF,  popGet(AOP(result),offset,FALSE,FALSE));
5100           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5101         }
5102     }
5103
5104 release :
5105     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5106     freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5107     freeAsmop(result,NULL,ic,TRUE);     
5108 }
5109
5110 /*-----------------------------------------------------------------*/
5111 /* genXor - code for xclusive or                                   */
5112 /*-----------------------------------------------------------------*/
5113 static void genXor (iCode *ic, iCode *ifx)
5114 {
5115   operand *left, *right, *result;
5116   int size, offset=0;
5117   unsigned long lit = 0L;
5118
5119   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5120
5121   aopOp((left = IC_LEFT(ic)),ic,FALSE);
5122   aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5123   aopOp((result=IC_RESULT(ic)),ic,TRUE);
5124
5125   /* if left is a literal & right is not ||
5126      if left needs acc & right does not */
5127   if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5128       (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5129     operand *tmp = right ;
5130     right = left;
5131     left = tmp;
5132   }
5133
5134   /* if result = right then exchange them */
5135   if(pic14_sameRegs(AOP(result),AOP(right))){
5136     operand *tmp = right ;
5137     right = left;
5138     left = tmp;
5139   }
5140
5141   /* if right is bit then exchange them */
5142   if (AOP_TYPE(right) == AOP_CRY &&
5143       AOP_TYPE(left) != AOP_CRY){
5144     operand *tmp = right ;
5145     right = left;
5146     left = tmp;
5147   }
5148   if(AOP_TYPE(right) == AOP_LIT)
5149     lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5150
5151   size = AOP_SIZE(result);
5152
5153   // if(bit ^ yy)
5154   // xx = bit ^ yy;
5155   if (AOP_TYPE(left) == AOP_CRY){
5156     if(AOP_TYPE(right) == AOP_LIT){
5157       // c = bit & literal;
5158       if(lit>>1){
5159         // lit>>1  != 0 => result = 1
5160         if(AOP_TYPE(result) == AOP_CRY){
5161           if(size)
5162             pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
5163           else if(ifx)
5164             continueIfTrue(ifx);
5165           goto release;
5166         }
5167         pic14_emitcode("setb","c");
5168       } else{
5169         // lit == (0 or 1)
5170         if(lit == 0){
5171           // lit == 0, result = left
5172           if(size && pic14_sameRegs(AOP(result),AOP(left)))
5173             goto release;
5174           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5175         } else{
5176           // lit == 1, result = not(left)
5177           if(size && pic14_sameRegs(AOP(result),AOP(left))){
5178             pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5179             goto release;
5180           } else {
5181             pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5182             pic14_emitcode("cpl","c");
5183           }
5184         }
5185       }
5186
5187     } else {
5188       // right != literal
5189       symbol *tlbl = newiTempLabel(NULL);
5190       if (AOP_TYPE(right) == AOP_CRY){
5191         // c = bit ^ bit;
5192         pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5193       }
5194       else{
5195         int sizer = AOP_SIZE(right);
5196         // c = bit ^ val
5197         // if val>>1 != 0, result = 1
5198         pic14_emitcode("setb","c");
5199         while(sizer){
5200           MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5201           if(sizer == 1)
5202             // test the msb of the lsb
5203             pic14_emitcode("anl","a,#0xfe");
5204           pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5205           sizer--;
5206         }
5207         // val = (0,1)
5208         pic14_emitcode("rrc","a");
5209       }
5210       pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5211       pic14_emitcode("cpl","c");
5212       pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5213     }
5214     // bit = c
5215     // val = c
5216     if(size)
5217       pic14_outBitC(result);
5218     // if(bit | ...)
5219     else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5220       genIfxJump(ifx, "c");           
5221     goto release ;
5222   }
5223
5224   if(pic14_sameRegs(AOP(result),AOP(left))){
5225     /* if left is same as result */
5226     for(;size--; offset++) {
5227       if(AOP_TYPE(right) == AOP_LIT){
5228         int t  = (lit >> (offset*8)) & 0x0FFL;
5229         if(t == 0x00L)
5230           continue;
5231         else
5232           if (IS_AOP_PREG(left)) {
5233             MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5234             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5235             aopPut(AOP(result),"a",offset);
5236           } else {
5237             emitpcode(POC_MOVLW, popGetLit(t));
5238             emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5239             pic14_emitcode("xrl","%s,%s",
5240                            aopGet(AOP(left),offset,FALSE,TRUE),
5241                            aopGet(AOP(right),offset,FALSE,FALSE));
5242           }
5243       } else {
5244         if (AOP_TYPE(left) == AOP_ACC)
5245           pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5246         else {
5247           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5248           emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
5249 /*
5250           if (IS_AOP_PREG(left)) {
5251             pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5252             aopPut(AOP(result),"a",offset);
5253           } else
5254             pic14_emitcode("xrl","%s,a",
5255                            aopGet(AOP(left),offset,FALSE,TRUE));
5256 */
5257         }
5258       }
5259     }
5260   } else {
5261     // left & result in different registers
5262     if(AOP_TYPE(result) == AOP_CRY){
5263       // result = bit
5264       // if(size), result in bit
5265       // if(!size && ifx), conditional oper: if(left ^ right)
5266       symbol *tlbl = newiTempLabel(NULL);
5267       int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5268       if(size)
5269         pic14_emitcode("setb","c");
5270       while(sizer--){
5271         if((AOP_TYPE(right) == AOP_LIT) &&
5272            (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5273           MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5274         } else {
5275           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5276           pic14_emitcode("xrl","a,%s",
5277                          aopGet(AOP(left),offset,FALSE,FALSE));
5278         }
5279         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5280         offset++;
5281       }
5282       if(size){
5283         CLRC;
5284         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5285         pic14_outBitC(result);
5286       } else if(ifx)
5287         jmpTrueOrFalse(ifx, tlbl);
5288     } else for(;(size--);offset++){
5289       // normal case
5290       // result = left & right
5291       if(AOP_TYPE(right) == AOP_LIT){
5292         int t = (lit >> (offset*8)) & 0x0FFL;
5293         switch(t) { 
5294         case 0x00:
5295           emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
5296           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5297           pic14_emitcode("movf","%s,w",
5298                          aopGet(AOP(left),offset,FALSE,FALSE));
5299           pic14_emitcode("movwf","%s",
5300                          aopGet(AOP(result),offset,FALSE,FALSE));
5301           break;
5302         case 0xff:
5303           emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
5304           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5305           pic14_emitcode("comf","%s,w",
5306                          aopGet(AOP(left),offset,FALSE,FALSE));
5307           pic14_emitcode("movwf","%s",
5308                          aopGet(AOP(result),offset,FALSE,FALSE));
5309           break;
5310         default:
5311           emitpcode(POC_MOVLW, popGetLit(t));
5312           emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5313           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5314           pic14_emitcode("movlw","0x%x",t);
5315           pic14_emitcode("xorwf","%s,w",
5316                          aopGet(AOP(left),offset,FALSE,FALSE));
5317           pic14_emitcode("movwf","%s",
5318                          aopGet(AOP(result),offset,FALSE,FALSE));
5319
5320         }
5321         continue;
5322       }
5323
5324       // faster than result <- left, anl result,right
5325       // and better if result is SFR
5326       if (AOP_TYPE(left) == AOP_ACC) {
5327         emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
5328         pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5329       } else {
5330         emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
5331         emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
5332         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5333         pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5334       }
5335       if ( AOP_TYPE(result) != AOP_ACC){
5336         emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
5337         pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5338       }
5339     }
5340   }
5341
5342   release :
5343     freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5344   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5345   freeAsmop(result,NULL,ic,TRUE);     
5346 }
5347
5348 /*-----------------------------------------------------------------*/
5349 /* genInline - write the inline code out                           */
5350 /*-----------------------------------------------------------------*/
5351 static void genInline (iCode *ic)
5352 {
5353     char *buffer, *bp, *bp1;
5354     
5355     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5356
5357     _G.inLine += (!options.asmpeep);
5358
5359     buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5360     strcpy(buffer,IC_INLINE(ic));
5361
5362     /* emit each line as a code */
5363     while (*bp) {
5364         if (*bp == '\n') {
5365             *bp++ = '\0';
5366             pic14_emitcode(bp1,"");
5367             bp1 = bp;
5368         } else {
5369             if (*bp == ':') {
5370                 bp++;
5371                 *bp = '\0';
5372                 bp++;
5373                 pic14_emitcode(bp1,"");
5374                 bp1 = bp;
5375             } else
5376                 bp++;
5377         }
5378     }
5379     if (bp1 != bp)
5380         pic14_emitcode(bp1,"");
5381     /*     pic14_emitcode("",buffer); */
5382     _G.inLine -= (!options.asmpeep);
5383 }
5384
5385 /*-----------------------------------------------------------------*/
5386 /* genRRC - rotate right with carry                                */
5387 /*-----------------------------------------------------------------*/
5388 static void genRRC (iCode *ic)
5389 {
5390     operand *left , *result ;
5391     int size, offset = 0;
5392     char *l;    
5393
5394     /* rotate right with carry */
5395     left = IC_LEFT(ic);
5396     result=IC_RESULT(ic);
5397     aopOp (left,ic,FALSE);
5398     aopOp (result,ic,FALSE);
5399
5400     /* move it to the result */
5401     size = AOP_SIZE(result);    
5402     offset = size - 1 ;
5403     CLRC;
5404     while (size--) {
5405         l = aopGet(AOP(left),offset,FALSE,FALSE);
5406         MOVA(l);
5407         pic14_emitcode("rrc","a");
5408         if (AOP_SIZE(result) > 1)
5409             aopPut(AOP(result),"a",offset--);
5410     }
5411     /* now we need to put the carry into the
5412     highest order byte of the result */
5413     if (AOP_SIZE(result) > 1) {
5414         l = aopGet(AOP(result),AOP_SIZE(result)-1,FALSE,FALSE);
5415         MOVA(l);
5416     }
5417     pic14_emitcode("mov","acc.7,c");
5418     aopPut(AOP(result),"a",AOP_SIZE(result)-1);
5419     freeAsmop(left,NULL,ic,TRUE);
5420     freeAsmop(result,NULL,ic,TRUE);
5421 }
5422
5423 /*-----------------------------------------------------------------*/
5424 /* genRLC - generate code for rotate left with carry               */
5425 /*-----------------------------------------------------------------*/
5426 static void genRLC (iCode *ic)
5427 {    
5428     operand *left , *result ;
5429     int size, offset = 0;
5430     char *l;    
5431
5432     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5433     /* rotate right with carry */
5434     left = IC_LEFT(ic);
5435     result=IC_RESULT(ic);
5436     aopOp (left,ic,FALSE);
5437     aopOp (result,ic,FALSE);
5438
5439     /* move it to the result */
5440     size = AOP_SIZE(result);    
5441     offset = 0 ;
5442     if (size--) {
5443         l = aopGet(AOP(left),offset,FALSE,FALSE);
5444         MOVA(l);
5445         pic14_emitcode("add","a,acc");
5446         if (AOP_SIZE(result) > 1)
5447             aopPut(AOP(result),"a",offset++);
5448         while (size--) {
5449             l = aopGet(AOP(left),offset,FALSE,FALSE);
5450             MOVA(l);
5451             pic14_emitcode("rlc","a");
5452             if (AOP_SIZE(result) > 1)
5453                 aopPut(AOP(result),"a",offset++);
5454         }
5455     }
5456     /* now we need to put the carry into the
5457     highest order byte of the result */
5458     if (AOP_SIZE(result) > 1) {
5459         l = aopGet(AOP(result),0,FALSE,FALSE);
5460         MOVA(l);
5461     }
5462     pic14_emitcode("mov","acc.0,c");
5463     aopPut(AOP(result),"a",0);
5464     freeAsmop(left,NULL,ic,TRUE);
5465     freeAsmop(result,NULL,ic,TRUE);
5466 }
5467
5468 /*-----------------------------------------------------------------*/
5469 /* genGetHbit - generates code get highest order bit               */
5470 /*-----------------------------------------------------------------*/
5471 static void genGetHbit (iCode *ic)
5472 {
5473     operand *left, *result;
5474     left = IC_LEFT(ic);
5475     result=IC_RESULT(ic);
5476     aopOp (left,ic,FALSE);
5477     aopOp (result,ic,FALSE);
5478
5479     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5480     /* get the highest order byte into a */
5481     MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5482     if(AOP_TYPE(result) == AOP_CRY){
5483         pic14_emitcode("rlc","a");
5484         pic14_outBitC(result);
5485     }
5486     else{
5487         pic14_emitcode("rl","a");
5488         pic14_emitcode("anl","a,#0x01");
5489         pic14_outAcc(result);
5490     }
5491
5492
5493     freeAsmop(left,NULL,ic,TRUE);
5494     freeAsmop(result,NULL,ic,TRUE);
5495 }
5496
5497 /*-----------------------------------------------------------------*/
5498 /* AccRol - rotate left accumulator by known count                 */
5499 /*-----------------------------------------------------------------*/
5500 static void AccRol (int shCount)
5501 {
5502     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5503     shCount &= 0x0007;              // shCount : 0..7
5504     switch(shCount){
5505         case 0 :
5506             break;
5507         case 1 :
5508             pic14_emitcode("rl","a");
5509             break;
5510         case 2 :
5511             pic14_emitcode("rl","a");
5512             pic14_emitcode("rl","a");
5513             break;
5514         case 3 :
5515             pic14_emitcode("swap","a");
5516             pic14_emitcode("rr","a");
5517             break;
5518         case 4 :
5519             pic14_emitcode("swap","a");
5520             break;
5521         case 5 :
5522             pic14_emitcode("swap","a");
5523             pic14_emitcode("rl","a");
5524             break;
5525         case 6 :
5526             pic14_emitcode("rr","a");
5527             pic14_emitcode("rr","a");
5528             break;
5529         case 7 :
5530             pic14_emitcode("rr","a");
5531             break;
5532     }
5533 }
5534
5535 /*-----------------------------------------------------------------*/
5536 /* AccLsh - left shift accumulator by known count                  */
5537 /*-----------------------------------------------------------------*/
5538 static void AccLsh (int shCount)
5539 {
5540     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5541     if(shCount != 0){
5542         if(shCount == 1)
5543             pic14_emitcode("add","a,acc");
5544         else 
5545             if(shCount == 2) {
5546             pic14_emitcode("add","a,acc");
5547             pic14_emitcode("add","a,acc");
5548         } else {
5549             /* rotate left accumulator */
5550             AccRol(shCount);
5551             /* and kill the lower order bits */
5552             pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
5553         }
5554     }
5555 }
5556
5557 /*-----------------------------------------------------------------*/
5558 /* AccRsh - right shift accumulator by known count                 */
5559 /*-----------------------------------------------------------------*/
5560 static void AccRsh (int shCount)
5561 {
5562     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5563     if(shCount != 0){
5564         if(shCount == 1){
5565             CLRC;
5566             pic14_emitcode("rrc","a");
5567         } else {
5568             /* rotate right accumulator */
5569             AccRol(8 - shCount);
5570             /* and kill the higher order bits */
5571             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5572         }
5573     }
5574 }
5575
5576 #if 0
5577 /*-----------------------------------------------------------------*/
5578 /* AccSRsh - signed right shift accumulator by known count                 */
5579 /*-----------------------------------------------------------------*/
5580 static void AccSRsh (int shCount)
5581 {
5582     symbol *tlbl ;
5583     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5584     if(shCount != 0){
5585         if(shCount == 1){
5586             pic14_emitcode("mov","c,acc.7");
5587             pic14_emitcode("rrc","a");
5588         } else if(shCount == 2){
5589             pic14_emitcode("mov","c,acc.7");
5590             pic14_emitcode("rrc","a");
5591             pic14_emitcode("mov","c,acc.7");
5592             pic14_emitcode("rrc","a");
5593         } else {
5594             tlbl = newiTempLabel(NULL);
5595             /* rotate right accumulator */
5596             AccRol(8 - shCount);
5597             /* and kill the higher order bits */
5598             pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
5599             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
5600             pic14_emitcode("orl","a,#0x%02x",
5601                      (unsigned char)~SRMask[shCount]);
5602             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5603         }
5604     }
5605 }
5606 #endif
5607 /*-----------------------------------------------------------------*/
5608 /* shiftR1Left2Result - shift right one byte from left to result   */
5609 /*-----------------------------------------------------------------*/
5610 static void shiftR1Left2ResultSigned (operand *left, int offl,
5611                                 operand *result, int offr,
5612                                 int shCount)
5613 {
5614   int same;
5615
5616   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5617
5618   same = (left == result) || (AOP(left) == AOP(result));
5619
5620   switch(shCount) {
5621   case 1:
5622     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5623     if(same) 
5624       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5625     else {
5626       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5627       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5628     }
5629
5630     break;
5631
5632   default:
5633     break;
5634   }
5635 }
5636
5637 /*-----------------------------------------------------------------*/
5638 /* shiftR1Left2Result - shift right one byte from left to result   */
5639 /*-----------------------------------------------------------------*/
5640 static void shiftR1Left2Result (operand *left, int offl,
5641                                 operand *result, int offr,
5642                                 int shCount, int sign)
5643 {
5644   int same;
5645
5646   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5647
5648   same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
5649
5650   /* Copy the msb into the carry if signed. */
5651   if(sign) {
5652     shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
5653     return;
5654   }
5655
5656
5657
5658   switch(shCount) {
5659   case 1:
5660     emitCLRC;
5661     if(same) 
5662       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5663     else {
5664       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5665       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5666     }
5667     break;
5668   case 2:
5669     emitCLRC;
5670     if(same) {
5671       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5672     } else {
5673       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5674       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5675     }
5676     emitCLRC;
5677     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5678
5679     break;
5680   case 3:
5681     if(same) 
5682       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
5683     else {
5684       emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5685       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5686     }
5687
5688     emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
5689     emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
5690     emitpcode(POC_ANDLW, popGetLit(0x1f));
5691     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5692     break;
5693       
5694   case 4:
5695     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5696     emitpcode(POC_ANDLW, popGetLit(0x0f));
5697     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5698     break;
5699
5700   case 5:
5701     emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
5702     emitpcode(POC_ANDLW, popGetLit(0x0f));
5703     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5704     emitCLRC;
5705     emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
5706
5707     break;
5708   case 6:
5709
5710     emitpcode(POC_RLFW,  popGet(AOP(left),offl,FALSE,FALSE));
5711     emitpcode(POC_ANDLW, popGetLit(0x80));
5712     emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5713     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
5714     emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
5715     break;
5716
5717   case 7:
5718
5719     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5720     emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5721     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5722
5723     break;
5724
5725   default:
5726     break;
5727   }
5728
5729
5730 #if 0
5731     
5732   MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
5733
5734   /* shift right accumulator */
5735   if(sign)
5736     AccSRsh(shCount);
5737   else
5738     AccRsh(shCount);
5739   aopPut(AOP(result),"a",offr);
5740 #endif
5741 }
5742
5743 /*-----------------------------------------------------------------*/
5744 /* shiftL1Left2Result - shift left one byte from left to result    */
5745 /*-----------------------------------------------------------------*/
5746 static void shiftL1Left2Result (operand *left, int offl,
5747                                 operand *result, int offr, int shCount)
5748 {
5749   int same;
5750
5751   //    char *l;
5752   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5753
5754   same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
5755   DEBUGpic14_emitcode ("; ***","same =  %d",same);
5756     //    l = aopGet(AOP(left),offl,FALSE,FALSE);
5757     //    MOVA(l);
5758     /* shift left accumulator */
5759     //AccLsh(shCount); // don't comment out just yet...
5760   //    aopPut(AOP(result),"a",offr);
5761
5762   switch(shCount) {
5763   case 1:
5764     /* Shift left 1 bit position */
5765     emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5766     if(same) {
5767       emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
5768     } else {
5769       emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
5770       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5771     }
5772     break;
5773   case 2:
5774     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5775     emitpcode(POC_ANDLW,popGetLit(0x7e));
5776     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5777     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5778     break;
5779   case 3:
5780     emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
5781     emitpcode(POC_ANDLW,popGetLit(0x3e));
5782     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5783     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5784     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5785     break;
5786   case 4:
5787     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5788     emitpcode(POC_ANDLW, popGetLit(0xf0));
5789     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5790     break;
5791   case 5:
5792     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5793     emitpcode(POC_ANDLW, popGetLit(0xf0));
5794     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5795     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5796     break;
5797   case 6:
5798     emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
5799     emitpcode(POC_ANDLW, popGetLit(0x30));
5800     emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
5801     emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
5802     emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
5803     break;
5804   case 7:
5805     emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
5806     emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
5807     emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
5808     break;
5809
5810   default:
5811     DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
5812   }
5813
5814 }
5815
5816 /*-----------------------------------------------------------------*/
5817 /* movLeft2Result - move byte from left to result                  */
5818 /*-----------------------------------------------------------------*/
5819 static void movLeft2Result (operand *left, int offl,
5820                             operand *result, int offr, int sign)
5821 {
5822     char *l;
5823     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5824     if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
5825         l = aopGet(AOP(left),offl,FALSE,FALSE);
5826
5827         if (*l == '@' && (IS_AOP_PREG(result))) {
5828             pic14_emitcode("mov","a,%s",l);
5829             aopPut(AOP(result),"a",offr);
5830         } else {
5831           if(!sign) {
5832             emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
5833             emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
5834
5835             //aopPut(AOP(result),l,offr);
5836           }else{
5837                 /* MSB sign in acc.7 ! */
5838                 if(pic14_getDataSize(left) == offl+1){
5839                     pic14_emitcode("mov","a,%s",l);
5840                     aopPut(AOP(result),"a",offr);
5841                 }
5842             }
5843         }
5844     }
5845 }
5846
5847 /*-----------------------------------------------------------------*/
5848 /* AccAXRrl1 - right rotate c->a:x->c by 1                         */
5849 /*-----------------------------------------------------------------*/
5850 static void AccAXRrl1 (char *x)
5851 {
5852     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5853     pic14_emitcode("rrc","a");
5854     pic14_emitcode("xch","a,%s", x);
5855     pic14_emitcode("rrc","a");
5856     pic14_emitcode("xch","a,%s", x);
5857 }
5858
5859 /*-----------------------------------------------------------------*/
5860 /* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
5861 /*-----------------------------------------------------------------*/
5862 static void AccAXLrl1 (char *x)
5863 {
5864     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5865     pic14_emitcode("xch","a,%s",x);
5866     pic14_emitcode("rlc","a");
5867     pic14_emitcode("xch","a,%s",x);
5868     pic14_emitcode("rlc","a");
5869 }
5870 #if 0
5871 /*-----------------------------------------------------------------*/
5872 /* AccAXLsh1 - left shift a:x<-0 by 1                              */
5873 /*-----------------------------------------------------------------*/
5874 static void AccAXLsh1 (char *x)
5875 {
5876     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5877     pic14_emitcode("xch","a,%s",x);
5878     pic14_emitcode("add","a,acc");
5879     pic14_emitcode("xch","a,%s",x);
5880     pic14_emitcode("rlc","a");
5881 }
5882 #endif
5883 #if 0
5884 /*-----------------------------------------------------------------*/
5885 /* AccAXLsh - left shift a:x by known count (0..7)                 */
5886 /*-----------------------------------------------------------------*/
5887 static void AccAXLsh (char *x, int shCount)
5888 {
5889     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5890     switch(shCount){
5891         case 0 :
5892             break;
5893         case 1 :
5894             AccAXLsh1(x);
5895             break;
5896         case 2 :
5897             AccAXLsh1(x);
5898             AccAXLsh1(x);
5899             break;
5900         case 3 :
5901         case 4 :
5902         case 5 :                        // AAAAABBB:CCCCCDDD
5903             AccRol(shCount);            // BBBAAAAA:CCCCCDDD
5904             pic14_emitcode("anl","a,#0x%02x",
5905                      SLMask[shCount]);  // BBB00000:CCCCCDDD
5906             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBB00000
5907             AccRol(shCount);            // DDDCCCCC:BBB00000
5908             pic14_emitcode("xch","a,%s",x);   // BBB00000:DDDCCCCC
5909             pic14_emitcode("xrl","a,%s",x);   // (BBB^DDD)CCCCC:DDDCCCCC
5910             pic14_emitcode("xch","a,%s",x);   // DDDCCCCC:(BBB^DDD)CCCCC
5911             pic14_emitcode("anl","a,#0x%02x",
5912                      SLMask[shCount]);  // DDD00000:(BBB^DDD)CCCCC
5913             pic14_emitcode("xch","a,%s",x);   // (BBB^DDD)CCCCC:DDD00000
5914             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:DDD00000            
5915             break;
5916         case 6 :                        // AAAAAABB:CCCCCCDD
5917             pic14_emitcode("anl","a,#0x%02x",
5918                      SRMask[shCount]);  // 000000BB:CCCCCCDD
5919             pic14_emitcode("mov","c,acc.0");  // c = B
5920             pic14_emitcode("xch","a,%s",x);   // CCCCCCDD:000000BB
5921             AccAXRrl1(x);               // BCCCCCCD:D000000B
5922             AccAXRrl1(x);               // BBCCCCCC:DD000000
5923             break;
5924         case 7 :                        // a:x <<= 7
5925             pic14_emitcode("anl","a,#0x%02x",
5926                      SRMask[shCount]);  // 0000000B:CCCCCCCD
5927             pic14_emitcode("mov","c,acc.0");  // c = B
5928             pic14_emitcode("xch","a,%s",x);   // CCCCCCCD:0000000B
5929             AccAXRrl1(x);               // BCCCCCCC:D0000000
5930             break;
5931         default :
5932             break;
5933     }
5934 }
5935 #endif
5936 #if 0
5937 /*-----------------------------------------------------------------*/
5938 /* AccAXRsh - right shift a:x known count (0..7)                   */
5939 /*-----------------------------------------------------------------*/
5940 static void AccAXRsh (char *x, int shCount)
5941 {   
5942     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5943     switch(shCount){
5944         case 0 :
5945             break;
5946         case 1 :
5947             CLRC;
5948             AccAXRrl1(x);               // 0->a:x
5949             break;
5950         case 2 :
5951             CLRC;
5952             AccAXRrl1(x);               // 0->a:x
5953             CLRC;
5954             AccAXRrl1(x);               // 0->a:x
5955             break;
5956         case 3 :
5957         case 4 :
5958         case 5 :                        // AAAAABBB:CCCCCDDD = a:x
5959             AccRol(8 - shCount);        // BBBAAAAA:DDDCCCCC
5960             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
5961             AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
5962             pic14_emitcode("anl","a,#0x%02x",
5963                      SRMask[shCount]);  // 000CCCCC:BBBAAAAA
5964             pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
5965             pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
5966             pic14_emitcode("anl","a,#0x%02x",
5967                      SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
5968             pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
5969             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
5970             pic14_emitcode("xch","a,%s",x);   // 000AAAAA:BBBCCCCC
5971             break;
5972         case 6 :                        // AABBBBBB:CCDDDDDD
5973             pic14_emitcode("mov","c,acc.7");
5974             AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
5975             AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
5976             pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
5977             pic14_emitcode("anl","a,#0x%02x",
5978                      SRMask[shCount]);  // 000000AA:BBBBBBCC
5979             break;
5980         case 7 :                        // ABBBBBBB:CDDDDDDD
5981             pic14_emitcode("mov","c,acc.7");  // c = A
5982             AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
5983             pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
5984             pic14_emitcode("anl","a,#0x%02x",
5985                      SRMask[shCount]);  // 0000000A:BBBBBBBC
5986             break;
5987         default :
5988             break;
5989     }
5990 }
5991 #endif
5992 /*-----------------------------------------------------------------*/
5993 /* AccAXRshS - right shift signed a:x known count (0..7)           */
5994 /*-----------------------------------------------------------------*/
5995 static void AccAXRshS (char *x, int shCount)
5996 {   
5997     symbol *tlbl ;
5998     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5999     switch(shCount){
6000         case 0 :
6001             break;
6002         case 1 :
6003             pic14_emitcode("mov","c,acc.7");
6004             AccAXRrl1(x);               // s->a:x
6005             break;
6006         case 2 :
6007             pic14_emitcode("mov","c,acc.7");
6008             AccAXRrl1(x);               // s->a:x
6009             pic14_emitcode("mov","c,acc.7");
6010             AccAXRrl1(x);               // s->a:x
6011             break;
6012         case 3 :
6013         case 4 :
6014         case 5 :                        // AAAAABBB:CCCCCDDD = a:x
6015             tlbl = newiTempLabel(NULL);
6016             AccRol(8 - shCount);        // BBBAAAAA:CCCCCDDD
6017             pic14_emitcode("xch","a,%s",x);   // CCCCCDDD:BBBAAAAA
6018             AccRol(8 - shCount);        // DDDCCCCC:BBBAAAAA
6019             pic14_emitcode("anl","a,#0x%02x",
6020                      SRMask[shCount]);  // 000CCCCC:BBBAAAAA
6021             pic14_emitcode("xrl","a,%s",x);   // BBB(CCCCC^AAAAA):BBBAAAAA
6022             pic14_emitcode("xch","a,%s",x);   // BBBAAAAA:BBB(CCCCC^AAAAA)
6023             pic14_emitcode("anl","a,#0x%02x",
6024                      SRMask[shCount]);  // 000AAAAA:BBB(CCCCC^AAAAA)
6025             pic14_emitcode("xch","a,%s",x);   // BBB(CCCCC^AAAAA):000AAAAA
6026             pic14_emitcode("xrl","a,%s",x);   // BBBCCCCC:000AAAAA
6027             pic14_emitcode("xch","a,%s",x);   // 000SAAAA:BBBCCCCC
6028             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
6029             pic14_emitcode("orl","a,#0x%02x",
6030                      (unsigned char)~SRMask[shCount]);  // 111AAAAA:BBBCCCCC
6031             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6032             break;                      // SSSSAAAA:BBBCCCCC
6033         case 6 :                        // AABBBBBB:CCDDDDDD
6034             tlbl = newiTempLabel(NULL);
6035             pic14_emitcode("mov","c,acc.7");
6036             AccAXLrl1(x);               // ABBBBBBC:CDDDDDDA
6037             AccAXLrl1(x);               // BBBBBBCC:DDDDDDAA
6038             pic14_emitcode("xch","a,%s",x);   // DDDDDDAA:BBBBBBCC
6039             pic14_emitcode("anl","a,#0x%02x",
6040                      SRMask[shCount]);  // 000000AA:BBBBBBCC
6041             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
6042             pic14_emitcode("orl","a,#0x%02x",
6043                      (unsigned char)~SRMask[shCount]);  // 111111AA:BBBBBBCC
6044             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6045             break;
6046         case 7 :                        // ABBBBBBB:CDDDDDDD
6047             tlbl = newiTempLabel(NULL);
6048             pic14_emitcode("mov","c,acc.7");  // c = A
6049             AccAXLrl1(x);               // BBBBBBBC:DDDDDDDA
6050             pic14_emitcode("xch","a,%s",x);   // DDDDDDDA:BBBBBBCC
6051             pic14_emitcode("anl","a,#0x%02x",
6052                      SRMask[shCount]);  // 0000000A:BBBBBBBC
6053             pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); 
6054             pic14_emitcode("orl","a,#0x%02x",
6055                      (unsigned char)~SRMask[shCount]);  // 1111111A:BBBBBBBC
6056             pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6057             break;
6058         default :
6059             break;
6060     }
6061 }
6062
6063 /*-----------------------------------------------------------------*/
6064 /* shiftL2Left2Result - shift left two bytes from left to result   */
6065 /*-----------------------------------------------------------------*/
6066 static void shiftL2Left2Result (operand *left, int offl,
6067                                 operand *result, int offr, int shCount)
6068 {
6069
6070
6071   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6072
6073   if(pic14_sameRegs(AOP(result), AOP(left))) {
6074     switch(shCount) {
6075     case 0:
6076       break;
6077     case 1:
6078     case 2:
6079     case 3:
6080
6081       emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
6082       emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
6083       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6084
6085       while(--shCount) {
6086         emitCLRC;
6087         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6088         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6089       }
6090
6091       break;
6092     case 4:
6093     case 5:
6094       emitpcode(POC_MOVLW, popGetLit(0x0f));
6095       emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6096       emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6097       emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6098       emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
6099       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6100       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6101       if(shCount >=5) {
6102         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6103         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6104       }
6105       break;
6106     case 6:
6107       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6108       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6109       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6110       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6111       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6112       emitpcode(POC_ANDLW,popGetLit(0xc0));
6113       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6114       emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6115       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6116       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6117       break;
6118     case 7:
6119       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6120       emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
6121       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6122       emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6123       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6124     }
6125
6126   } else {
6127     switch(shCount) {
6128     case 0:
6129       break;
6130     case 1:
6131     case 2:
6132     case 3:
6133       /* note, use a mov/add for the shift since the mov has a
6134          chance of getting optimized out */
6135       emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
6136       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6137       emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6138       emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6139       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6140
6141       while(--shCount) {
6142         emitCLRC;
6143         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6144         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6145       }
6146       break;
6147
6148     case 4:
6149     case 5:
6150       emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6151       emitpcode(POC_ANDLW, popGetLit(0xF0));
6152       emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6153       emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
6154       emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6155       emitpcode(POC_ANDLW, popGetLit(0xF0));
6156       emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
6157       emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6158
6159
6160       if(shCount == 5) {
6161         emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
6162         emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6163       }
6164       break;
6165     case 6:
6166       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6167       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6168       emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
6169       emitpcode(POC_MOVWF,  popGet(AOP(result),offr,FALSE,FALSE));
6170
6171       emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6172       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6173       emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6174       emitpcode(POC_ANDLW,popGetLit(0xc0));
6175       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6176       emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
6177       emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
6178       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6179       break;
6180     case 7:
6181       emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6182       emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6183       emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6184       emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
6185       emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
6186     }
6187   }
6188
6189 }
6190 /*-----------------------------------------------------------------*/
6191 /* shiftR2Left2Result - shift right two bytes from left to result  */
6192 /*-----------------------------------------------------------------*/
6193 static void shiftR2Left2Result (operand *left, int offl,
6194                                 operand *result, int offr,
6195                                 int shCount, int sign)
6196 {
6197   int same=0;
6198
6199   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6200   same = pic14_sameRegs(AOP(result), AOP(left));
6201
6202   if(same && ((offl + MSB16) == offr)){
6203     same=1;
6204     /* don't crash result[offr] */
6205     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6206     pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6207   } else {
6208     movLeft2Result(left,offl, result, offr, 0);
6209     MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6210   }
6211   /* a:x >> shCount (x = lsb(result))*/
6212   if(sign)
6213     AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6214   else {
6215     //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6216     
6217     switch(shCount) {
6218     case 0:
6219       break;
6220     case 1:
6221     case 2:
6222     case 3:
6223       emitCLRC;
6224       if(same) {
6225         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6226         emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6227       } else {
6228
6229         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6230         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6231         emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
6232         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6233       }
6234
6235       while(--shCount) {
6236         emitCLRC;
6237         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6238         emitpcode(POC_RRF,popGet(AOP(result),offr,FALSE,FALSE));
6239       }
6240       break;
6241     case 4:
6242     case 5:
6243       if(same) {
6244
6245         emitpcode(POC_MOVLW, popGetLit(0xf0));
6246         emitpcode(POC_ANDWF, popGet(AOP(result),offr,FALSE,FALSE));
6247         emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
6248
6249         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6250         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6251         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6252         emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6253       } else {
6254         emitpcode(POC_SWAPF, popGet(AOP(left),offl,FALSE,FALSE));
6255         emitpcode(POC_ANDLW, popGetLit(0x0f));
6256         emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
6257
6258         emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6259         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6260         emitpcode(POC_ANDLW, popGetLit(0xf0));
6261         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6262         emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
6263       }
6264
6265       if(shCount >=5) {
6266         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6267         emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
6268       }
6269
6270       break;
6271
6272     case 6:
6273       if(same) {
6274
6275         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6276         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6277
6278         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6279         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6280         emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6281         emitpcode(POC_ANDLW,popGetLit(0x03));
6282         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6283         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6284         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6285         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6286       } else {
6287         emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6288         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6289         emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16,FALSE,FALSE));
6290         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6291         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6292         emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
6293         emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE));
6294         emitpcode(POC_ANDLW,popGetLit(0x03));
6295         emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6296       }
6297
6298       break;
6299     case 7:
6300       emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
6301       emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
6302       emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
6303       emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6304       emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
6305     }
6306   }
6307 }
6308
6309 /*-----------------------------------------------------------------*/
6310 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6311 /*-----------------------------------------------------------------*/
6312 static void shiftLLeftOrResult (operand *left, int offl,
6313                                 operand *result, int offr, int shCount)
6314 {
6315     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6316     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6317     /* shift left accumulator */
6318     AccLsh(shCount);
6319     /* or with result */
6320     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6321     /* back to result */
6322     aopPut(AOP(result),"a",offr);
6323 }
6324
6325 /*-----------------------------------------------------------------*/
6326 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6327 /*-----------------------------------------------------------------*/
6328 static void shiftRLeftOrResult (operand *left, int offl,
6329                                 operand *result, int offr, int shCount)
6330 {
6331     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6332     MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6333     /* shift right accumulator */
6334     AccRsh(shCount);
6335     /* or with result */
6336     pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6337     /* back to result */
6338     aopPut(AOP(result),"a",offr);
6339 }
6340
6341 /*-----------------------------------------------------------------*/
6342 /* genlshOne - left shift a one byte quantity by known count       */
6343 /*-----------------------------------------------------------------*/
6344 static void genlshOne (operand *result, operand *left, int shCount)
6345 {       
6346     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6347     shiftL1Left2Result(left, LSB, result, LSB, shCount);
6348 }
6349
6350 /*-----------------------------------------------------------------*/
6351 /* genlshTwo - left shift two bytes by known amount != 0           */
6352 /*-----------------------------------------------------------------*/
6353 static void genlshTwo (operand *result,operand *left, int shCount)
6354 {
6355     int size;
6356     
6357     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6358     size = pic14_getDataSize(result);
6359
6360     /* if shCount >= 8 */
6361     if (shCount >= 8) {
6362         shCount -= 8 ;
6363
6364         if (size > 1){
6365             if (shCount)
6366                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6367             else 
6368                 movLeft2Result(left, LSB, result, MSB16, 0);
6369         }
6370         emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
6371     }
6372
6373     /*  1 <= shCount <= 7 */
6374     else {  
6375         if(size == 1)
6376             shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6377         else 
6378             shiftL2Left2Result(left, LSB, result, LSB, shCount);
6379     }
6380 }
6381
6382 /*-----------------------------------------------------------------*/
6383 /* shiftLLong - shift left one long from left to result            */
6384 /* offl = LSB or MSB16                                             */
6385 /*-----------------------------------------------------------------*/
6386 static void shiftLLong (operand *left, operand *result, int offr )
6387 {
6388     char *l;
6389     int size = AOP_SIZE(result);
6390
6391     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6392     if(size >= LSB+offr){
6393         l = aopGet(AOP(left),LSB,FALSE,FALSE);
6394         MOVA(l);
6395         pic14_emitcode("add","a,acc");
6396         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6397             size >= MSB16+offr && offr != LSB )
6398             pic14_emitcode("xch","a,%s",
6399                      aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6400         else        
6401             aopPut(AOP(result),"a",LSB+offr);
6402     }
6403
6404     if(size >= MSB16+offr){
6405         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6406             l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6407             MOVA(l);
6408         }
6409         pic14_emitcode("rlc","a");
6410         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6411             size >= MSB24+offr && offr != LSB)
6412             pic14_emitcode("xch","a,%s",
6413                      aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6414         else        
6415             aopPut(AOP(result),"a",MSB16+offr);
6416     }
6417
6418     if(size >= MSB24+offr){
6419         if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6420             l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6421             MOVA(l);
6422         }
6423         pic14_emitcode("rlc","a");
6424         if (pic14_sameRegs(AOP(left),AOP(result)) && 
6425             size >= MSB32+offr && offr != LSB )
6426             pic14_emitcode("xch","a,%s",
6427                      aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6428         else        
6429             aopPut(AOP(result),"a",MSB24+offr);
6430     }
6431
6432     if(size > MSB32+offr){
6433         if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6434             l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6435             MOVA(l);    
6436         }
6437         pic14_emitcode("rlc","a");
6438         aopPut(AOP(result),"a",MSB32+offr);
6439     }
6440     if(offr != LSB)
6441         aopPut(AOP(result),zero,LSB);       
6442 }
6443
6444 /*-----------------------------------------------------------------*/
6445 /* genlshFour - shift four byte by a known amount != 0             */
6446 /*-----------------------------------------------------------------*/
6447 static void genlshFour (operand *result, operand *left, int shCount)
6448 {
6449     int size;
6450
6451     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6452     size = AOP_SIZE(result);
6453
6454     /* if shifting more that 3 bytes */
6455     if (shCount >= 24 ) {
6456         shCount -= 24;
6457         if (shCount)
6458             /* lowest order of left goes to the highest
6459             order of the destination */
6460             shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6461         else
6462             movLeft2Result(left, LSB, result, MSB32, 0);
6463         aopPut(AOP(result),zero,LSB);
6464         aopPut(AOP(result),zero,MSB16);
6465         aopPut(AOP(result),zero,MSB32);
6466         return;
6467     }
6468
6469     /* more than two bytes */
6470     else if ( shCount >= 16 ) {
6471         /* lower order two bytes goes to higher order two bytes */
6472         shCount -= 16;
6473         /* if some more remaining */
6474         if (shCount)
6475             shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6476         else {
6477             movLeft2Result(left, MSB16, result, MSB32, 0);
6478             movLeft2Result(left, LSB, result, MSB24, 0);
6479         }
6480         aopPut(AOP(result),zero,MSB16);
6481         aopPut(AOP(result),zero,LSB);
6482         return;
6483     }    
6484
6485     /* if more than 1 byte */
6486     else if ( shCount >= 8 ) {
6487         /* lower order three bytes goes to higher order  three bytes */
6488         shCount -= 8;
6489         if(size == 2){
6490             if(shCount)
6491                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6492             else
6493                 movLeft2Result(left, LSB, result, MSB16, 0);
6494         }
6495         else{   /* size = 4 */
6496             if(shCount == 0){
6497                 movLeft2Result(left, MSB24, result, MSB32, 0);
6498                 movLeft2Result(left, MSB16, result, MSB24, 0);
6499                 movLeft2Result(left, LSB, result, MSB16, 0);
6500                 aopPut(AOP(result),zero,LSB);
6501             }
6502             else if(shCount == 1)
6503                 shiftLLong(left, result, MSB16);
6504             else{
6505                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6506                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6507                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6508                 aopPut(AOP(result),zero,LSB);
6509             }
6510         }
6511     }
6512
6513     /* 1 <= shCount <= 7 */
6514     else if(shCount <= 2){
6515         shiftLLong(left, result, LSB);
6516         if(shCount == 2)
6517             shiftLLong(result, result, LSB);
6518     }
6519     /* 3 <= shCount <= 7, optimize */
6520     else{
6521         shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6522         shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6523         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6524     }
6525 }
6526
6527 /*-----------------------------------------------------------------*/
6528 /* genLeftShiftLiteral - left shifting by known count              */
6529 /*-----------------------------------------------------------------*/
6530 static void genLeftShiftLiteral (operand *left,
6531                                  operand *right,
6532                                  operand *result,
6533                                  iCode *ic)
6534 {    
6535     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6536     int size;
6537
6538     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6539     freeAsmop(right,NULL,ic,TRUE);
6540
6541     aopOp(left,ic,FALSE);
6542     aopOp(result,ic,FALSE);
6543
6544     size = getSize(operandType(result));
6545
6546 #if VIEW_SIZE
6547     pic14_emitcode("; shift left ","result %d, left %d",size,
6548              AOP_SIZE(left));
6549 #endif
6550
6551     /* I suppose that the left size >= result size */
6552     if(shCount == 0){
6553         while(size--){
6554             movLeft2Result(left, size, result, size, 0);
6555         }
6556     }
6557
6558     else if(shCount >= (size * 8))
6559         while(size--)
6560             aopPut(AOP(result),zero,size);
6561     else{
6562         switch (size) {
6563             case 1:
6564                 genlshOne (result,left,shCount);
6565                 break;
6566
6567             case 2:
6568             case 3:
6569                 genlshTwo (result,left,shCount);
6570                 break;
6571
6572             case 4:
6573                 genlshFour (result,left,shCount);
6574                 break;
6575         }
6576     }
6577     freeAsmop(left,NULL,ic,TRUE);
6578     freeAsmop(result,NULL,ic,TRUE);
6579 }
6580
6581 /*-----------------------------------------------------------------*/
6582 /* genLeftShift - generates code for left shifting                 */
6583 /*-----------------------------------------------------------------*/
6584 static void genLeftShift (iCode *ic)
6585 {
6586     operand *left,*right, *result;
6587     int size, offset;
6588     char *l;
6589     symbol *tlbl , *tlbl1;
6590
6591     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6592
6593     right = IC_RIGHT(ic);
6594     left  = IC_LEFT(ic);
6595     result = IC_RESULT(ic);
6596
6597     aopOp(right,ic,FALSE);
6598
6599     /* if the shift count is known then do it 
6600     as efficiently as possible */
6601     if (AOP_TYPE(right) == AOP_LIT) {
6602         genLeftShiftLiteral (left,right,result,ic);
6603         return ;
6604     }
6605
6606     /* shift count is unknown then we have to form 
6607     a loop get the loop count in B : Note: we take
6608     only the lower order byte since shifting
6609     more that 32 bits make no sense anyway, ( the
6610     largest size of an object can be only 32 bits ) */  
6611
6612     
6613     aopOp(left,ic,FALSE);
6614     aopOp(result,ic,FALSE);
6615
6616     /* now move the left to the result if they are not the
6617     same */
6618     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6619         AOP_SIZE(result) > 1) {
6620
6621         size = AOP_SIZE(result);
6622         offset=0;
6623         while (size--) {
6624             l = aopGet(AOP(left),offset,FALSE,TRUE);
6625             if (*l == '@' && (IS_AOP_PREG(result))) {
6626
6627                 pic14_emitcode("mov","a,%s",l);
6628                 aopPut(AOP(result),"a",offset);
6629             } else
6630                 aopPut(AOP(result),l,offset);
6631             offset++;
6632         }
6633     }
6634
6635     size = AOP_SIZE(result);
6636
6637     /* if it is only one byte then */
6638     if (size == 1) {
6639       if(optimized_for_speed) {
6640         emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
6641         emitpcode(POC_ANDLW,  popGetLit(0xf0));
6642         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6643         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
6644         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
6645         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6646         emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
6647         emitpcode(POC_RLFW,   popGet(AOP(result),0,FALSE,FALSE));
6648         emitpcode(POC_ANDLW,  popGetLit(0xfe));
6649         emitpcode(POC_ADDFW,  popGet(AOP(result),0,FALSE,FALSE));
6650         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6651         emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
6652       } else {
6653
6654         tlbl = newiTempLabel(NULL);
6655         if (!pic14_sameRegs(AOP(left),AOP(result))) {
6656           emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
6657           emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
6658         }
6659
6660         emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
6661         emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
6662         emitpLabel(tlbl->key);
6663         emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
6664         emitpcode(POC_ADDLW,  popGetLit(1));
6665         emitSKPC;
6666         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6667       }
6668       goto release ;
6669     }
6670     
6671
6672     tlbl = newiTempLabel(NULL);
6673     offset = 0 ;   
6674     tlbl1 = newiTempLabel(NULL);
6675
6676     reAdjustPreg(AOP(result));    
6677     
6678     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
6679     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
6680     l = aopGet(AOP(result),offset,FALSE,FALSE);
6681     MOVA(l);
6682     pic14_emitcode("add","a,acc");         
6683     aopPut(AOP(result),"a",offset++);
6684     while (--size) {
6685         l = aopGet(AOP(result),offset,FALSE,FALSE);
6686         MOVA(l);
6687         pic14_emitcode("rlc","a");         
6688         aopPut(AOP(result),"a",offset++);
6689     }
6690     reAdjustPreg(AOP(result));
6691
6692     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6693     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6694 release:
6695     freeAsmop (right,NULL,ic,TRUE);
6696     freeAsmop(left,NULL,ic,TRUE);
6697     freeAsmop(result,NULL,ic,TRUE);
6698 }
6699
6700 /*-----------------------------------------------------------------*/
6701 /* genrshOne - right shift a one byte quantity by known count      */
6702 /*-----------------------------------------------------------------*/
6703 static void genrshOne (operand *result, operand *left,
6704                        int shCount, int sign)
6705 {
6706     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6707     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
6708 }
6709
6710 /*-----------------------------------------------------------------*/
6711 /* genrshTwo - right shift two bytes by known amount != 0          */
6712 /*-----------------------------------------------------------------*/
6713 static void genrshTwo (operand *result,operand *left,
6714                        int shCount, int sign)
6715 {
6716     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6717     /* if shCount >= 8 */
6718     if (shCount >= 8) {
6719         shCount -= 8 ;
6720         if (shCount)
6721             shiftR1Left2Result(left, MSB16, result, LSB,
6722                                shCount, sign);
6723         else 
6724             movLeft2Result(left, MSB16, result, LSB, sign);
6725         if(sign)
6726           addSign(result, MSB16, sign);
6727         else
6728           emitpcode(POC_CLRF,popGet(AOP(result),MSB16,FALSE,FALSE));
6729
6730     }
6731
6732     /*  1 <= shCount <= 7 */
6733     else
6734         shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
6735 }
6736
6737 /*-----------------------------------------------------------------*/
6738 /* shiftRLong - shift right one long from left to result           */
6739 /* offl = LSB or MSB16                                             */
6740 /*-----------------------------------------------------------------*/
6741 static void shiftRLong (operand *left, int offl,
6742                         operand *result, int sign)
6743 {
6744     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6745     if(!sign)
6746         pic14_emitcode("clr","c");
6747     MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
6748     if(sign)
6749         pic14_emitcode("mov","c,acc.7");
6750     pic14_emitcode("rrc","a");
6751     aopPut(AOP(result),"a",MSB32-offl);
6752     if(offl == MSB16)
6753         /* add sign of "a" */
6754         addSign(result, MSB32, sign);
6755
6756     MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
6757     pic14_emitcode("rrc","a");
6758     aopPut(AOP(result),"a",MSB24-offl);
6759
6760     MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
6761     pic14_emitcode("rrc","a");
6762     aopPut(AOP(result),"a",MSB16-offl);
6763
6764     if(offl == LSB){
6765         MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
6766         pic14_emitcode("rrc","a");
6767         aopPut(AOP(result),"a",LSB);
6768     }
6769 }
6770
6771 /*-----------------------------------------------------------------*/
6772 /* genrshFour - shift four byte by a known amount != 0             */
6773 /*-----------------------------------------------------------------*/
6774 static void genrshFour (operand *result, operand *left,
6775                         int shCount, int sign)
6776 {
6777     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6778     /* if shifting more that 3 bytes */
6779     if(shCount >= 24 ) {
6780         shCount -= 24;
6781         if(shCount)
6782             shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
6783         else
6784             movLeft2Result(left, MSB32, result, LSB, sign);
6785         addSign(result, MSB16, sign);
6786     }
6787     else if(shCount >= 16){
6788         shCount -= 16;
6789         if(shCount)
6790             shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
6791         else{
6792             movLeft2Result(left, MSB24, result, LSB, 0);
6793             movLeft2Result(left, MSB32, result, MSB16, sign);
6794         }
6795         addSign(result, MSB24, sign);
6796     }
6797     else if(shCount >= 8){
6798         shCount -= 8;
6799         if(shCount == 1)
6800             shiftRLong(left, MSB16, result, sign);
6801         else if(shCount == 0){
6802             movLeft2Result(left, MSB16, result, LSB, 0);
6803             movLeft2Result(left, MSB24, result, MSB16, 0);
6804             movLeft2Result(left, MSB32, result, MSB24, sign);
6805             addSign(result, MSB32, sign);
6806         }
6807         else{
6808             shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
6809             shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
6810             /* the last shift is signed */
6811             shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
6812             addSign(result, MSB32, sign);
6813         }
6814     }
6815     else{   /* 1 <= shCount <= 7 */
6816         if(shCount <= 2){
6817             shiftRLong(left, LSB, result, sign);
6818             if(shCount == 2)
6819                 shiftRLong(result, LSB, result, sign);
6820         }
6821         else{
6822             shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
6823             shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
6824             shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
6825         }
6826     }
6827 }
6828
6829 /*-----------------------------------------------------------------*/
6830 /* genRightShiftLiteral - right shifting by known count            */
6831 /*-----------------------------------------------------------------*/
6832 static void genRightShiftLiteral (operand *left,
6833                                   operand *right,
6834                                   operand *result,
6835                                   iCode *ic,
6836                                   int sign)
6837 {    
6838     int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6839     int size;
6840
6841     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6842     freeAsmop(right,NULL,ic,TRUE);
6843
6844     aopOp(left,ic,FALSE);
6845     aopOp(result,ic,FALSE);
6846
6847 #if VIEW_SIZE
6848     pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
6849              AOP_SIZE(left));
6850 #endif
6851
6852     size = pic14_getDataSize(left);
6853     /* test the LEFT size !!! */
6854
6855     /* I suppose that the left size >= result size */
6856     if(shCount == 0){
6857         size = pic14_getDataSize(result);
6858         while(size--)
6859             movLeft2Result(left, size, result, size, 0);
6860     }
6861
6862     else if(shCount >= (size * 8)){
6863         if(sign)
6864             /* get sign in acc.7 */
6865             MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
6866         addSign(result, LSB, sign);
6867     } else{
6868         switch (size) {
6869             case 1:
6870                 genrshOne (result,left,shCount,sign);
6871                 break;
6872
6873             case 2:
6874                 genrshTwo (result,left,shCount,sign);
6875                 break;
6876
6877             case 4:
6878                 genrshFour (result,left,shCount,sign);
6879                 break;
6880             default :
6881                 break;
6882         }
6883
6884         freeAsmop(left,NULL,ic,TRUE);
6885         freeAsmop(result,NULL,ic,TRUE);
6886     }
6887 }
6888
6889 /*-----------------------------------------------------------------*/
6890 /* genSignedRightShift - right shift of signed number              */
6891 /*-----------------------------------------------------------------*/
6892 static void genSignedRightShift (iCode *ic)
6893 {
6894     operand *right, *left, *result;
6895     int size, offset;
6896     char *l;
6897     symbol *tlbl, *tlbl1 ;
6898
6899     /* we do it the hard way put the shift count in b
6900     and loop thru preserving the sign */
6901     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6902
6903     right = IC_RIGHT(ic);
6904     left  = IC_LEFT(ic);
6905     result = IC_RESULT(ic);
6906
6907     aopOp(right,ic,FALSE);  
6908
6909
6910     if ( AOP_TYPE(right) == AOP_LIT) {
6911         genRightShiftLiteral (left,right,result,ic,1);
6912         return ;
6913     }
6914         /* shift count is unknown then we have to form 
6915        a loop get the loop count in B : Note: we take
6916        only the lower order byte since shifting
6917        more that 32 bits make no sense anyway, ( the
6918        largest size of an object can be only 32 bits ) */  
6919
6920     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
6921     pic14_emitcode("inc","b");
6922     freeAsmop (right,NULL,ic,TRUE);
6923     aopOp(left,ic,FALSE);
6924     aopOp(result,ic,FALSE);
6925
6926     /* now move the left to the result if they are not the
6927     same */
6928     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
6929         AOP_SIZE(result) > 1) {
6930
6931         size = AOP_SIZE(result);
6932         offset=0;
6933         while (size--) {
6934             l = aopGet(AOP(left),offset,FALSE,TRUE);
6935             if (*l == '@' && IS_AOP_PREG(result)) {
6936
6937                 pic14_emitcode("mov","a,%s",l);
6938                 aopPut(AOP(result),"a",offset);
6939             } else
6940                 aopPut(AOP(result),l,offset);
6941             offset++;
6942         }
6943     }
6944
6945     /* mov the highest order bit to OVR */    
6946     tlbl = newiTempLabel(NULL);
6947     tlbl1= newiTempLabel(NULL);
6948
6949     size = AOP_SIZE(result);
6950     offset = size - 1;
6951     pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
6952     pic14_emitcode("rlc","a");
6953     pic14_emitcode("mov","ov,c");
6954     /* if it is only one byte then */
6955     if (size == 1) {
6956         l = aopGet(AOP(left),0,FALSE,FALSE);
6957         MOVA(l);
6958         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6959         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6960         pic14_emitcode("mov","c,ov");
6961         pic14_emitcode("rrc","a");
6962         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6963         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6964         aopPut(AOP(result),"a",0);
6965         goto release ;
6966     }
6967
6968     reAdjustPreg(AOP(result));
6969     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
6970     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
6971     pic14_emitcode("mov","c,ov");
6972     while (size--) {
6973         l = aopGet(AOP(result),offset,FALSE,FALSE);
6974         MOVA(l);
6975         pic14_emitcode("rrc","a");         
6976         aopPut(AOP(result),"a",offset--);
6977     }
6978     reAdjustPreg(AOP(result));
6979     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
6980     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
6981
6982 release:
6983     freeAsmop(left,NULL,ic,TRUE);
6984     freeAsmop(result,NULL,ic,TRUE);
6985 }
6986
6987 /*-----------------------------------------------------------------*/
6988 /* genRightShift - generate code for right shifting                */
6989 /*-----------------------------------------------------------------*/
6990 static void genRightShift (iCode *ic)
6991 {
6992     operand *right, *left, *result;
6993     sym_link *retype ;
6994     int size, offset;
6995     char *l;
6996     symbol *tlbl, *tlbl1 ;
6997
6998     /* if signed then we do it the hard way preserve the
6999     sign bit moving it inwards */
7000     retype = getSpec(operandType(IC_RESULT(ic)));
7001     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7002
7003     if (!SPEC_USIGN(retype)) {
7004         genSignedRightShift (ic);
7005         return ;
7006     }
7007
7008     /* signed & unsigned types are treated the same : i.e. the
7009     signed is NOT propagated inwards : quoting from the
7010     ANSI - standard : "for E1 >> E2, is equivalent to division
7011     by 2**E2 if unsigned or if it has a non-negative value,
7012     otherwise the result is implementation defined ", MY definition
7013     is that the sign does not get propagated */
7014
7015     right = IC_RIGHT(ic);
7016     left  = IC_LEFT(ic);
7017     result = IC_RESULT(ic);
7018
7019     aopOp(right,ic,FALSE);
7020
7021     /* if the shift count is known then do it 
7022     as efficiently as possible */
7023     if (AOP_TYPE(right) == AOP_LIT) {
7024         genRightShiftLiteral (left,right,result,ic, 0);
7025         return ;
7026     }
7027
7028     /* shift count is unknown then we have to form 
7029     a loop get the loop count in B : Note: we take
7030     only the lower order byte since shifting
7031     more that 32 bits make no sense anyway, ( the
7032     largest size of an object can be only 32 bits ) */  
7033
7034     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7035     pic14_emitcode("inc","b");
7036     aopOp(left,ic,FALSE);
7037     aopOp(result,ic,FALSE);
7038
7039     /* now move the left to the result if they are not the
7040     same */
7041     if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7042         AOP_SIZE(result) > 1) {
7043
7044         size = AOP_SIZE(result);
7045         offset=0;
7046         while (size--) {
7047             l = aopGet(AOP(left),offset,FALSE,TRUE);
7048             if (*l == '@' && IS_AOP_PREG(result)) {
7049
7050                 pic14_emitcode("mov","a,%s",l);
7051                 aopPut(AOP(result),"a",offset);
7052             } else
7053                 aopPut(AOP(result),l,offset);
7054             offset++;
7055         }
7056     }
7057
7058     tlbl = newiTempLabel(NULL);
7059     tlbl1= newiTempLabel(NULL);
7060     size = AOP_SIZE(result);
7061     offset = size - 1;
7062
7063     /* if it is only one byte then */
7064     if (size == 1) {
7065 /*
7066         l = aopGet(AOP(left),0,FALSE,FALSE);
7067         MOVA(l);
7068         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7069         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7070         CLRC;
7071         pic14_emitcode("rrc","a");
7072         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7073         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7074         aopPut(AOP(result),"a",0);
7075 */
7076         tlbl = newiTempLabel(NULL);
7077         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7078           emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
7079           emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
7080         }
7081
7082         emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
7083         emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
7084         emitpLabel(tlbl->key);
7085         emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
7086         emitpcode(POC_ADDLW,  popGetLit(1));
7087         emitSKPC;
7088         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7089
7090         goto release ;
7091     }
7092
7093     reAdjustPreg(AOP(result));
7094     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7095     pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7096     CLRC;
7097     while (size--) {
7098         l = aopGet(AOP(result),offset,FALSE,FALSE);
7099         MOVA(l);
7100         pic14_emitcode("rrc","a");         
7101         aopPut(AOP(result),"a",offset--);
7102     }
7103     reAdjustPreg(AOP(result));
7104
7105     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7106     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7107
7108 release:
7109     freeAsmop(left,NULL,ic,TRUE);
7110     freeAsmop (right,NULL,ic,TRUE);
7111     freeAsmop(result,NULL,ic,TRUE);
7112 }
7113
7114 /*-----------------------------------------------------------------*/
7115 /* genUnpackBits - generates code for unpacking bits               */
7116 /*-----------------------------------------------------------------*/
7117 static void genUnpackBits (operand *result, char *rname, int ptype)
7118 {    
7119     int shCnt ;
7120     int rlen = 0 ;
7121     sym_link *etype;
7122     int offset = 0 ;
7123
7124     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7125     etype = getSpec(operandType(result));
7126
7127     /* read the first byte  */
7128     switch (ptype) {
7129
7130     case POINTER:
7131     case IPOINTER:
7132         pic14_emitcode("mov","a,@%s",rname);
7133         break;
7134         
7135     case PPOINTER:
7136         pic14_emitcode("movx","a,@%s",rname);
7137         break;
7138         
7139     case FPOINTER:
7140         pic14_emitcode("movx","a,@dptr");
7141         break;
7142
7143     case CPOINTER:
7144         pic14_emitcode("clr","a");
7145         pic14_emitcode("movc","a","@a+dptr");
7146         break;
7147
7148     case GPOINTER:
7149         pic14_emitcode("lcall","__gptrget");
7150         break;
7151     }
7152
7153     /* if we have bitdisplacement then it fits   */
7154     /* into this byte completely or if length is */
7155     /* less than a byte                          */
7156     if ((shCnt = SPEC_BSTR(etype)) || 
7157         (SPEC_BLEN(etype) <= 8))  {
7158
7159         /* shift right acc */
7160         AccRsh(shCnt);
7161
7162         pic14_emitcode("anl","a,#0x%02x",
7163                  ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7164         aopPut(AOP(result),"a",offset);
7165         return ;
7166     }
7167
7168     /* bit field did not fit in a byte  */
7169     rlen = SPEC_BLEN(etype) - 8;
7170     aopPut(AOP(result),"a",offset++);
7171
7172     while (1)  {
7173
7174         switch (ptype) {
7175         case POINTER:
7176         case IPOINTER:
7177             pic14_emitcode("inc","%s",rname);
7178             pic14_emitcode("mov","a,@%s",rname);
7179             break;
7180             
7181         case PPOINTER:
7182             pic14_emitcode("inc","%s",rname);
7183             pic14_emitcode("movx","a,@%s",rname);
7184             break;
7185
7186         case FPOINTER:
7187             pic14_emitcode("inc","dptr");
7188             pic14_emitcode("movx","a,@dptr");
7189             break;
7190             
7191         case CPOINTER:
7192             pic14_emitcode("clr","a");
7193             pic14_emitcode("inc","dptr");
7194             pic14_emitcode("movc","a","@a+dptr");
7195             break;
7196             
7197         case GPOINTER:
7198             pic14_emitcode("inc","dptr");
7199             pic14_emitcode("lcall","__gptrget");
7200             break;
7201         }
7202
7203         rlen -= 8;            
7204         /* if we are done */
7205         if ( rlen <= 0 )
7206             break ;
7207         
7208         aopPut(AOP(result),"a",offset++);
7209                               
7210     }
7211     
7212     if (rlen) {
7213         pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7214         aopPut(AOP(result),"a",offset);        
7215     }
7216     
7217     return ;
7218 }
7219
7220
7221 /*-----------------------------------------------------------------*/
7222 /* genDataPointerGet - generates code when ptr offset is known     */
7223 /*-----------------------------------------------------------------*/
7224 static void genDataPointerGet (operand *left, 
7225                                operand *result, 
7226                                iCode *ic)
7227 {
7228   int size , offset = 0;
7229
7230
7231   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7232
7233
7234   /* optimization - most of the time, left and result are the same
7235    * address, but different types. for the pic code, we could omit
7236    * the following
7237    */
7238
7239   aopOp(result,ic,TRUE);
7240
7241   emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,TRUE));
7242
7243   size = AOP_SIZE(result);
7244
7245   while (size--) {
7246     emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,TRUE));
7247     offset++;
7248   }
7249
7250   freeAsmop(left,NULL,ic,TRUE);
7251   freeAsmop(result,NULL,ic,TRUE);
7252 }
7253
7254 /*-----------------------------------------------------------------*/
7255 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7256 /*-----------------------------------------------------------------*/
7257 static void genNearPointerGet (operand *left, 
7258                                operand *result, 
7259                                iCode *ic)
7260 {
7261     asmop *aop = NULL;
7262     regs *preg = NULL ;
7263     char *rname ;
7264     sym_link *rtype, *retype;
7265     sym_link *ltype = operandType(left);    
7266     char buffer[80];
7267
7268     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7269
7270     rtype = operandType(result);
7271     retype= getSpec(rtype);
7272     
7273     aopOp(left,ic,FALSE);
7274     
7275     /* if left is rematerialisable and
7276        result is not bit variable type and
7277        the left is pointer to data space i.e
7278        lower 128 bytes of space */
7279     if (AOP_TYPE(left) == AOP_IMMD &&
7280         !IS_BITVAR(retype)         &&
7281         DCL_TYPE(ltype) == POINTER) {
7282         genDataPointerGet (left,result,ic);
7283         return ;
7284     }
7285     
7286     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7287
7288         /* if the value is already in a pointer register
7289        then don't need anything more */
7290     if (!AOP_INPREG(AOP(left))) {
7291         /* otherwise get a free pointer register */
7292     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7293         aop = newAsmop(0);
7294         preg = getFreePtr(ic,&aop,FALSE);
7295         pic14_emitcode("mov","%s,%s",
7296                 preg->name,
7297                 aopGet(AOP(left),0,FALSE,TRUE));
7298         rname = preg->name ;
7299     } else
7300         rname = aopGet(AOP(left),0,FALSE,FALSE);
7301     
7302     freeAsmop(left,NULL,ic,TRUE);
7303     aopOp (result,ic,FALSE);
7304     
7305       /* if bitfield then unpack the bits */
7306     if (IS_BITVAR(retype)) 
7307         genUnpackBits (result,rname,POINTER);
7308     else {
7309         /* we have can just get the values */
7310         int size = AOP_SIZE(result);
7311         int offset = 0 ;        
7312         
7313     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7314         while (size--) {
7315             if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7316
7317                 pic14_emitcode("mov","a,@%s",rname);
7318                 aopPut(AOP(result),"a",offset);
7319             } else {
7320                 sprintf(buffer,"@%s",rname);
7321                 aopPut(AOP(result),buffer,offset);
7322             }
7323             offset++ ;
7324             if (size)
7325                 pic14_emitcode("inc","%s",rname);
7326         }
7327     }
7328
7329     /* now some housekeeping stuff */
7330     if (aop) {
7331         /* we had to allocate for this iCode */
7332     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7333         freeAsmop(NULL,aop,ic,TRUE);
7334     } else { 
7335         /* we did not allocate which means left
7336            already in a pointer register, then
7337            if size > 0 && this could be used again
7338            we have to point it back to where it 
7339            belongs */
7340     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7341         if (AOP_SIZE(result) > 1 &&
7342             !OP_SYMBOL(left)->remat &&
7343             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7344               ic->depth )) {
7345             int size = AOP_SIZE(result) - 1;
7346             while (size--)
7347                 pic14_emitcode("dec","%s",rname);
7348         }
7349     }
7350
7351     /* done */
7352     freeAsmop(result,NULL,ic,TRUE);
7353      
7354 }
7355
7356 /*-----------------------------------------------------------------*/
7357 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
7358 /*-----------------------------------------------------------------*/
7359 static void genPagedPointerGet (operand *left, 
7360                                operand *result, 
7361                                iCode *ic)
7362 {
7363     asmop *aop = NULL;
7364     regs *preg = NULL ;
7365     char *rname ;
7366     sym_link *rtype, *retype;    
7367
7368     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7369
7370     rtype = operandType(result);
7371     retype= getSpec(rtype);
7372     
7373     aopOp(left,ic,FALSE);
7374
7375   /* if the value is already in a pointer register
7376        then don't need anything more */
7377     if (!AOP_INPREG(AOP(left))) {
7378         /* otherwise get a free pointer register */
7379         aop = newAsmop(0);
7380         preg = getFreePtr(ic,&aop,FALSE);
7381         pic14_emitcode("mov","%s,%s",
7382                 preg->name,
7383                 aopGet(AOP(left),0,FALSE,TRUE));
7384         rname = preg->name ;
7385     } else
7386         rname = aopGet(AOP(left),0,FALSE,FALSE);
7387     
7388     freeAsmop(left,NULL,ic,TRUE);
7389     aopOp (result,ic,FALSE);
7390
7391     /* if bitfield then unpack the bits */
7392     if (IS_BITVAR(retype)) 
7393         genUnpackBits (result,rname,PPOINTER);
7394     else {
7395         /* we have can just get the values */
7396         int size = AOP_SIZE(result);
7397         int offset = 0 ;        
7398         
7399         while (size--) {
7400             
7401             pic14_emitcode("movx","a,@%s",rname);
7402             aopPut(AOP(result),"a",offset);
7403             
7404             offset++ ;
7405             
7406             if (size)
7407                 pic14_emitcode("inc","%s",rname);
7408         }
7409     }
7410
7411     /* now some housekeeping stuff */
7412     if (aop) {
7413         /* we had to allocate for this iCode */
7414         freeAsmop(NULL,aop,ic,TRUE);
7415     } else { 
7416         /* we did not allocate which means left
7417            already in a pointer register, then
7418            if size > 0 && this could be used again
7419            we have to point it back to where it 
7420            belongs */
7421         if (AOP_SIZE(result) > 1 &&
7422             !OP_SYMBOL(left)->remat &&
7423             ( OP_SYMBOL(left)->liveTo > ic->seq ||
7424               ic->depth )) {
7425             int size = AOP_SIZE(result) - 1;
7426             while (size--)
7427                 pic14_emitcode("dec","%s",rname);
7428         }
7429     }
7430
7431     /* done */
7432     freeAsmop(result,NULL,ic,TRUE);
7433     
7434         
7435 }
7436
7437 /*-----------------------------------------------------------------*/
7438 /* genFarPointerGet - gget value from far space                    */
7439 /*-----------------------------------------------------------------*/
7440 static void genFarPointerGet (operand *left,
7441                               operand *result, iCode *ic)
7442 {
7443     int size, offset ;
7444     sym_link *retype = getSpec(operandType(result));
7445
7446     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7447
7448     aopOp(left,ic,FALSE);
7449
7450     /* if the operand is already in dptr 
7451     then we do nothing else we move the value to dptr */
7452     if (AOP_TYPE(left) != AOP_STR) {
7453         /* if this is remateriazable */
7454         if (AOP_TYPE(left) == AOP_IMMD)
7455             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7456         else { /* we need to get it byte by byte */
7457             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7458             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7459             if (options.model == MODEL_FLAT24)
7460             {
7461                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7462             }
7463         }
7464     }
7465     /* so dptr know contains the address */
7466     freeAsmop(left,NULL,ic,TRUE);
7467     aopOp(result,ic,FALSE);
7468
7469     /* if bit then unpack */
7470     if (IS_BITVAR(retype)) 
7471         genUnpackBits(result,"dptr",FPOINTER);
7472     else {
7473         size = AOP_SIZE(result);
7474         offset = 0 ;
7475
7476         while (size--) {
7477             pic14_emitcode("movx","a,@dptr");
7478             aopPut(AOP(result),"a",offset++);
7479             if (size)
7480                 pic14_emitcode("inc","dptr");
7481         }
7482     }
7483
7484     freeAsmop(result,NULL,ic,TRUE);
7485 }
7486
7487 /*-----------------------------------------------------------------*/
7488 /* pic14_emitcodePointerGet - gget value from code space                  */
7489 /*-----------------------------------------------------------------*/
7490 static void pic14_emitcodePointerGet (operand *left,
7491                                 operand *result, iCode *ic)
7492 {
7493     int size, offset ;
7494     sym_link *retype = getSpec(operandType(result));
7495
7496     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7497
7498     aopOp(left,ic,FALSE);
7499
7500     /* if the operand is already in dptr 
7501     then we do nothing else we move the value to dptr */
7502     if (AOP_TYPE(left) != AOP_STR) {
7503         /* if this is remateriazable */
7504         if (AOP_TYPE(left) == AOP_IMMD)
7505             pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7506         else { /* we need to get it byte by byte */
7507             pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7508             pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7509             if (options.model == MODEL_FLAT24)
7510             {
7511                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7512             }
7513         }
7514     }
7515     /* so dptr know contains the address */
7516     freeAsmop(left,NULL,ic,TRUE);
7517     aopOp(result,ic,FALSE);
7518
7519     /* if bit then unpack */
7520     if (IS_BITVAR(retype)) 
7521         genUnpackBits(result,"dptr",CPOINTER);
7522     else {
7523         size = AOP_SIZE(result);
7524         offset = 0 ;
7525
7526         while (size--) {
7527             pic14_emitcode("clr","a");
7528             pic14_emitcode("movc","a,@a+dptr");
7529             aopPut(AOP(result),"a",offset++);
7530             if (size)
7531                 pic14_emitcode("inc","dptr");
7532         }
7533     }
7534
7535     freeAsmop(result,NULL,ic,TRUE);
7536 }
7537
7538 /*-----------------------------------------------------------------*/
7539 /* genGenPointerGet - gget value from generic pointer space        */
7540 /*-----------------------------------------------------------------*/
7541 static void genGenPointerGet (operand *left,
7542                               operand *result, iCode *ic)
7543 {
7544   int size, offset ;
7545   sym_link *retype = getSpec(operandType(result));
7546
7547   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7548   aopOp(left,ic,FALSE);
7549   aopOp(result,ic,FALSE);
7550
7551
7552   DEBUGpic14_emitcode ("; ","result %s, left %s",
7553                          AopType(AOP_TYPE(result)),
7554                          AopType(AOP_TYPE(left)));
7555
7556   /* if the operand is already in dptr 
7557      then we do nothing else we move the value to dptr */
7558   if (AOP_TYPE(left) != AOP_STR) {
7559     /* if this is remateriazable */
7560     if (AOP_TYPE(left) == AOP_IMMD) {
7561       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7562       pic14_emitcode("mov","b,#%d",pointerCode(retype));
7563     }
7564     else { /* we need to get it byte by byte */
7565
7566       size = AOP_SIZE(result);
7567       offset = 0 ;
7568
7569       while(size--) {
7570         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7571         emitpcode(POC_MOVWF,popGet(AOP(result),offset++,FALSE,FALSE));
7572         if(size)
7573           emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7574       }
7575       goto release;
7576     }
7577   }
7578   /* so dptr know contains the address */
7579
7580   /* if bit then unpack */
7581   if (IS_BITVAR(retype)) 
7582     genUnpackBits(result,"dptr",GPOINTER);
7583
7584  release:
7585   freeAsmop(left,NULL,ic,TRUE);
7586   freeAsmop(result,NULL,ic,TRUE);
7587
7588 }
7589
7590 /*-----------------------------------------------------------------*/
7591 /* genPointerGet - generate code for pointer get                   */
7592 /*-----------------------------------------------------------------*/
7593 static void genPointerGet (iCode *ic)
7594 {
7595     operand *left, *result ;
7596     sym_link *type, *etype;
7597     int p_type;
7598
7599     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7600
7601     left = IC_LEFT(ic);
7602     result = IC_RESULT(ic) ;
7603
7604     /* depending on the type of pointer we need to
7605     move it to the correct pointer register */
7606     type = operandType(left);
7607     etype = getSpec(type);
7608     /* if left is of type of pointer then it is simple */
7609     if (IS_PTR(type) && !IS_FUNC(type->next)) 
7610         p_type = DCL_TYPE(type);
7611     else {
7612         /* we have to go by the storage class */
7613         p_type = PTR_TYPE(SPEC_OCLS(etype));
7614
7615 /*      if (SPEC_OCLS(etype)->codesp ) { */
7616 /*          p_type = CPOINTER ;  */
7617 /*      } */
7618 /*      else */
7619 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
7620 /*              p_type = FPOINTER ; */
7621 /*          else */
7622 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
7623 /*                  p_type = PPOINTER; */
7624 /*              else */
7625 /*                  if (SPEC_OCLS(etype) == idata ) */
7626 /*                      p_type = IPOINTER; */
7627 /*                  else */
7628 /*                      p_type = POINTER ; */
7629     }
7630
7631     /* now that we have the pointer type we assign
7632     the pointer values */
7633     switch (p_type) {
7634
7635     case POINTER:       
7636     case IPOINTER:
7637         genNearPointerGet (left,result,ic);
7638         break;
7639
7640     case PPOINTER:
7641         genPagedPointerGet(left,result,ic);
7642         break;
7643
7644     case FPOINTER:
7645         genFarPointerGet (left,result,ic);
7646         break;
7647
7648     case CPOINTER:
7649         pic14_emitcodePointerGet (left,result,ic);
7650         break;
7651
7652     case GPOINTER:
7653         genGenPointerGet (left,result,ic);
7654         break;
7655     }
7656
7657 }
7658
7659 /*-----------------------------------------------------------------*/
7660 /* genPackBits - generates code for packed bit storage             */
7661 /*-----------------------------------------------------------------*/
7662 static void genPackBits (sym_link    *etype ,
7663                          operand *right ,
7664                          char *rname, int p_type)
7665 {
7666     int shCount = 0 ;
7667     int offset = 0  ;
7668     int rLen = 0 ;
7669     int blen, bstr ;   
7670     char *l ;
7671
7672     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7673     blen = SPEC_BLEN(etype);
7674     bstr = SPEC_BSTR(etype);
7675
7676     l = aopGet(AOP(right),offset++,FALSE,FALSE);
7677     MOVA(l);   
7678
7679     /* if the bit lenth is less than or    */
7680     /* it exactly fits a byte then         */
7681     if (SPEC_BLEN(etype) <= 8 )  {
7682         shCount = SPEC_BSTR(etype) ;
7683
7684         /* shift left acc */
7685         AccLsh(shCount);
7686
7687         if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
7688
7689
7690             switch (p_type) {
7691                 case POINTER:
7692                     pic14_emitcode ("mov","b,a");
7693                     pic14_emitcode("mov","a,@%s",rname);
7694                     break;
7695
7696                 case FPOINTER:
7697                     pic14_emitcode ("mov","b,a");
7698                     pic14_emitcode("movx","a,@dptr");
7699                     break;
7700
7701                 case GPOINTER:
7702                     pic14_emitcode ("push","b");
7703                     pic14_emitcode ("push","acc");
7704                     pic14_emitcode ("lcall","__gptrget");
7705                     pic14_emitcode ("pop","b");
7706                     break;
7707             }
7708
7709             pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
7710                       ((unsigned char)(0xFF << (blen+bstr)) | 
7711                        (unsigned char)(0xFF >> (8-bstr)) ) );
7712             pic14_emitcode ("orl","a,b");
7713             if (p_type == GPOINTER)
7714                 pic14_emitcode("pop","b");
7715         }
7716     }
7717
7718     switch (p_type) {
7719         case POINTER:
7720             pic14_emitcode("mov","@%s,a",rname);
7721             break;
7722
7723         case FPOINTER:
7724             pic14_emitcode("movx","@dptr,a");
7725             break;
7726
7727         case GPOINTER:
7728             DEBUGpic14_emitcode(";lcall","__gptrput");
7729             break;
7730     }
7731
7732     /* if we r done */
7733     if ( SPEC_BLEN(etype) <= 8 )
7734         return ;
7735
7736     pic14_emitcode("inc","%s",rname);
7737     rLen = SPEC_BLEN(etype) ;     
7738
7739     /* now generate for lengths greater than one byte */
7740     while (1) {
7741
7742         l = aopGet(AOP(right),offset++,FALSE,TRUE);
7743
7744         rLen -= 8 ;
7745         if (rLen <= 0 )
7746             break ;
7747
7748         switch (p_type) {
7749             case POINTER:
7750                 if (*l == '@') {
7751                     MOVA(l);
7752                     pic14_emitcode("mov","@%s,a",rname);
7753                 } else
7754                     pic14_emitcode("mov","@%s,%s",rname,l);
7755                 break;
7756
7757             case FPOINTER:
7758                 MOVA(l);
7759                 pic14_emitcode("movx","@dptr,a");
7760                 break;
7761
7762             case GPOINTER:
7763                 MOVA(l);
7764                 DEBUGpic14_emitcode(";lcall","__gptrput");
7765                 break;  
7766         }   
7767         pic14_emitcode ("inc","%s",rname);
7768     }
7769
7770     MOVA(l);
7771
7772     /* last last was not complete */
7773     if (rLen)   {
7774         /* save the byte & read byte */
7775         switch (p_type) {
7776             case POINTER:
7777                 pic14_emitcode ("mov","b,a");
7778                 pic14_emitcode("mov","a,@%s",rname);
7779                 break;
7780
7781             case FPOINTER:
7782                 pic14_emitcode ("mov","b,a");
7783                 pic14_emitcode("movx","a,@dptr");
7784                 break;
7785
7786             case GPOINTER:
7787                 pic14_emitcode ("push","b");
7788                 pic14_emitcode ("push","acc");
7789                 pic14_emitcode ("lcall","__gptrget");
7790                 pic14_emitcode ("pop","b");
7791                 break;
7792         }
7793
7794         pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
7795         pic14_emitcode ("orl","a,b");
7796     }
7797
7798     if (p_type == GPOINTER)
7799         pic14_emitcode("pop","b");
7800
7801     switch (p_type) {
7802
7803     case POINTER:
7804         pic14_emitcode("mov","@%s,a",rname);
7805         break;
7806         
7807     case FPOINTER:
7808         pic14_emitcode("movx","@dptr,a");
7809         break;
7810         
7811     case GPOINTER:
7812         DEBUGpic14_emitcode(";lcall","__gptrput");
7813         break;                  
7814     }
7815 }
7816 /*-----------------------------------------------------------------*/
7817 /* genDataPointerSet - remat pointer to data space                 */
7818 /*-----------------------------------------------------------------*/
7819 static void genDataPointerSet(operand *right,
7820                               operand *result,
7821                               iCode *ic)
7822 {
7823     int size, offset = 0 ;
7824     char *l, buffer[256];
7825
7826     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7827     aopOp(right,ic,FALSE);
7828     
7829     l = aopGet(AOP(result),0,FALSE,TRUE);
7830     size = AOP_SIZE(right);
7831     // tsd, was l+1 - the underline `_' prefix was being stripped
7832     while (size--) {
7833         if (offset)
7834             sprintf(buffer,"(%s + %d)",l,offset);
7835         else
7836             sprintf(buffer,"%s",l);
7837
7838         if (AOP_TYPE(right) == AOP_LIT) {
7839           unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7840           lit = lit >> (8*offset);
7841           if(lit&0xff) {
7842             pic14_emitcode("movlw","%d",lit);
7843             pic14_emitcode("movwf","%s",buffer);
7844
7845             emitpcode(POC_MOVLW, popGetLit(lit&0xff));
7846             emitpcode(POC_MOVWF, popRegFromString(buffer));
7847
7848           } else {
7849             pic14_emitcode("clrf","%s",buffer);
7850             emitpcode(POC_CLRF, popRegFromString(buffer));
7851           }
7852         }else {
7853           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
7854           pic14_emitcode("movwf","%s",buffer);
7855
7856           emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
7857           emitpcode(POC_MOVWF, popRegFromString(buffer));
7858
7859         }
7860
7861         offset++;
7862     }
7863
7864     freeAsmop(right,NULL,ic,TRUE);
7865     freeAsmop(result,NULL,ic,TRUE);
7866 }
7867
7868 /*-----------------------------------------------------------------*/
7869 /* genNearPointerSet - pic14_emitcode for near pointer put                */
7870 /*-----------------------------------------------------------------*/
7871 static void genNearPointerSet (operand *right,
7872                                operand *result, 
7873                                iCode *ic)
7874 {
7875     asmop *aop = NULL;
7876     char *l;
7877     sym_link *retype;
7878     sym_link *ptype = operandType(result);
7879
7880     
7881     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7882     retype= getSpec(operandType(right));
7883
7884     aopOp(result,ic,FALSE);
7885     
7886     /* if the result is rematerializable &
7887        in data space & not a bit variable */
7888     if (AOP_TYPE(result) == AOP_IMMD &&
7889         DCL_TYPE(ptype) == POINTER   &&
7890         !IS_BITVAR(retype)) {
7891         genDataPointerSet (right,result,ic);
7892         return;
7893     }
7894
7895     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7896
7897     /* if the value is already in a pointer register
7898     then don't need anything more */
7899     if (!AOP_INPREG(AOP(result))) {
7900         /* otherwise get a free pointer register */
7901         //aop = newAsmop(0);
7902         //preg = getFreePtr(ic,&aop,FALSE);
7903         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7904         //pic14_emitcode("mov","%s,%s",
7905         //         preg->name,
7906         //         aopGet(AOP(result),0,FALSE,TRUE));
7907         //rname = preg->name ;
7908         pic14_emitcode("movwf","fsr");
7909     }// else
7910     //   rname = aopGet(AOP(result),0,FALSE,FALSE);
7911
7912     freeAsmop(result,NULL,ic,TRUE);
7913     aopOp (right,ic,FALSE);
7914     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7915
7916     /* if bitfield then unpack the bits */
7917     if (IS_BITVAR(retype)) {
7918       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
7919              "The programmer is obviously confused");
7920       //genPackBits (retype,right,rname,POINTER);
7921       exit(1);
7922     }
7923     else {
7924         /* we have can just get the values */
7925         int size = AOP_SIZE(right);
7926         int offset = 0 ;    
7927
7928     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7929         while (size--) {
7930             l = aopGet(AOP(right),offset,FALSE,TRUE);
7931             if (*l == '@' ) {
7932               //MOVA(l);
7933               //pic14_emitcode("mov","@%s,a",rname);
7934               pic14_emitcode("movf","indf,w ;1");
7935             } else {
7936
7937               if (AOP_TYPE(right) == AOP_LIT) {
7938                 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
7939                 if(lit) {
7940                   pic14_emitcode("movlw","%s",l);
7941                   pic14_emitcode("movwf","indf ;2");
7942                 } else 
7943                   pic14_emitcode("clrf","indf");
7944               }else {
7945                 pic14_emitcode("movf","%s,w",l);
7946                 pic14_emitcode("movwf","indf ;2");
7947               }
7948             //pic14_emitcode("mov","@%s,%s",rname,l);
7949             }
7950             if (size)
7951               pic14_emitcode("incf","fsr,f ;3");
7952             //pic14_emitcode("inc","%s",rname);
7953             offset++;
7954         }
7955     }
7956
7957     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7958     /* now some housekeeping stuff */
7959     if (aop) {
7960         /* we had to allocate for this iCode */
7961         freeAsmop(NULL,aop,ic,TRUE);
7962     } else { 
7963         /* we did not allocate which means left
7964         already in a pointer register, then
7965         if size > 0 && this could be used again
7966         we have to point it back to where it 
7967         belongs */
7968     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7969         if (AOP_SIZE(right) > 1 &&
7970             !OP_SYMBOL(result)->remat &&
7971             ( OP_SYMBOL(result)->liveTo > ic->seq ||
7972               ic->depth )) {
7973             int size = AOP_SIZE(right) - 1;
7974             while (size--)
7975               pic14_emitcode("decf","fsr,f");
7976               //pic14_emitcode("dec","%s",rname);
7977         }
7978     }
7979
7980     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7981     /* done */
7982     freeAsmop(right,NULL,ic,TRUE);
7983
7984
7985 }
7986
7987 /*-----------------------------------------------------------------*/
7988 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
7989 /*-----------------------------------------------------------------*/
7990 static void genPagedPointerSet (operand *right,
7991                                operand *result, 
7992                                iCode *ic)
7993 {
7994     asmop *aop = NULL;
7995     regs *preg = NULL ;
7996     char *rname , *l;
7997     sym_link *retype;
7998        
7999     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8000
8001     retype= getSpec(operandType(right));
8002     
8003     aopOp(result,ic,FALSE);
8004     
8005     /* if the value is already in a pointer register
8006        then don't need anything more */
8007     if (!AOP_INPREG(AOP(result))) {
8008         /* otherwise get a free pointer register */
8009         aop = newAsmop(0);
8010         preg = getFreePtr(ic,&aop,FALSE);
8011         pic14_emitcode("mov","%s,%s",
8012                 preg->name,
8013                 aopGet(AOP(result),0,FALSE,TRUE));
8014         rname = preg->name ;
8015     } else
8016         rname = aopGet(AOP(result),0,FALSE,FALSE);
8017     
8018     freeAsmop(result,NULL,ic,TRUE);
8019     aopOp (right,ic,FALSE);
8020
8021     /* if bitfield then unpack the bits */
8022     if (IS_BITVAR(retype)) 
8023         genPackBits (retype,right,rname,PPOINTER);
8024     else {
8025         /* we have can just get the values */
8026         int size = AOP_SIZE(right);
8027         int offset = 0 ;        
8028         
8029         while (size--) {
8030             l = aopGet(AOP(right),offset,FALSE,TRUE);
8031             
8032             MOVA(l);
8033             pic14_emitcode("movx","@%s,a",rname);
8034
8035             if (size)
8036                 pic14_emitcode("inc","%s",rname);
8037
8038             offset++;
8039         }
8040     }
8041     
8042     /* now some housekeeping stuff */
8043     if (aop) {
8044         /* we had to allocate for this iCode */
8045         freeAsmop(NULL,aop,ic,TRUE);
8046     } else { 
8047         /* we did not allocate which means left
8048            already in a pointer register, then
8049            if size > 0 && this could be used again
8050            we have to point it back to where it 
8051            belongs */
8052         if (AOP_SIZE(right) > 1 &&
8053             !OP_SYMBOL(result)->remat &&
8054             ( OP_SYMBOL(result)->liveTo > ic->seq ||
8055               ic->depth )) {
8056             int size = AOP_SIZE(right) - 1;
8057             while (size--)
8058                 pic14_emitcode("dec","%s",rname);
8059         }
8060     }
8061
8062     /* done */
8063     freeAsmop(right,NULL,ic,TRUE);
8064     
8065         
8066 }
8067
8068 /*-----------------------------------------------------------------*/
8069 /* genFarPointerSet - set value from far space                     */
8070 /*-----------------------------------------------------------------*/
8071 static void genFarPointerSet (operand *right,
8072                               operand *result, iCode *ic)
8073 {
8074     int size, offset ;
8075     sym_link *retype = getSpec(operandType(right));
8076
8077     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8078     aopOp(result,ic,FALSE);
8079
8080     /* if the operand is already in dptr 
8081     then we do nothing else we move the value to dptr */
8082     if (AOP_TYPE(result) != AOP_STR) {
8083         /* if this is remateriazable */
8084         if (AOP_TYPE(result) == AOP_IMMD)
8085             pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8086         else { /* we need to get it byte by byte */
8087             pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8088             pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8089             if (options.model == MODEL_FLAT24)
8090             {
8091                pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8092             }
8093         }
8094     }
8095     /* so dptr know contains the address */
8096     freeAsmop(result,NULL,ic,TRUE);
8097     aopOp(right,ic,FALSE);
8098
8099     /* if bit then unpack */
8100     if (IS_BITVAR(retype)) 
8101         genPackBits(retype,right,"dptr",FPOINTER);
8102     else {
8103         size = AOP_SIZE(right);
8104         offset = 0 ;
8105
8106         while (size--) {
8107             char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8108             MOVA(l);
8109             pic14_emitcode("movx","@dptr,a");
8110             if (size)
8111                 pic14_emitcode("inc","dptr");
8112         }
8113     }
8114
8115     freeAsmop(right,NULL,ic,TRUE);
8116 }
8117
8118 /*-----------------------------------------------------------------*/
8119 /* genGenPointerSet - set value from generic pointer space         */
8120 /*-----------------------------------------------------------------*/
8121 static void genGenPointerSet (operand *right,
8122                               operand *result, iCode *ic)
8123 {
8124   int size, offset ;
8125   sym_link *retype = getSpec(operandType(right));
8126
8127   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8128
8129   aopOp(result,ic,FALSE);
8130   aopOp(right,ic,FALSE);
8131   size = AOP_SIZE(right);
8132
8133   DEBUGpic14_emitcode ("; ","result %s=%s, right %s=%s, size = %d",
8134                        AopType(AOP_TYPE(result)),
8135                        aopGet(AOP(result),0,TRUE,FALSE),
8136                        AopType(AOP_TYPE(right)),
8137                        aopGet(AOP(right),0,FALSE,FALSE),
8138                        size);
8139
8140   /* if the operand is already in dptr 
8141      then we do nothing else we move the value to dptr */
8142   if (AOP_TYPE(result) != AOP_STR) {
8143     /* if this is remateriazable */
8144     if (AOP_TYPE(result) == AOP_IMMD) {
8145       pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8146       pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8147     }
8148     else { /* we need to get it byte by byte */
8149       //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8150       size = AOP_SIZE(right);
8151       offset = 0 ;
8152
8153       /* hack hack! see if this the FSR. If so don't load W */
8154       if(AOP_TYPE(right) != AOP_ACC) {
8155
8156         if(size==2)
8157           emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8158
8159         if(size==4) {
8160           emitpcode(POC_MOVLW,popGetLit(0xfd));
8161           emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8162         }
8163
8164         while(size--) {
8165           emitpcode(POC_MOVFW,popGet(AOP(right),offset++,FALSE,FALSE));
8166           emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8167           
8168           if(size)
8169             emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8170         }
8171
8172
8173         goto release;
8174       } 
8175
8176       if(aopIdx(AOP(result),0) != 4) {
8177
8178         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8179         goto release;
8180       }
8181
8182       emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8183       goto release;
8184
8185     }
8186   }
8187   /* so dptr know contains the address */
8188
8189
8190   /* if bit then unpack */
8191   if (IS_BITVAR(retype)) 
8192     genPackBits(retype,right,"dptr",GPOINTER);
8193   else {
8194     size = AOP_SIZE(right);
8195     offset = 0 ;
8196
8197     while (--size) {
8198       //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8199       if(size)
8200         pic14_emitcode("incf","fsr,f");
8201       pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8202       pic14_emitcode("movwf","indf");
8203       //MOVA(l);
8204       //DEBUGpic14_emitcode(";lcall","__gptrput");
8205       //if (size)
8206       //    pic14_emitcode("inc","dptr");
8207     }
8208   }
8209
8210  release:
8211   freeAsmop(right,NULL,ic,TRUE);
8212   freeAsmop(result,NULL,ic,TRUE);
8213 }
8214
8215 /*-----------------------------------------------------------------*/
8216 /* genPointerSet - stores the value into a pointer location        */
8217 /*-----------------------------------------------------------------*/
8218 static void genPointerSet (iCode *ic)
8219 {    
8220     operand *right, *result ;
8221     sym_link *type, *etype;
8222     int p_type;
8223
8224     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8225
8226     right = IC_RIGHT(ic);
8227     result = IC_RESULT(ic) ;
8228
8229     /* depending on the type of pointer we need to
8230     move it to the correct pointer register */
8231     type = operandType(result);
8232     etype = getSpec(type);
8233     /* if left is of type of pointer then it is simple */
8234     if (IS_PTR(type) && !IS_FUNC(type->next)) {
8235         p_type = DCL_TYPE(type);
8236     }
8237     else {
8238         /* we have to go by the storage class */
8239         p_type = PTR_TYPE(SPEC_OCLS(etype));
8240
8241 /*      if (SPEC_OCLS(etype)->codesp ) { */
8242 /*          p_type = CPOINTER ;  */
8243 /*      } */
8244 /*      else */
8245 /*          if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8246 /*              p_type = FPOINTER ; */
8247 /*          else */
8248 /*              if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8249 /*                  p_type = PPOINTER ; */
8250 /*              else */
8251 /*                  if (SPEC_OCLS(etype) == idata ) */
8252 /*                      p_type = IPOINTER ; */
8253 /*                  else */
8254 /*                      p_type = POINTER ; */
8255     }
8256
8257     /* now that we have the pointer type we assign
8258     the pointer values */
8259     switch (p_type) {
8260
8261     case POINTER:
8262     case IPOINTER:
8263         genNearPointerSet (right,result,ic);
8264         break;
8265
8266     case PPOINTER:
8267         genPagedPointerSet (right,result,ic);
8268         break;
8269
8270     case FPOINTER:
8271         genFarPointerSet (right,result,ic);
8272         break;
8273
8274     case GPOINTER:
8275         genGenPointerSet (right,result,ic);
8276         break;
8277     }
8278
8279 }
8280
8281 /*-----------------------------------------------------------------*/
8282 /* genIfx - generate code for Ifx statement                        */
8283 /*-----------------------------------------------------------------*/
8284 static void genIfx (iCode *ic, iCode *popIc)
8285 {
8286   operand *cond = IC_COND(ic);
8287   int isbit =0;
8288
8289   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8290
8291   aopOp(cond,ic,FALSE);
8292
8293   /* get the value into acc */
8294   if (AOP_TYPE(cond) != AOP_CRY)
8295     pic14_toBoolean(cond);
8296   else
8297     isbit = 1;
8298   /* the result is now in the accumulator */
8299   freeAsmop(cond,NULL,ic,TRUE);
8300
8301   /* if there was something to be popped then do it */
8302   if (popIc)
8303     genIpop(popIc);
8304
8305   /* if the condition is  a bit variable */
8306   if (isbit && IS_ITEMP(cond) && 
8307       SPIL_LOC(cond)) {
8308     genIfxJump(ic,SPIL_LOC(cond)->rname);
8309     DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8310   }
8311   else {
8312     if (isbit && !IS_ITEMP(cond))
8313       genIfxJump(ic,OP_SYMBOL(cond)->rname);
8314     else
8315       genIfxJump(ic,"a");
8316   }
8317   ic->generated = 1;
8318
8319 }
8320
8321 /*-----------------------------------------------------------------*/
8322 /* genAddrOf - generates code for address of                       */
8323 /*-----------------------------------------------------------------*/
8324 static void genAddrOf (iCode *ic)
8325 {
8326   //symbol *sym = OP_SYMBOL(IC_LEFT(ic));
8327   operand *right, *result, *left;
8328   //int size, offset ;
8329
8330   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8331
8332
8333   //aopOp(IC_RESULT(ic),ic,FALSE);
8334
8335   aopOp((left=IC_LEFT(ic)),ic,FALSE);
8336   aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8337   aopOp((result=IC_RESULT(ic)),ic,TRUE);
8338
8339   if(result)
8340     DEBUGpic14_emitcode ("; ","result %s",
8341                          AopType(AOP_TYPE(IC_RESULT(ic))));
8342
8343   if(left)
8344     DEBUGpic14_emitcode ("; ","left %s",
8345                          AopType(AOP_TYPE(IC_LEFT(ic))));
8346   if(right)
8347     DEBUGpic14_emitcode ("; ","right %s",
8348                          AopType(AOP_TYPE(IC_RIGHT(ic))));
8349   
8350   emitpcode(POC_MOVLW, popGet(AOP(left),0,FALSE,FALSE));
8351   emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
8352
8353 #if 0
8354   /* object not on stack then we need the name */
8355   size = AOP_SIZE(IC_RESULT(ic));
8356   offset = 0;
8357
8358   while (size--) {
8359     char s[SDCC_NAME_MAX];
8360     if (offset) 
8361       sprintf(s,"#(%s >> %d)",
8362               sym->rname,
8363               offset*8);
8364     else
8365       sprintf(s,"#%s",sym->rname);
8366     aopPut(AOP(IC_RESULT(ic)),s,offset++);
8367   }
8368 #endif
8369
8370
8371   //  freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
8372   freeAsmop(left,NULL,ic,FALSE);
8373   freeAsmop(result,NULL,ic,TRUE);
8374
8375 }
8376
8377 #if 0
8378 /*-----------------------------------------------------------------*/
8379 /* genFarFarAssign - assignment when both are in far space         */
8380 /*-----------------------------------------------------------------*/
8381 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8382 {
8383     int size = AOP_SIZE(right);
8384     int offset = 0;
8385     char *l ;
8386     /* first push the right side on to the stack */
8387     while (size--) {
8388         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8389         MOVA(l);
8390         pic14_emitcode ("push","acc");
8391     }
8392     
8393     freeAsmop(right,NULL,ic,FALSE);
8394     /* now assign DPTR to result */
8395     aopOp(result,ic,FALSE);
8396     size = AOP_SIZE(result);
8397     while (size--) {
8398         pic14_emitcode ("pop","acc");
8399         aopPut(AOP(result),"a",--offset);
8400     }
8401     freeAsmop(result,NULL,ic,FALSE);
8402         
8403 }
8404 #endif
8405
8406 /*-----------------------------------------------------------------*/
8407 /* genAssign - generate code for assignment                        */
8408 /*-----------------------------------------------------------------*/
8409 static void genAssign (iCode *ic)
8410 {
8411   operand *result, *right;
8412   int size, offset,know_W;
8413   unsigned long lit = 0L;
8414
8415   result = IC_RESULT(ic);
8416   right  = IC_RIGHT(ic) ;
8417
8418   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8419
8420   /* if they are the same */
8421   if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8422     return ;
8423
8424   aopOp(right,ic,FALSE);
8425   aopOp(result,ic,TRUE);
8426
8427   DEBUGpic14_emitcode ("; ","result %s, right %s, size = %d",
8428                        AopType(AOP_TYPE(IC_RESULT(ic))),
8429                        AopType(AOP_TYPE(IC_RIGHT(ic))),
8430                        AOP_SIZE(result));
8431
8432   /* if they are the same registers */
8433   if (pic14_sameRegs(AOP(right),AOP(result)))
8434     goto release;
8435
8436   /* if the result is a bit */
8437   if (AOP_TYPE(result) == AOP_CRY) {
8438
8439     /* if the right size is a literal then
8440        we know what the value is */
8441     if (AOP_TYPE(right) == AOP_LIT) {
8442           
8443       emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8444                   popGet(AOP(result),0,FALSE,FALSE));
8445
8446       if (((int) operandLitValue(right))) 
8447         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8448                        AOP(result)->aopu.aop_dir,
8449                        AOP(result)->aopu.aop_dir);
8450       else
8451         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8452                        AOP(result)->aopu.aop_dir,
8453                        AOP(result)->aopu.aop_dir);
8454       goto release;
8455     }
8456
8457     /* the right is also a bit variable */
8458     if (AOP_TYPE(right) == AOP_CRY) {
8459       emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
8460       emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8461       emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
8462
8463       pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8464                      AOP(result)->aopu.aop_dir,
8465                      AOP(result)->aopu.aop_dir);
8466       pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8467                      AOP(right)->aopu.aop_dir,
8468                      AOP(right)->aopu.aop_dir);
8469       pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8470                      AOP(result)->aopu.aop_dir,
8471                      AOP(result)->aopu.aop_dir);
8472       goto release ;
8473     }
8474
8475     /* we need to or */
8476     emitpcode(POC_BCF,    popGet(AOP(result),0,FALSE,FALSE));
8477     pic14_toBoolean(right);
8478     emitSKPZ;
8479     emitpcode(POC_BSF,    popGet(AOP(result),0,FALSE,FALSE));
8480     //aopPut(AOP(result),"a",0);
8481     goto release ;
8482   }
8483
8484   /* bit variables done */
8485   /* general case */
8486   size = AOP_SIZE(result);
8487   offset = 0 ;
8488   if(AOP_TYPE(right) == AOP_LIT)
8489     lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8490
8491   if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
8492     if(aopIdx(AOP(result),0) == 4) {
8493       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8494       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8495       goto release;
8496     } else
8497       DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
8498   }
8499
8500   know_W=-1;
8501   while (size--) {
8502     if(AOP_TYPE(right) == AOP_LIT) {
8503       if(lit&0xff) {
8504         if(know_W != (lit&0xff))
8505           emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8506         know_W = lit&0xff;
8507         emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8508       } else
8509         emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8510
8511       lit >>= 8;
8512
8513     } else if (AOP_TYPE(right) == AOP_CRY) {
8514       emitpcode(POC_CLRF, popGet(AOP(result),offset,FALSE,FALSE));
8515       if(offset == 0) {
8516         emitpcode(POC_BTFSS, popGet(AOP(right),0,FALSE,FALSE));
8517         emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
8518       }
8519     } else {
8520       emitpcode(POC_MOVFW, popGet(AOP(right),offset,FALSE,FALSE));
8521       emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
8522     }
8523             
8524     offset++;
8525   }
8526
8527     
8528  release:
8529   freeAsmop (right,NULL,ic,FALSE);
8530   freeAsmop (result,NULL,ic,TRUE);
8531 }   
8532
8533 /*-----------------------------------------------------------------*/
8534 /* genJumpTab - genrates code for jump table                       */
8535 /*-----------------------------------------------------------------*/
8536 static void genJumpTab (iCode *ic)
8537 {
8538     symbol *jtab;
8539     char *l;
8540
8541     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8542
8543     aopOp(IC_JTCOND(ic),ic,FALSE);
8544     /* get the condition into accumulator */
8545     l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8546     MOVA(l);
8547     /* multiply by three */
8548     pic14_emitcode("add","a,acc");
8549     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8550
8551     jtab = newiTempLabel(NULL);
8552     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8553     pic14_emitcode("jmp","@a+dptr");
8554     pic14_emitcode("","%05d_DS_:",jtab->key+100);
8555
8556     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8557     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8558     emitSKPNC;
8559     emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8560     emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8561     emitpLabel(jtab->key);
8562
8563     freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8564
8565     /* now generate the jump labels */
8566     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8567          jtab = setNextItem(IC_JTLABELS(ic))) {
8568         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8569         emitpcode(POC_GOTO,popGetLabel(jtab->key));
8570         
8571     }
8572
8573 }
8574
8575 /*-----------------------------------------------------------------*/
8576 /* genMixedOperation - gen code for operators between mixed types  */
8577 /*-----------------------------------------------------------------*/
8578 /*
8579   TSD - Written for the PIC port - but this unfortunately is buggy.
8580   This routine is good in that it is able to efficiently promote 
8581   types to different (larger) sizes. Unfortunately, the temporary
8582   variables that are optimized out by this routine are sometimes
8583   used in other places. So until I know how to really parse the 
8584   iCode tree, I'm going to not be using this routine :(.
8585 */
8586 static int genMixedOperation (iCode *ic)
8587 {
8588 #if 0
8589   operand *result = IC_RESULT(ic);
8590   sym_link *ctype = operandType(IC_LEFT(ic));
8591   operand *right = IC_RIGHT(ic);
8592   int ret = 0;
8593   int big,small;
8594   int offset;
8595
8596   iCode *nextic;
8597   operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8598
8599   pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8600
8601   nextic = ic->next;
8602   if(!nextic)
8603     return 0;
8604
8605   nextright = IC_RIGHT(nextic);
8606   nextleft  = IC_LEFT(nextic);
8607   nextresult = IC_RESULT(nextic);
8608
8609   aopOp(right,ic,FALSE);
8610   aopOp(result,ic,FALSE);
8611   aopOp(nextright,  nextic, FALSE);
8612   aopOp(nextleft,   nextic, FALSE);
8613   aopOp(nextresult, nextic, FALSE);
8614
8615   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8616
8617     operand *t = right;
8618     right = nextright;
8619     nextright = t; 
8620
8621     pic14_emitcode(";remove right +","");
8622
8623   } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
8624 /*
8625     operand *t = right;
8626     right = nextleft;
8627     nextleft = t; 
8628 */
8629     pic14_emitcode(";remove left +","");
8630   } else
8631     return 0;
8632
8633   big = AOP_SIZE(nextleft);
8634   small = AOP_SIZE(nextright);
8635
8636   switch(nextic->op) {
8637
8638   case '+':
8639     pic14_emitcode(";optimize a +","");
8640     /* if unsigned or not an integral type */
8641     if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
8642       pic14_emitcode(";add a bit to something","");
8643     } else {
8644
8645       pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
8646
8647       if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
8648         pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
8649         pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
8650       } else
8651         pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
8652
8653       offset = 0;
8654       while(--big) {
8655
8656         offset++;
8657
8658         if(--small) {
8659           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8660             pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8661             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8662           }
8663
8664           pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8665           emitSKPNC;
8666           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8667                    AOP(IC_RIGHT(nextic))->aopu.aop_dir,
8668                    AOP(IC_RIGHT(nextic))->aopu.aop_dir);
8669           pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8670           pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
8671
8672         } else {
8673           pic14_emitcode("rlf","known_zero,w");
8674
8675           /*
8676             if right is signed
8677               btfsc  right,7
8678                addlw ff
8679           */
8680           if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
8681             pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
8682             pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8683           } else {
8684             pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
8685           }
8686         }
8687       }
8688       ret = 1;
8689     }
8690   }
8691   ret = 1;
8692
8693 release:
8694   freeAsmop(right,NULL,ic,TRUE);
8695   freeAsmop(result,NULL,ic,TRUE);
8696   freeAsmop(nextright,NULL,ic,TRUE);
8697   freeAsmop(nextleft,NULL,ic,TRUE);
8698   if(ret)
8699     nextic->generated = 1;
8700
8701   return ret;
8702 #else
8703   return 0;
8704 #endif
8705 }
8706 /*-----------------------------------------------------------------*/
8707 /* genCast - gen code for casting                                  */
8708 /*-----------------------------------------------------------------*/
8709 static void genCast (iCode *ic)
8710 {
8711     operand *result = IC_RESULT(ic);
8712     sym_link *ctype = operandType(IC_LEFT(ic));
8713     operand *right = IC_RIGHT(ic);
8714     int size, offset ;
8715
8716     DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
8717     /* if they are equivalent then do nothing */
8718     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
8719         return ;
8720
8721     aopOp(right,ic,FALSE) ;
8722     aopOp(result,ic,FALSE);
8723
8724     /* if the result is a bit */
8725     if (AOP_TYPE(result) == AOP_CRY) {
8726         /* if the right size is a literal then
8727         we know what the value is */
8728         if (AOP_TYPE(right) == AOP_LIT) {
8729
8730           emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8731                       popGet(AOP(result),0,FALSE,FALSE));
8732
8733             if (((int) operandLitValue(right))) 
8734               pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
8735                        AOP(result)->aopu.aop_dir,
8736                        AOP(result)->aopu.aop_dir);
8737             else
8738               pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
8739                        AOP(result)->aopu.aop_dir,
8740                        AOP(result)->aopu.aop_dir);
8741
8742             goto release;
8743         }
8744
8745         /* the right is also a bit variable */
8746         if (AOP_TYPE(right) == AOP_CRY) {
8747
8748           emitCLRC;
8749           emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8750
8751           pic14_emitcode("clrc","");
8752           pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8753                    AOP(right)->aopu.aop_dir,
8754                    AOP(right)->aopu.aop_dir);
8755             aopPut(AOP(result),"c",0);
8756             goto release ;
8757         }
8758
8759         /* we need to or */
8760         pic14_toBoolean(right);
8761         aopPut(AOP(result),"a",0);
8762         goto release ;
8763     }
8764
8765     /* if they are the same size : or less */
8766     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
8767
8768         /* if they are in the same place */
8769         if (pic14_sameRegs(AOP(right),AOP(result)))
8770             goto release;
8771
8772         /* if they in different places then copy */
8773         size = AOP_SIZE(result);
8774         offset = 0 ;
8775         while (size--) {
8776             aopPut(AOP(result),
8777                    aopGet(AOP(right),offset,FALSE,FALSE),
8778                    offset);
8779             offset++;
8780         }
8781         goto release;
8782     }
8783
8784
8785     /* if the result is of type pointer */
8786     if (IS_PTR(ctype)) {
8787
8788         int p_type;
8789         sym_link *type = operandType(right);
8790         sym_link *etype = getSpec(type);
8791
8792         /* pointer to generic pointer */
8793         if (IS_GENPTR(ctype)) {
8794             char *l = zero;
8795             
8796             if (IS_PTR(type)) 
8797                 p_type = DCL_TYPE(type);
8798             else {
8799                 /* we have to go by the storage class */
8800                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8801
8802 /*              if (SPEC_OCLS(etype)->codesp )  */
8803 /*                  p_type = CPOINTER ;  */
8804 /*              else */
8805 /*                  if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8806 /*                      p_type = FPOINTER ; */
8807 /*                  else */
8808 /*                      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8809 /*                          p_type = PPOINTER; */
8810 /*                      else */
8811 /*                          if (SPEC_OCLS(etype) == idata ) */
8812 /*                              p_type = IPOINTER ; */
8813 /*                          else */
8814 /*                              p_type = POINTER ; */
8815             }
8816                 
8817             /* the first two bytes are known */
8818             size = GPTRSIZE - 1; 
8819             offset = 0 ;
8820             while (size--) {
8821                 aopPut(AOP(result),
8822                        aopGet(AOP(right),offset,FALSE,FALSE),
8823                        offset);
8824                 offset++;
8825             }
8826             /* the last byte depending on type */
8827             switch (p_type) {
8828             case IPOINTER:
8829             case POINTER:
8830                 l = zero;
8831                 break;
8832             case FPOINTER:
8833                 l = one;
8834                 break;
8835             case CPOINTER:
8836                 l = "#0x02";
8837                 break;                          
8838             case PPOINTER:
8839                 l = "#0x03";
8840                 break;
8841                 
8842             default:
8843                 /* this should never happen */
8844                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8845                        "got unknown pointer type");
8846                 exit(1);
8847             }
8848             aopPut(AOP(result),l, GPTRSIZE - 1);            
8849             goto release ;
8850         }
8851         
8852         /* just copy the pointers */
8853         size = AOP_SIZE(result);
8854         offset = 0 ;
8855         while (size--) {
8856             aopPut(AOP(result),
8857                    aopGet(AOP(right),offset,FALSE,FALSE),
8858                    offset);
8859             offset++;
8860         }
8861         goto release ;
8862     }
8863     
8864
8865     if (AOP_TYPE(right) == AOP_CRY) {
8866       int offset = 1;
8867       size = AOP_SIZE(right);
8868
8869       emitpcode(POC_CLRF,   popGet(AOP(result),0,FALSE,FALSE));
8870       emitpcode(POC_BTFSC,  popGet(AOP(right),0,FALSE,FALSE));
8871       emitpcode(POC_INCF,   popGet(AOP(result),0,FALSE,FALSE));
8872
8873       pic14_emitcode("clrf","%s ; %d", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8874       pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8875                AOP(right)->aopu.aop_dir,
8876                AOP(right)->aopu.aop_dir);
8877       pic14_emitcode("incf","%s,f", aopGet(AOP(result),0,FALSE,FALSE),__LINE__);
8878       while (size--) {
8879         pic14_emitcode("clrf","%s;%d", aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8880         emitpcode(POC_CLRF,   popGet(AOP(result),offset++,FALSE,FALSE));
8881       }
8882       goto release;
8883     }
8884
8885     /* so we now know that the size of destination is greater
8886     than the size of the source.
8887     Now, if the next iCode is an operator then we might be
8888     able to optimize the operation without performing a cast.
8889     */
8890     if(genMixedOperation(ic))
8891       goto release;
8892
8893     
8894     /* we move to result for the size of source */
8895     size = AOP_SIZE(right);
8896     offset = 0 ;
8897     while (size--) {
8898       pic14_emitcode(";","%d",__LINE__);
8899       /* aopPut(AOP(result),
8900              aopGet(AOP(right),offset,FALSE,FALSE),
8901              offset); */
8902       emitpcode(POC_MOVFW,   popGet(AOP(right),offset,FALSE,FALSE));
8903       emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
8904       offset++;
8905     }
8906
8907     /* now depending on the sign of the destination */
8908     size = AOP_SIZE(result) - AOP_SIZE(right);
8909     /* if unsigned or not an integral type */
8910     if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
8911       while (size--) {
8912           emitpcode(POC_CLRF,   popGet(AOP(result),offset,FALSE,FALSE));
8913           pic14_emitcode("clrf","%s  ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__);
8914           offset++;
8915       }
8916     } else {
8917       /* we need to extend the sign :{ */
8918
8919       emitpcodeNULLop(POC_CLRW);
8920
8921       if(offset)
8922         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
8923       else
8924         emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
8925
8926       emitpcode(POC_MOVLW,   popGetLit(0xff));
8927
8928         pic14_emitcode("clrw","");
8929         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
8930                  AOP(right)->aopu.aop_dir,
8931                  AOP(right)->aopu.aop_dir);
8932         pic14_emitcode("movlw","0xff");
8933         while (size--) {
8934           emitpcode(POC_MOVWF,   popGet(AOP(result),offset,FALSE,FALSE));
8935           pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
8936           offset++;
8937           // aopPut(AOP(result),"a",offset++);
8938         }
8939
8940     }
8941
8942     /* we are done hurray !!!! */
8943
8944 release:
8945     freeAsmop(right,NULL,ic,TRUE);
8946     freeAsmop(result,NULL,ic,TRUE);
8947
8948 }
8949
8950 /*-----------------------------------------------------------------*/
8951 /* genDjnz - generate decrement & jump if not zero instrucion      */
8952 /*-----------------------------------------------------------------*/
8953 static int genDjnz (iCode *ic, iCode *ifx)
8954 {
8955     symbol *lbl, *lbl1;
8956     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8957
8958     if (!ifx)
8959         return 0;
8960     
8961     /* if the if condition has a false label
8962        then we cannot save */
8963     if (IC_FALSE(ifx))
8964         return 0;
8965
8966     /* if the minus is not of the form 
8967        a = a - 1 */
8968     if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
8969         !IS_OP_LITERAL(IC_RIGHT(ic)))
8970         return 0;
8971
8972     if (operandLitValue(IC_RIGHT(ic)) != 1)
8973         return 0;
8974
8975     /* if the size of this greater than one then no
8976        saving */
8977     if (getSize(operandType(IC_RESULT(ic))) > 1)
8978         return 0;
8979
8980     /* otherwise we can save BIG */
8981     lbl = newiTempLabel(NULL);
8982     lbl1= newiTempLabel(NULL);
8983
8984     aopOp(IC_RESULT(ic),ic,FALSE);
8985     
8986     if (IS_AOP_PREG(IC_RESULT(ic))) {
8987         pic14_emitcode("dec","%s",
8988                  aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8989         pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8990         pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
8991     } else {    
8992
8993
8994       emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8995       emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
8996
8997       pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
8998       pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
8999
9000     }
9001 /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9002 /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9003 /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9004 /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9005
9006     
9007     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9008     ifx->generated = 1;
9009     return 1;
9010 }
9011
9012 /*-----------------------------------------------------------------*/
9013 /* genReceive - generate code for a receive iCode                  */
9014 /*-----------------------------------------------------------------*/
9015 static void genReceive (iCode *ic)
9016 {    
9017     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9018
9019     if (isOperandInFarSpace(IC_RESULT(ic)) && 
9020         ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9021           IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9022
9023         int size = getSize(operandType(IC_RESULT(ic)));
9024         int offset =  fReturnSizePic - size;
9025         while (size--) {
9026             pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9027                                     fReturn[fReturnSizePic - offset - 1] : "acc"));
9028             offset++;
9029         }
9030         aopOp(IC_RESULT(ic),ic,FALSE);  
9031         size = AOP_SIZE(IC_RESULT(ic));
9032         offset = 0;
9033         while (size--) {
9034             pic14_emitcode ("pop","acc");
9035             aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9036         }
9037         
9038     } else {
9039         _G.accInUse++;
9040         aopOp(IC_RESULT(ic),ic,FALSE);  
9041         _G.accInUse--;
9042         assignResultValue(IC_RESULT(ic));       
9043     }
9044
9045     freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9046 }
9047
9048 /*-----------------------------------------------------------------*/
9049 /* genpic14Code - generate code for pic14 based controllers        */
9050 /*-----------------------------------------------------------------*/
9051 /*
9052  * At this point, ralloc.c has gone through the iCode and attempted
9053  * to optimize in a way suitable for a PIC. Now we've got to generate
9054  * PIC instructions that correspond to the iCode.
9055  *
9056  * Once the instructions are generated, we'll pass through both the
9057  * peep hole optimizer and the pCode optimizer.
9058  *-----------------------------------------------------------------*/
9059
9060 void genpic14Code (iCode *lic)
9061 {
9062     iCode *ic;
9063     int cln = 0;
9064
9065     lineHead = lineCurr = NULL;
9066
9067     pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9068     addpBlock(pb);
9069
9070     /* if debug information required */
9071 /*     if (options.debug && currFunc) { */
9072     if (currFunc) {
9073         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9074         _G.debugLine = 1;
9075         if (IS_STATIC(currFunc->etype)) {
9076             pic14_emitcode("",";F%s$%s$0$0     %d",moduleName,currFunc->name,__LINE__);
9077             //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9078         } else {
9079             pic14_emitcode("",";G$%s$0$0   %d",currFunc->name,__LINE__);
9080             //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9081         }
9082         _G.debugLine = 0;
9083     }
9084
9085
9086     for (ic = lic ; ic ; ic = ic->next ) {
9087
9088       DEBUGpic14_emitcode(";ic","");
9089         if ( cln != ic->lineno ) {
9090             if ( options.debug ) {
9091                 _G.debugLine = 1;
9092                 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9093                          FileBaseName(ic->filename),ic->lineno,
9094                          ic->level,ic->block);
9095                 _G.debugLine = 0;
9096             }
9097             pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9098             cln = ic->lineno ;
9099         }
9100         /* if the result is marked as
9101            spilt and rematerializable or code for
9102            this has already been generated then
9103            do nothing */
9104         if (resultRemat(ic) || ic->generated ) 
9105             continue ;
9106         
9107         /* depending on the operation */
9108         switch (ic->op) {
9109         case '!' :
9110             genNot(ic);
9111             break;
9112             
9113         case '~' :
9114             genCpl(ic);
9115             break;
9116             
9117         case UNARYMINUS:
9118             genUminus (ic);
9119             break;
9120             
9121         case IPUSH:
9122             genIpush (ic);
9123             break;
9124             
9125         case IPOP:
9126             /* IPOP happens only when trying to restore a 
9127                spilt live range, if there is an ifx statement
9128                following this pop then the if statement might
9129                be using some of the registers being popped which
9130                would destory the contents of the register so
9131                we need to check for this condition and handle it */
9132             if (ic->next            && 
9133                 ic->next->op == IFX &&
9134                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9135                 genIfx (ic->next,ic);
9136             else
9137                 genIpop (ic);
9138             break; 
9139             
9140         case CALL:
9141             genCall (ic);
9142             break;
9143             
9144         case PCALL:
9145             genPcall (ic);
9146             break;
9147             
9148         case FUNCTION:
9149             genFunction (ic);
9150             break;
9151             
9152         case ENDFUNCTION:
9153             genEndFunction (ic);
9154             break;
9155             
9156         case RETURN:
9157             genRet (ic);
9158             break;
9159             
9160         case LABEL:
9161             genLabel (ic);
9162             break;
9163             
9164         case GOTO:
9165             genGoto (ic);
9166             break;
9167             
9168         case '+' :
9169             genPlus (ic) ;
9170             break;
9171             
9172         case '-' :
9173             if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9174                 genMinus (ic);
9175             break;
9176             
9177         case '*' :
9178             genMult (ic);
9179             break;
9180             
9181         case '/' :
9182             genDiv (ic) ;
9183             break;
9184             
9185         case '%' :
9186             genMod (ic);
9187             break;
9188             
9189         case '>' :
9190             genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));                 
9191             break;
9192             
9193         case '<' :
9194             genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9195             break;
9196             
9197         case LE_OP:
9198         case GE_OP:
9199         case NE_OP:
9200             
9201             /* note these two are xlated by algebraic equivalence
9202                during parsing SDCC.y */
9203             werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9204                    "got '>=' or '<=' shouldn't have come here");
9205             break;      
9206             
9207         case EQ_OP:
9208             genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9209             break;          
9210             
9211         case AND_OP:
9212             genAndOp (ic);
9213             break;
9214             
9215         case OR_OP:
9216             genOrOp (ic);
9217             break;
9218             
9219         case '^' :
9220             genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9221             break;
9222             
9223         case '|' :
9224                 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9225             break;
9226             
9227         case BITWISEAND:
9228             genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9229             break;
9230             
9231         case INLINEASM:
9232             genInline (ic);
9233             break;
9234             
9235         case RRC:
9236             genRRC (ic);
9237             break;
9238             
9239         case RLC:
9240             genRLC (ic);
9241             break;
9242             
9243         case GETHBIT:
9244             genGetHbit (ic);
9245             break;
9246             
9247         case LEFT_OP:
9248             genLeftShift (ic);
9249             break;
9250             
9251         case RIGHT_OP:
9252             genRightShift (ic);
9253             break;
9254             
9255         case GET_VALUE_AT_ADDRESS:
9256             genPointerGet(ic);
9257             break;
9258             
9259         case '=' :
9260             if (POINTER_SET(ic))
9261                 genPointerSet(ic);
9262             else
9263                 genAssign(ic);
9264             break;
9265             
9266         case IFX:
9267             genIfx (ic,NULL);
9268             break;
9269             
9270         case ADDRESS_OF:
9271             genAddrOf (ic);
9272             break;
9273             
9274         case JUMPTABLE:
9275             genJumpTab (ic);
9276             break;
9277             
9278         case CAST:
9279             genCast (ic);
9280             break;
9281             
9282         case RECEIVE:
9283             genReceive(ic);
9284             break;
9285             
9286         case SEND:
9287             addSet(&_G.sendSet,ic);
9288             break;
9289
9290         default :
9291             ic = ic;
9292         }
9293     }
9294     
9295
9296     /* now we are ready to call the 
9297        peep hole optimizer */
9298     if (!options.nopeep) {
9299       printf("peep hole optimizing\n");
9300         peepHole (&lineHead);
9301     }
9302     /* now do the actual printing */
9303     printLine (lineHead,codeOutFile);
9304
9305     printf("printing pBlock\n\n");
9306     printpBlock(stdout,pb);
9307
9308     return;
9309 }