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