tidied it up a little.
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   gen.c - source file for code generation for pic
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh  Moved aopLiteral to SDCCglue.c to help the split
29       Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #include "common.h"
40 #include "SDCCpeeph.h"
41 #include "ralloc.h"
42 #include "pcode.h"
43 #include "gen.h"
44
45
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
51
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
55
56 /* max_key keeps track of the largest label number used in 
57 a function. This is then used to adjust the label offset
58 for the next function.
59 */
60 static int max_key=0;
61 static int GpsuedoStkPtr=0;
62
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
67
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69
70 /* this is the down and dirty file with all kinds of 
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
74
75 static char *zero = "#0x00";
76 static char *one  = "#0x01";
77 static char *spname = "sp";
78
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
81 static char **fReturn = fReturnpic14;
82
83 static char *accUse[] = {"a","b"};
84
85 //static short rbank = -1;
86
87 static struct {
88         short r0Pushed;
89         short r1Pushed;
90         short accInUse;
91         short inLine;
92         short debugLine;
93         short nRegsSaved;
94         set *sendSet;
95 } _G;
96
97 /* Resolved ifx structure. This structure stores information
98 about an iCode ifx that makes it easier to generate code.
99 */
100 typedef struct resolvedIfx {
101         symbol *lbl;       /* pointer to a label */
102         int condition;   /* true or false ifx */
103                                          int generated;   /* set true when the code associated with the ifx
104                                          * is generated */
105 } resolvedIfx;
106
107 extern int pic14_ptrRegReq ;
108 extern int pic14_nRegs;
109 extern FILE *codeOutFile;
110 static void saverbank (int, iCode *,bool);
111
112 static lineNode *lineHead = NULL;
113 static lineNode *lineCurr = NULL;
114
115 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
116 0xE0, 0xC0, 0x80, 0x00};
117 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
118 0x07, 0x03, 0x01, 0x00};
119
120 static  pBlock *pb;
121
122 /*-----------------------------------------------------------------*/
123 /*      my_powof2(n) - If `n' is an integaer power of 2, then the          */
124 /*                                 exponent of 2 is returned, otherwise -1 is      */
125 /*                                 returned.                                                                       */
126 /* note that this is similar to the function `powof2' in SDCCsymt  */
127 /* if(n == 2^y)                                                                                                    */
128 /*       return y;                                                                                                         */
129 /* return -1;                                                                                                      */
130 /*-----------------------------------------------------------------*/
131 static int my_powof2 (unsigned long num)
132 {
133         if(num) {
134                 if( (num & (num-1)) == 0) {
135                         int nshifts = -1;
136                         while(num) {
137                                 num>>=1;
138                                 nshifts++;
139                         }
140                         return nshifts;
141                 }
142         }
143         
144         return -1;
145 }
146
147 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
148 {
149         
150         DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
151                 line_no,
152                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
153                 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
154                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
155                 ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
156                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
157                 ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
158                 ((result) ? AOP_SIZE(result) : 0));
159         
160 }
161
162 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
163 {
164         
165         DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
166                 line_no,
167                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
168                 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
169                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
170                 ((left)   ? (SPEC_USIGN(operandType(left))       ? 'u' : 's') : '-'),
171                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
172                 ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
173         
174 }
175
176 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
177 {
178         va_list ap;
179         char lb[INITIAL_INLINEASM];  
180         char *lbp = lb;
181         
182         if(!debug_verbose)
183                 return;
184         
185         va_start(ap,fmt);   
186         
187         if (inst && *inst) {
188                 if (fmt && *fmt)
189                         sprintf(lb,"%s\t",inst);
190                 else
191                         sprintf(lb,"%s",inst);
192                 vsprintf(lb+(strlen(lb)),fmt,ap);
193         }  else
194                 vsprintf(lb,fmt,ap);
195         
196         while (isspace(*lbp)) lbp++;
197         
198         if (lbp && *lbp) 
199                 lineCurr = (lineCurr ?
200                 connectLine(lineCurr,newLineNode(lb)) :
201         (lineHead = newLineNode(lb)));
202         lineCurr->isInline = _G.inLine;
203         lineCurr->isDebug  = _G.debugLine;
204         
205         addpCode2pBlock(pb,newpCodeCharP(lb));
206         
207         va_end(ap);
208 }
209
210
211 void emitpLabel(int key)
212 {
213         addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
214 }
215
216 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 {
218         if(pcop)
219                 addpCode2pBlock(pb,newpCode(poc,pcop));
220         else
221                 DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
222 }
223
224 void emitpcodeNULLop(PIC_OPCODE poc)
225 {
226         
227         addpCode2pBlock(pb,newpCode(poc,NULL));
228         
229 }
230
231
232 /*-----------------------------------------------------------------*/
233 /* pic14_emitcode - writes the code into a file : for now it is simple    */
234 /*-----------------------------------------------------------------*/
235 void pic14_emitcode (char *inst,char *fmt, ...)
236 {
237         va_list ap;
238         char lb[INITIAL_INLINEASM];  
239         char *lbp = lb;
240         
241         va_start(ap,fmt);   
242         
243         if (inst && *inst) {
244                 if (fmt && *fmt)
245                         sprintf(lb,"%s\t",inst);
246                 else
247                         sprintf(lb,"%s",inst);
248                 vsprintf(lb+(strlen(lb)),fmt,ap);
249         }  else
250                 vsprintf(lb,fmt,ap);
251         
252         while (isspace(*lbp)) lbp++;
253         
254         if (lbp && *lbp) 
255                 lineCurr = (lineCurr ?
256                 connectLine(lineCurr,newLineNode(lb)) :
257         (lineHead = newLineNode(lb)));
258         lineCurr->isInline = _G.inLine;
259         lineCurr->isDebug  = _G.debugLine;
260         
261         if(debug_verbose)
262                 addpCode2pBlock(pb,newpCodeCharP(lb));
263         
264         va_end(ap);
265 }
266
267 /*-----------------------------------------------------------------*/
268 /* pic14_emitDebuggerSymbol - associate the current code location  */
269 /*       with a debugger symbol                                                                            */
270 /*-----------------------------------------------------------------*/
271 void
272 pic14_emitDebuggerSymbol (char * debugSym)
273 {
274         _G.debugLine = 1;
275         pic14_emitcode ("", ";%s ==.", debugSym);
276         _G.debugLine = 0;
277 }
278
279
280 /*-----------------------------------------------------------------*/
281 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
282 /*-----------------------------------------------------------------*/
283 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
284 {
285         bool r0iu = FALSE , r1iu = FALSE;
286         bool r0ou = FALSE , r1ou = FALSE;
287         
288         /* the logic: if r0 & r1 used in the instruction
289         then we are in trouble otherwise */
290         
291         /* first check if r0 & r1 are used by this
292         instruction, in which case we are in trouble */
293         if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
294                 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
295         {
296                 goto endOfWorld;          
297         }
298         
299         r0ou = bitVectBitValue(ic->rMask,R0_IDX);
300         r1ou = bitVectBitValue(ic->rMask,R1_IDX);
301         
302         /* if no usage of r0 then return it */
303         if (!r0iu && !r0ou) {
304                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
305                 (*aopp)->type = AOP_R0;
306                 
307                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
308         }
309         
310         /* if no usage of r1 then return it */
311         if (!r1iu && !r1ou) {
312                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
313                 (*aopp)->type = AOP_R1;
314                 
315                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
316         }    
317         
318         /* now we know they both have usage */
319         /* if r0 not used in this instruction */
320         if (!r0iu) {
321                 /* push it if not already pushed */
322                 if (!_G.r0Pushed) {
323                         //pic14_emitcode ("push","%s",
324                         //                pic14_regWithIdx(R0_IDX)->dname);
325                         _G.r0Pushed++ ;
326                 }
327                 
328                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
329                 (*aopp)->type = AOP_R0;
330                 
331                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
332         }
333         
334         /* if r1 not used then */
335         
336         if (!r1iu) {
337                 /* push it if not already pushed */
338                 if (!_G.r1Pushed) {
339                         //pic14_emitcode ("push","%s",
340                         //                pic14_regWithIdx(R1_IDX)->dname);
341                         _G.r1Pushed++ ;
342                 }
343                 
344                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
345                 (*aopp)->type = AOP_R1;
346                 return pic14_regWithIdx(R1_IDX);
347         }
348         
349 endOfWorld :
350         /* I said end of world but not quite end of world yet */
351         /* if this is a result then we can push it on the stack*/
352         if (result) {
353                 (*aopp)->type = AOP_STK;        
354                 return NULL;
355         }
356         
357         /* other wise this is true end of the world */
358         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
359                 "getFreePtr should never reach here");
360         exit(0);
361 }
362
363 /*-----------------------------------------------------------------*/
364 /* newAsmop - creates a new asmOp                                                                  */
365 /*-----------------------------------------------------------------*/
366 asmop *newAsmop (short type)
367 {
368         asmop *aop;
369         
370         aop = Safe_calloc(1,sizeof(asmop));
371         aop->type = type;
372         return aop;
373 }
374
375 static void genSetDPTR(int n)
376 {
377         if (!n)
378         {
379                 pic14_emitcode(";", "Select standard DPTR");
380                 pic14_emitcode("mov", "dps, #0x00");
381         }
382         else
383         {
384                 pic14_emitcode(";", "Select alternate DPTR");
385                 pic14_emitcode("mov", "dps, #0x01");
386         }
387 }
388
389 /*-----------------------------------------------------------------*/
390 /* resolveIfx - converts an iCode ifx into a form more useful for  */
391 /*                              generating code                                                                    */
392 /*-----------------------------------------------------------------*/
393 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
394 {
395         if(!resIfx) 
396                 return;
397         
398         //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
399         
400         resIfx->condition = 1;  /* assume that the ifx is true */
401         resIfx->generated = 0;  /* indicate that the ifx has not been used */
402         
403         if(!ifx) {
404                 resIfx->lbl = newiTempLabel(NULL);      /* oops, there is no ifx. so create a label */
405                                                                                         /*
406                                                                                         DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
407                                                                                         __FUNCTION__,__LINE__,resIfx->lbl->key);
408                 */
409         } else {
410                 if(IC_TRUE(ifx)) {
411                         resIfx->lbl = IC_TRUE(ifx);
412                 } else {
413                         resIfx->lbl = IC_FALSE(ifx);
414                         resIfx->condition = 0;
415                 }
416                 /*
417                 if(IC_TRUE(ifx)) 
418                 DEBUGpic14_emitcode("; ***","ifx true is non-null");
419                 if(IC_FALSE(ifx)) 
420                 DEBUGpic14_emitcode("; ***","ifx false is non-null");
421                 */
422         }
423         
424         //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
425         
426 }
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type                       */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
431 {
432         
433         return PTR_TYPE(SPEC_OCLS(etype));
434         
435 }
436
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol                                                                   */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
441 {
442         asmop *aop;
443         memmap *space= SPEC_OCLS(sym->etype);
444         
445         DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446         /* if already has one */
447         if (sym->aop)
448                 return sym->aop;
449         
450         /* assign depending on the storage class */
451         /* if it is on the stack or indirectly addressable */
452         /* space we need to assign either r0 or r1 to it         */    
453         if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454                 sym->aop = aop = newAsmop(0);
455                 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456                 aop->size = getSize(sym->type);
457                 
458                 /* now assign the address of the variable to 
459                 the pointer register */
460                 if (aop->type != AOP_STK) {
461                         
462                         if (sym->onStack) {
463                                 if ( _G.accInUse )
464                                         pic14_emitcode("push","acc");
465                                 
466                                 pic14_emitcode("mov","a,_bp");
467                                 pic14_emitcode("add","a,#0x%02x",
468                                         ((sym->stack < 0) ?
469                                         ((char)(sym->stack - _G.nRegsSaved )) :
470                                 ((char)sym->stack)) & 0xff);
471                                 pic14_emitcode("mov","%s,a",
472                                         aop->aopu.aop_ptr->name);
473                                 
474                                 if ( _G.accInUse )
475                                         pic14_emitcode("pop","acc");
476                         } else
477                                 pic14_emitcode("mov","%s,#%s",
478                                 aop->aopu.aop_ptr->name,
479                                 sym->rname);
480                         aop->paged = space->paged;
481                 } else
482                         aop->aopu.aop_stk = sym->stack;
483                 return aop;
484         }
485         
486         if (sym->onStack && options.stack10bit)
487         {
488         /* It's on the 10 bit stack, which is located in
489         * far data space.
490                 */
491                 
492                 //DEBUGpic14_emitcode(";","%d",__LINE__);
493                 
494                 if ( _G.accInUse )
495                         pic14_emitcode("push","acc");
496                 
497                 pic14_emitcode("mov","a,_bp");
498                 pic14_emitcode("add","a,#0x%02x",
499                         ((sym->stack < 0) ?
500                         ((char)(sym->stack - _G.nRegsSaved )) :
501                 ((char)sym->stack)) & 0xff);
502                 
503                 genSetDPTR(1);
504                 pic14_emitcode ("mov","dpx1,#0x40");
505                 pic14_emitcode ("mov","dph1,#0x00");
506                 pic14_emitcode ("mov","dpl1, a");
507                 genSetDPTR(0);
508                 
509                 if ( _G.accInUse )
510                         pic14_emitcode("pop","acc");
511                 
512                 sym->aop = aop = newAsmop(AOP_DPTR2);
513                 aop->size = getSize(sym->type); 
514                 return aop;
515         }
516         
517         //DEBUGpic14_emitcode(";","%d",__LINE__);
518         /* if in bit space */
519         if (IN_BITSPACE(space)) {
520                 sym->aop = aop = newAsmop (AOP_CRY);
521                 aop->aopu.aop_dir = sym->rname ;
522                 aop->size = getSize(sym->type);
523                 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524                 return aop;
525         }
526         /* if it is in direct space */
527         if (IN_DIRSPACE(space)) {
528                 sym->aop = aop = newAsmop (AOP_DIR);
529                 aop->aopu.aop_dir = sym->rname ;
530                 aop->size = getSize(sym->type);
531                 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
532                 return aop;
533         }
534         
535         /* special case for a function */
536         if (IS_FUNC(sym->type)) {   
537                 
538                 sym->aop = aop = newAsmop(AOP_PCODE);
539                 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
540                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
541                 PCOI(aop->aopu.pcop)->_function = 1;
542                 PCOI(aop->aopu.pcop)->index = 0;
543                 aop->size = FPTRSIZE; 
544                 /*
545                 sym->aop = aop = newAsmop(AOP_IMMD);    
546                 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
547                 strcpy(aop->aopu.aop_immd,sym->rname);
548                 aop->size = FPTRSIZE; 
549                 */
550                 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
551                 return aop;
552         }
553         
554         
555         /* only remaining is far space */
556         /* in which case DPTR gets the address */
557         sym->aop = aop = newAsmop(AOP_PCODE);
558         
559         aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
560         PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
561         PCOI(aop->aopu.pcop)->index = 0;
562         
563         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
564                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
565         
566         allocDirReg (IC_LEFT(ic));
567         
568         aop->size = FPTRSIZE; 
569         /*
570         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
571         sym->aop = aop = newAsmop(AOP_DPTR);
572         pic14_emitcode ("mov","dptr,#%s", sym->rname);
573         aop->size = getSize(sym->type);
574         
575           DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
576         */
577         
578         /* if it is in code space */
579         if (IN_CODESPACE(space))
580                 aop->code = 1;
581         
582         return aop;       
583 }
584
585 /*-----------------------------------------------------------------*/
586 /* aopForRemat - rematerialzes an object                                                   */
587 /*-----------------------------------------------------------------*/
588 static asmop *aopForRemat (operand *op) // x symbol *sym)
589 {
590         symbol *sym = OP_SYMBOL(op);
591         iCode *ic = NULL;
592         asmop *aop = newAsmop(AOP_PCODE);
593         int val = 0;
594         int offset = 0;
595         
596         ic = sym->rematiCode;
597         
598         DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
599         if(IS_OP_POINTER(op)) {
600                 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
601         }
602         for (;;) {
603                 if (ic->op == '+') {
604                         val += (int) operandLitValue(IC_RIGHT(ic));
605                 } else if (ic->op == '-') {
606                         val -= (int) operandLitValue(IC_RIGHT(ic));
607                 } else
608                         break;
609                 
610                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
611         }
612         
613         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
614         aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
615         PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
616         PCOI(aop->aopu.pcop)->index = val;
617         
618         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
619                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
620                 val, IS_PTR_CONST(operandType(op)));
621         
622         //      DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
623         
624         allocDirReg (IC_LEFT(ic));
625         
626         return aop;              
627 }
628
629 int aopIdx (asmop *aop, int offset)
630 {
631         if(!aop)
632                 return -1;
633         
634         if(aop->type !=  AOP_REG)
635                 return -2;
636         
637         return aop->aopu.aop_reg[offset]->rIdx;
638         
639 }
640 /*-----------------------------------------------------------------*/
641 /* regsInCommon - two operands have some registers in common       */
642 /*-----------------------------------------------------------------*/
643 static bool regsInCommon (operand *op1, operand *op2)
644 {
645         symbol *sym1, *sym2;
646         int i;
647         
648         /* if they have registers in common */
649         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
650                 return FALSE ;
651         
652         sym1 = OP_SYMBOL(op1);
653         sym2 = OP_SYMBOL(op2);
654         
655         if (sym1->nRegs == 0 || sym2->nRegs == 0)
656                 return FALSE ;
657         
658         for (i = 0 ; i < sym1->nRegs ; i++) {
659                 int j;
660                 if (!sym1->regs[i])
661                         continue ;
662                 
663                 for (j = 0 ; j < sym2->nRegs ;j++ ) {
664                         if (!sym2->regs[j])
665                                 continue ;
666                         
667                         if (sym2->regs[j] == sym1->regs[i])
668                                 return TRUE ;
669                 }
670         }
671         
672         return FALSE ;
673 }
674
675 /*-----------------------------------------------------------------*/
676 /* operandsEqu - equivalent                                                                        */
677 /*-----------------------------------------------------------------*/
678 static bool operandsEqu ( operand *op1, operand *op2)
679 {
680         symbol *sym1, *sym2;
681         
682         /* if they not symbols */
683         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
684                 return FALSE;
685         
686         sym1 = OP_SYMBOL(op1);
687         sym2 = OP_SYMBOL(op2);
688         
689         /* if both are itemps & one is spilt
690         and the other is not then false */
691         if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
692                 sym1->isspilt != sym2->isspilt )
693                 return FALSE ;
694         
695         /* if they are the same */
696         if (sym1 == sym2)
697                 return TRUE ;
698         
699         if (sym1->rname[0] && sym2->rname[0]
700                 && strcmp (sym1->rname, sym2->rname) == 0)
701                 return TRUE;
702         
703         
704         /* if left is a tmp & right is not */
705         if (IS_ITEMP(op1)  && 
706                 !IS_ITEMP(op2) &&
707                 sym1->isspilt  &&
708                 (sym1->usl.spillLoc == sym2))
709                 return TRUE;
710         
711         if (IS_ITEMP(op2)  && 
712                 !IS_ITEMP(op1) &&
713                 sym2->isspilt  &&
714                 sym1->level > 0 &&
715                 (sym2->usl.spillLoc == sym1))
716                 return TRUE ;
717         
718         return FALSE ;
719 }
720
721 /*-----------------------------------------------------------------*/
722 /* pic14_sameRegs - two asmops have the same registers             */
723 /*-----------------------------------------------------------------*/
724 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
725 {
726         int i;
727         
728         if (aop1 == aop2)
729                 return TRUE ;
730         
731         if (aop1->type != AOP_REG ||
732                 aop2->type != AOP_REG )
733                 return FALSE ;
734         
735         if (aop1->size != aop2->size )
736                 return FALSE ;
737         
738         for (i = 0 ; i < aop1->size ; i++ )
739                 if (aop1->aopu.aop_reg[i] !=
740                         aop2->aopu.aop_reg[i] )
741                         return FALSE ;
742                 
743                 return TRUE ;
744 }
745
746 /*-----------------------------------------------------------------*/
747 /* aopOp - allocates an asmop for an operand  :                    */
748 /*-----------------------------------------------------------------*/
749 void aopOp (operand *op, iCode *ic, bool result)
750 {
751         asmop *aop;
752         symbol *sym;
753         int i;
754         
755         if (!op)
756                 return ;
757         
758         /* if this a literal */
759         if (IS_OP_LITERAL(op)) {
760                 op->aop = aop = newAsmop(AOP_LIT);
761                 aop->aopu.aop_lit = op->operand.valOperand;
762                 aop->size = getSize(operandType(op));
763                 return;
764         }
765         
766         {
767                 sym_link *type = operandType(op);
768                 if(IS_PTR_CONST(type))
769                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
770         }
771         
772         /* if already has a asmop then continue */
773         if (op->aop)
774                 return ;
775         
776         /* if the underlying symbol has a aop */
777         if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
778                 DEBUGpic14_emitcode(";","%d",__LINE__);
779                 op->aop = OP_SYMBOL(op)->aop;
780                 return;
781         }
782         
783         /* if this is a true symbol */
784         if (IS_TRUE_SYMOP(op)) {          
785                 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
786                 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
787                 return ;
788         }
789         
790         /* this is a temporary : this has
791         only four choices :
792         a) register
793         b) spillocation
794         c) rematerialize 
795         d) conditional   
796         e) can be a return use only */
797         
798         sym = OP_SYMBOL(op);
799         
800         
801         /* if the type is a conditional */
802         if (sym->regType == REG_CND) {
803                 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
804                 aop->size = 0;
805                 return;
806         }
807         
808         /* if it is spilt then two situations
809         a) is rematerialize 
810         b) has a spill location */
811         if (sym->isspilt || sym->nRegs == 0) {
812                 
813                 DEBUGpic14_emitcode(";","%d",__LINE__);
814                 /* rematerialize it NOW */
815                 if (sym->remat) {
816                         
817                         sym->aop = op->aop = aop = aopForRemat (op);
818                         aop->size = getSize(sym->type);
819                         //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
820                         return;
821                 }
822                 
823                 if (sym->accuse) {
824                         int i;
825                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
826                         aop->size = getSize(sym->type);
827                         for ( i = 0 ; i < 2 ; i++ )
828                                 aop->aopu.aop_str[i] = accUse[i];
829                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
830                         return;  
831                 }
832                 
833                 if (sym->ruonly ) {
834                         if(sym->isptr) {        // && sym->uptr 
835                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
836                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
837                                 
838                                 //PCOI(aop->aopu.pcop)->_const = 0;
839                                 //PCOI(aop->aopu.pcop)->index = 0;
840                                 /*
841                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
842                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
843                                 */
844                                 //allocDirReg (IC_LEFT(ic));
845                                 
846                                 aop->size = getSize(sym->type);
847                                 DEBUGpic14_emitcode(";","%d",__LINE__);
848                                 return;
849                                 
850                         } else {
851                                 
852                                 unsigned i;
853                                 
854                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
855                                 aop->size = getSize(sym->type);
856                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
857                                         aop->aopu.aop_str[i] = fReturn[i];
858                                 
859                                 DEBUGpic14_emitcode(";","%d",__LINE__);
860                                 return;
861                         }
862                 }
863                 
864                 /* else spill location  */
865                 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
866                         /* force a new aop if sizes differ */
867                         sym->usl.spillLoc->aop = NULL;
868                 }
869                 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
870                         __FUNCTION__,__LINE__,
871                         sym->usl.spillLoc->rname,
872                         sym->rname, sym->usl.spillLoc->offset);
873                 
874                 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
875                 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
876                 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
877                         getSize(sym->type), 
878                         sym->usl.spillLoc->offset);
879                 aop->size = getSize(sym->type);
880                 
881                 return;
882         }
883         
884         {
885                 sym_link *type = operandType(op);
886                 if(IS_PTR_CONST(type)) 
887                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
888         }
889         
890         /* must be in a register */
891         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
892         sym->aop = op->aop = aop = newAsmop(AOP_REG);
893         aop->size = sym->nRegs;
894         for ( i = 0 ; i < sym->nRegs ;i++)
895                 aop->aopu.aop_reg[i] = sym->regs[i];
896 }
897
898 /*-----------------------------------------------------------------*/
899 /* freeAsmop - free up the asmop given to an operand                       */
900 /*----------------------------------------------------------------*/
901 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
902 {       
903         asmop *aop ;
904         
905         if (!op)
906                 aop = aaop;
907         else 
908                 aop = op->aop;
909         
910         if (!aop)
911                 return ;
912         
913         if (aop->freed)
914                 goto dealloc; 
915         
916         aop->freed = 1;
917         
918         /* depending on the asmop type only three cases need work AOP_RO
919         , AOP_R1 && AOP_STK */
920 #if 0
921         switch (aop->type) {
922         case AOP_R0 :
923                 if (_G.r0Pushed ) {
924                         if (pop) {
925                                 pic14_emitcode ("pop","ar0");     
926                                 _G.r0Pushed--;
927                         }
928                 }
929                 bitVectUnSetBit(ic->rUsed,R0_IDX);
930                 break;
931                 
932         case AOP_R1 :
933                 if (_G.r1Pushed ) {
934                         if (pop) {
935                                 pic14_emitcode ("pop","ar1");
936                                 _G.r1Pushed--;
937                         }
938                 }
939                 bitVectUnSetBit(ic->rUsed,R1_IDX);                      
940                 break;
941                 
942         case AOP_STK :
943                 {
944                         int sz = aop->size;      
945                         int stk = aop->aopu.aop_stk + aop->size;
946                         bitVectUnSetBit(ic->rUsed,R0_IDX);
947                         bitVectUnSetBit(ic->rUsed,R1_IDX);                
948                         
949                         getFreePtr(ic,&aop,FALSE);
950                         
951                         if (options.stack10bit)
952                         {
953                                 /* I'm not sure what to do here yet... */
954                                 /* #STUB */
955                                 fprintf(stderr, 
956                                         "*** Warning: probably generating bad code for "
957                                         "10 bit stack mode.\n");
958                         }
959                         
960                         if (stk) {
961                                 pic14_emitcode ("mov","a,_bp");
962                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
963                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
964                         } else {
965                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
966                         }
967                         
968                         while (sz--) {
969                                 pic14_emitcode("pop","acc");
970                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
971                                 if (!sz) break;
972                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
973                         }
974                         op->aop = aop;
975                         freeAsmop(op,NULL,ic,TRUE);
976                         if (_G.r0Pushed) {
977                                 pic14_emitcode("pop","ar0");
978                                 _G.r0Pushed--;
979                         }
980                         
981                         if (_G.r1Pushed) {
982                                 pic14_emitcode("pop","ar1");
983                                 _G.r1Pushed--;
984                         }         
985                 }
986         }
987 #endif
988         
989 dealloc:
990         /* all other cases just dealloc */
991         if (op ) {
992                 op->aop = NULL;
993                 if (IS_SYMOP(op)) {
994                         OP_SYMBOL(op)->aop = NULL;      
995                         /* if the symbol has a spill */
996                         if (SPIL_LOC(op))
997                                 SPIL_LOC(op)->aop = NULL;
998                 }
999         }
1000 }
1001
1002 /*-----------------------------------------------------------------*/
1003 /* aopGet - for fetching value of the aop                                                  */
1004 /*-----------------------------------------------------------------*/
1005 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1006 {
1007         char *s = buffer ;
1008         char *rs;
1009         
1010         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1011         /* offset is greater than
1012         size then zero */
1013         if (offset > (aop->size - 1) &&
1014                 aop->type != AOP_LIT)
1015                 return zero;
1016         
1017         /* depending on type */
1018         switch (aop->type) {
1019                 
1020         case AOP_R0:
1021         case AOP_R1:
1022                 DEBUGpic14_emitcode(";","%d",__LINE__);
1023                 /* if we need to increment it */           
1024                 while (offset > aop->coff) {            
1025                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
1026                         aop->coff++;
1027                 }
1028                 
1029                 while (offset < aop->coff) {
1030                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1031                         aop->coff--;
1032                 }
1033                 
1034                 aop->coff = offset ;
1035                 if (aop->paged) {
1036                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1037                         return (dname ? "acc" : "a");
1038                 }               
1039                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1040                 rs = Safe_calloc(1,strlen(s)+1);
1041                 strcpy(rs,s);   
1042                 return rs;
1043                 
1044         case AOP_DPTR:
1045         case AOP_DPTR2:
1046                 DEBUGpic14_emitcode(";","%d",__LINE__);
1047                 if (aop->type == AOP_DPTR2)
1048                 {
1049                         genSetDPTR(1);
1050                 }
1051                 
1052                 while (offset > aop->coff) {
1053                         pic14_emitcode ("inc","dptr");
1054                         aop->coff++;
1055                 }
1056                 
1057                 while (offset < aop->coff) {            
1058                         pic14_emitcode("lcall","__decdptr");
1059                         aop->coff--;
1060                 }
1061                 
1062                 aop->coff = offset;
1063                 if (aop->code) {
1064                         pic14_emitcode("clr","a");
1065                         pic14_emitcode("movc","a,@a+dptr");
1066                 }
1067                 else {
1068                         pic14_emitcode("movx","a,@dptr");
1069                 }
1070                 
1071                 if (aop->type == AOP_DPTR2)
1072                 {
1073                         genSetDPTR(0);
1074                 }
1075                 
1076                 return (dname ? "acc" : "a");
1077                 
1078                 
1079         case AOP_IMMD:
1080                 if (bit16) 
1081                         sprintf (s,"%s",aop->aopu.aop_immd);
1082                 else
1083                         if (offset) 
1084                                 sprintf(s,"(%s >> %d)",
1085                                 aop->aopu.aop_immd,
1086                                 offset*8);
1087                         else
1088                                 sprintf(s,"%s",
1089                                 aop->aopu.aop_immd);
1090                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1091                         rs = Safe_calloc(1,strlen(s)+1);
1092                         strcpy(rs,s);   
1093                         return rs;
1094                         
1095         case AOP_DIR:
1096                 if (offset) {
1097                         sprintf(s,"(%s + %d)",
1098                                 aop->aopu.aop_dir,
1099                                 offset);
1100                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1101                 } else
1102                         sprintf(s,"%s",aop->aopu.aop_dir);
1103                 rs = Safe_calloc(1,strlen(s)+1);
1104                 strcpy(rs,s);   
1105                 return rs;
1106                 
1107         case AOP_REG:
1108                 //if (dname) 
1109                 //        return aop->aopu.aop_reg[offset]->dname;
1110                 //else
1111                 return aop->aopu.aop_reg[offset]->name;
1112                 
1113         case AOP_CRY:
1114                 //pic14_emitcode(";","%d",__LINE__);
1115                 return aop->aopu.aop_dir;
1116                 
1117         case AOP_ACC:
1118                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1119                 return "AOP_accumulator_bug";
1120                 
1121         case AOP_LIT:
1122                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1123                 rs = Safe_calloc(1,strlen(s)+1);
1124                 strcpy(rs,s);   
1125                 return rs;
1126                 
1127         case AOP_STR:
1128                 aop->coff = offset ;
1129                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1130                         dname)
1131                         return "acc";
1132                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1133                 
1134                 return aop->aopu.aop_str[offset];
1135                 
1136         case AOP_PCODE:
1137                 {
1138                         pCodeOp *pcop = aop->aopu.pcop;
1139                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1140                         if(pcop->name) {
1141                                 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1142                                 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1143                                 sprintf(s,"%s", pcop->name);
1144                         } else
1145                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1146                         
1147                 }
1148                 rs = Safe_calloc(1,strlen(s)+1);
1149                 strcpy(rs,s);   
1150                 return rs;
1151                 
1152   }
1153   
1154   werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1155           "aopget got unsupported aop->type");
1156   exit(0);
1157 }
1158
1159
1160 /*-----------------------------------------------------------------*/
1161 /* popGetTempReg - create a new temporary pCodeOp                                  */
1162 /*-----------------------------------------------------------------*/
1163 pCodeOp *popGetTempReg(void)
1164 {
1165         
1166         pCodeOp *pcop;
1167         
1168         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1169         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1170                 PCOR(pcop)->r->wasUsed=1;
1171                 PCOR(pcop)->r->isFree=0;
1172         }
1173         
1174         return pcop;
1175 }
1176
1177 /*-----------------------------------------------------------------*/
1178 /* popGetTempReg - create a new temporary pCodeOp                                  */
1179 /*-----------------------------------------------------------------*/
1180 void popReleaseTempReg(pCodeOp *pcop)
1181 {
1182         
1183         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1184                 PCOR(pcop)->r->isFree = 1;
1185         
1186 }
1187 /*-----------------------------------------------------------------*/
1188 /* popGetLabel - create a new pCodeOp of type PO_LABEL                     */
1189 /*-----------------------------------------------------------------*/
1190 pCodeOp *popGetLabel(unsigned int key)
1191 {
1192         
1193         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1194         
1195         if(key>(unsigned int)max_key)
1196                 max_key = key;
1197         
1198         return newpCodeOpLabel(NULL,key+100+labelOffset);
1199 }
1200
1201 /*-------------------------------------------------------------------*/
1202 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1203 /*-------------------------------------------------------------------*/
1204 pCodeOp *popGetHighLabel(unsigned int key)
1205 {
1206         pCodeOp *pcop;
1207         pcop = popGetLabel(key);
1208         PCOLAB(pcop)->offset = 1;
1209         return pcop;
1210 }
1211
1212 /*-----------------------------------------------------------------*/
1213 /* popGet - asm operator to pcode operator conversion                      */
1214 /*-----------------------------------------------------------------*/
1215 pCodeOp *popGetLit(unsigned int lit)
1216 {
1217         
1218         return newpCodeOpLit(lit);
1219 }
1220
1221 /*-----------------------------------------------------------------*/
1222 /* popGetImmd - asm operator to pcode immediate conversion                 */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1225 {
1226         
1227         return newpCodeOpImmd(name, offset,index, 0, is_func);
1228 }
1229
1230
1231 /*-----------------------------------------------------------------*/
1232 /* popGet - asm operator to pcode operator conversion                      */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *popGetWithString(char *str, int isExtern)
1235 {
1236         pCodeOp *pcop;
1237         
1238         
1239         if(!str) {
1240                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1241                 exit (1);
1242         }
1243         
1244         pcop = newpCodeOp(str,PO_STR);
1245         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1246         
1247         return pcop;
1248 }
1249
1250 /*-----------------------------------------------------------------*/
1251 /* popRegFromString -                                                                                      */
1252 /*-----------------------------------------------------------------*/
1253 pCodeOp *popRegFromString(char *str, int size, int offset)
1254 {
1255         
1256         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1257         pcop->type = PO_DIR;
1258         
1259         DEBUGpic14_emitcode(";","%d",__LINE__);
1260         
1261         if(!str)
1262                 str = "BAD_STRING";
1263         
1264         pcop->name = Safe_calloc(1,strlen(str)+1);
1265         strcpy(pcop->name,str);
1266         
1267         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1268         
1269         PCOR(pcop)->r = dirregWithName(pcop->name);
1270         if(PCOR(pcop)->r == NULL) {
1271                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1272                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1273                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1274         } else {
1275                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1276         }
1277         PCOR(pcop)->instance = offset;
1278         
1279         return pcop;
1280 }
1281
1282 /*-----------------------------------------------------------------*/
1283 /*-----------------------------------------------------------------*/
1284 pCodeOp *popRegFromIdx(int rIdx)
1285 {
1286         pCodeOp *pcop;
1287         
1288         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1289                 __FUNCTION__,__LINE__,rIdx);
1290         
1291         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1292         
1293         PCOR(pcop)->rIdx = rIdx;
1294         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1295         PCOR(pcop)->r->isFree = 0;
1296         PCOR(pcop)->r->wasUsed = 1;
1297         
1298         pcop->type = PCOR(pcop)->r->pc_type;
1299         
1300         
1301         return pcop;
1302 }
1303
1304 /*-----------------------------------------------------------------*/
1305 /* popGet - asm operator to pcode operator conversion                      */
1306 /*-----------------------------------------------------------------*/
1307 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1308 {
1309         //char *s = buffer ;
1310         //char *rs;
1311         
1312         pCodeOp *pcop;
1313         
1314         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1315         /* offset is greater than
1316         size then zero */
1317         
1318         if (offset > (aop->size - 1) &&
1319                 aop->type != AOP_LIT)
1320                 return NULL;  //zero;
1321         
1322         /* depending on type */
1323         switch (aop->type) {
1324                 
1325         case AOP_R0:
1326         case AOP_R1:
1327         case AOP_DPTR:
1328         case AOP_DPTR2:
1329         case AOP_ACC:
1330                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1331                 return NULL;
1332                 
1333         case AOP_IMMD:
1334                 DEBUGpic14_emitcode(";","%d",__LINE__);
1335                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1336                 
1337         case AOP_DIR:
1338                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1339 #if 0
1340                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1341                 pcop->type = PO_DIR;
1342                 
1343                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1344                 strcpy(pcop->name,aop->aopu.aop_dir);   
1345                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1346                 if(PCOR(pcop)->r == NULL) {
1347                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1348                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1349                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1350                 } else {
1351                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1352                 }
1353                 PCOR(pcop)->instance = offset;
1354                 
1355                 return pcop;
1356 #endif
1357                 
1358         case AOP_REG:
1359                 {
1360                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1361                         
1362                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1363                         PCOR(pcop)->rIdx = rIdx;
1364                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1365                         PCOR(pcop)->r->wasUsed=1;
1366                         PCOR(pcop)->r->isFree=0;
1367                         
1368                         PCOR(pcop)->instance = offset;
1369                         pcop->type = PCOR(pcop)->r->pc_type;
1370                         //rs = aop->aopu.aop_reg[offset]->name;
1371                         DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1372                         return pcop;
1373                 }
1374                 
1375         case AOP_CRY:
1376                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1377                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1378                 //if(PCOR(pcop)->r == NULL)
1379                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1380                 return pcop;
1381                 
1382         case AOP_LIT:
1383                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1384                 
1385         case AOP_STR:
1386                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1387                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1388                 /*
1389                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1390                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1391                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1392                 pcop->type = PCOR(pcop)->r->pc_type;
1393                 pcop->name = PCOR(pcop)->r->name;
1394                 
1395                   return pcop;
1396                 */
1397                 
1398         case AOP_PCODE:
1399                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1400                         __LINE__, 
1401                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1402                 pcop = pCodeOpCopy(aop->aopu.pcop);
1403                 PCOI(pcop)->offset = offset;
1404                 return pcop;
1405         }
1406         
1407         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1408                 "popGet got unsupported aop->type");
1409         exit(0);
1410 }
1411 /*-----------------------------------------------------------------*/
1412 /* aopPut - puts a string for a aop                                                        */
1413 /*-----------------------------------------------------------------*/
1414 void aopPut (asmop *aop, char *s, int offset)
1415 {
1416         char *d = buffer ;
1417         symbol *lbl ;
1418         
1419         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1420         
1421         if (aop->size && offset > ( aop->size - 1)) {
1422                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1423                         "aopPut got offset > aop->size");
1424                 exit(0);
1425         }
1426         
1427         /* will assign value to value */
1428         /* depending on where it is ofcourse */
1429         switch (aop->type) {
1430         case AOP_DIR:
1431                 if (offset) {
1432                         sprintf(d,"(%s + %d)",
1433                                 aop->aopu.aop_dir,offset);
1434                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1435                         
1436                 } else
1437                         sprintf(d,"%s",aop->aopu.aop_dir);
1438                 
1439                 if (strcmp(d,s)) {
1440                         DEBUGpic14_emitcode(";","%d",__LINE__);
1441                         if(strcmp(s,"W"))
1442                                 pic14_emitcode("movf","%s,w",s);
1443                         pic14_emitcode("movwf","%s",d);
1444                         
1445                         if(strcmp(s,"W")) {
1446                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1447                                 if(offset >= aop->size) {
1448                                         emitpcode(POC_CLRF,popGet(aop,offset));
1449                                         break;
1450                                 } else
1451                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1452                         }
1453                         
1454                         emitpcode(POC_MOVWF,popGet(aop,offset));
1455                         
1456                         
1457                 }
1458                 break;
1459                 
1460         case AOP_REG:
1461                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1462                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1463                         /*
1464                         if (*s == '@'             ||
1465                         strcmp(s,"r0") == 0 ||
1466                         strcmp(s,"r1") == 0 ||
1467                         strcmp(s,"r2") == 0 ||
1468                         strcmp(s,"r3") == 0 ||
1469                         strcmp(s,"r4") == 0 ||
1470                         strcmp(s,"r5") == 0 ||
1471                         strcmp(s,"r6") == 0 || 
1472                         strcmp(s,"r7") == 0 )
1473                         pic14_emitcode("mov","%s,%s  ; %d",
1474                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1475                         else
1476                         */
1477                         
1478                         if(strcmp(s,"W")==0 )
1479                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1480                         
1481                         pic14_emitcode("movwf","%s",
1482                                 aop->aopu.aop_reg[offset]->name);
1483                         
1484                         if(strcmp(s,zero)==0) {
1485                                 emitpcode(POC_CLRF,popGet(aop,offset));
1486                                 
1487                         } else if(strcmp(s,"W")==0) {
1488                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1489                                 pcop->type = PO_GPR_REGISTER;
1490                                 
1491                                 PCOR(pcop)->rIdx = -1;
1492                                 PCOR(pcop)->r = NULL;
1493                                 
1494                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1495                                 pcop->name = Safe_strdup(s);
1496                                 emitpcode(POC_MOVFW,pcop);
1497                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1498                         } else if(strcmp(s,one)==0) {
1499                                 emitpcode(POC_CLRF,popGet(aop,offset));
1500                                 emitpcode(POC_INCF,popGet(aop,offset));
1501                         } else {
1502                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1503                         }
1504                 }
1505                 break;
1506                 
1507         case AOP_DPTR:
1508         case AOP_DPTR2:
1509                 
1510                 if (aop->type == AOP_DPTR2)
1511                 {
1512                         genSetDPTR(1);
1513                 }
1514                 
1515                 if (aop->code) {
1516                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1517                                 "aopPut writting to code space");
1518                         exit(0);
1519                 }
1520                 
1521                 while (offset > aop->coff) {
1522                         aop->coff++;
1523                         pic14_emitcode ("inc","dptr");
1524                 }
1525                 
1526                 while (offset < aop->coff) {
1527                         aop->coff-- ;
1528                         pic14_emitcode("lcall","__decdptr");
1529                 }
1530                 
1531                 aop->coff = offset;
1532                 
1533                 /* if not in accumulater */
1534                 MOVA(s);
1535                 
1536                 pic14_emitcode ("movx","@dptr,a");
1537                 
1538                 if (aop->type == AOP_DPTR2)
1539                 {
1540                         genSetDPTR(0);
1541                 }
1542                 break;
1543                 
1544         case AOP_R0:
1545         case AOP_R1:
1546                 while (offset > aop->coff) {
1547                         aop->coff++;
1548                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1549                 }
1550                 while (offset < aop->coff) {
1551                         aop->coff-- ;
1552                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1553                 }
1554                 aop->coff = offset;
1555                 
1556                 if (aop->paged) {
1557                         MOVA(s);                         
1558                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1559                         
1560                 } else
1561                         if (*s == '@') {
1562                                 MOVA(s);
1563                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1564                         } else
1565                                 if (strcmp(s,"r0") == 0 ||
1566                                         strcmp(s,"r1") == 0 ||
1567                                         strcmp(s,"r2") == 0 ||
1568                                         strcmp(s,"r3") == 0 ||
1569                                         strcmp(s,"r4") == 0 ||
1570                                         strcmp(s,"r5") == 0 ||
1571                                         strcmp(s,"r6") == 0 || 
1572                                         strcmp(s,"r7") == 0 ) {
1573                                         char buffer[10];
1574                                         sprintf(buffer,"a%s",s);
1575                                         pic14_emitcode("mov","@%s,%s",
1576                                                 aop->aopu.aop_ptr->name,buffer);
1577                                 } else
1578                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1579                                 
1580                                 break;
1581                                 
1582         case AOP_STK:
1583                 if (strcmp(s,"a") == 0)
1584                         pic14_emitcode("push","acc");
1585                 else
1586                         pic14_emitcode("push","%s",s);
1587                 
1588                 break;
1589                 
1590         case AOP_CRY:
1591                 /* if bit variable */
1592                 if (!aop->aopu.aop_dir) {
1593                         pic14_emitcode("clr","a");
1594                         pic14_emitcode("rlc","a");
1595                 } else {
1596                         if (s == zero) 
1597                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1598                         else
1599                                 if (s == one)
1600                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1601                                 else
1602                                         if (!strcmp(s,"c"))
1603                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1604                                         else {
1605                                                 lbl = newiTempLabel(NULL);
1606                                                 
1607                                                 if (strcmp(s,"a")) {
1608                                                         MOVA(s);
1609                                                 }
1610                                                 pic14_emitcode("clr","c");
1611                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1612                                                 pic14_emitcode("cpl","c");
1613                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1614                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1615                                         }
1616                 }
1617                 break;
1618                 
1619         case AOP_STR:
1620                 aop->coff = offset;
1621                 if (strcmp(aop->aopu.aop_str[offset],s))
1622                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1623                 break;
1624                 
1625         case AOP_ACC:
1626                 aop->coff = offset;
1627                 if (!offset && (strcmp(s,"acc") == 0))
1628                         break;
1629                 
1630                 if (strcmp(aop->aopu.aop_str[offset],s))
1631                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1632                 break;
1633                 
1634         default :
1635                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1636                         "aopPut got unsupported aop->type");
1637                 exit(0);
1638         }
1639         
1640 }
1641
1642 /*-----------------------------------------------------------------*/
1643 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1644 /*-----------------------------------------------------------------*/
1645 void mov2w (asmop *aop, int offset)
1646 {
1647         
1648         if(!aop)
1649                 return;
1650         
1651         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1652         
1653         if ( aop->type == AOP_PCODE ||
1654                 aop->type == AOP_LIT ||
1655                 aop->type == AOP_IMMD )
1656                 emitpcode(POC_MOVLW,popGet(aop,offset));
1657         else
1658                 emitpcode(POC_MOVFW,popGet(aop,offset));
1659         
1660 }
1661
1662 /*-----------------------------------------------------------------*/
1663 /* reAdjustPreg - points a register back to where it should        */
1664 /*-----------------------------------------------------------------*/
1665 static void reAdjustPreg (asmop *aop)
1666 {
1667         int size ;
1668         
1669         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1670         aop->coff = 0;
1671         if ((size = aop->size) <= 1)
1672                 return ;
1673         size-- ;
1674         switch (aop->type) {
1675         case AOP_R0 :
1676         case AOP_R1 :
1677                 while (size--)
1678                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1679                 break;                  
1680         case AOP_DPTR :
1681         case AOP_DPTR2:
1682                 if (aop->type == AOP_DPTR2)
1683                 {
1684                         genSetDPTR(1);
1685                 } 
1686                 while (size--)
1687                 {
1688                         pic14_emitcode("lcall","__decdptr");
1689                 }
1690                 
1691                 if (aop->type == AOP_DPTR2)
1692                 {
1693                         genSetDPTR(0);
1694                 }
1695                 break;
1696                 
1697         }
1698         
1699 }
1700
1701
1702 #if 0
1703 /*-----------------------------------------------------------------*/
1704 /* opIsGptr: returns non-zero if the passed operand is             */
1705 /* a generic pointer type.                                         */
1706 /*-----------------------------------------------------------------*/ 
1707 static int opIsGptr(operand *op)
1708 {
1709         sym_link *type = operandType(op);
1710         
1711         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1712         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1713         {
1714                 return 1;
1715         }
1716         return 0;          
1717 }
1718 #endif
1719
1720 /*-----------------------------------------------------------------*/
1721 /* pic14_getDataSize - get the operand data size                   */
1722 /*-----------------------------------------------------------------*/
1723 int pic14_getDataSize(operand *op)
1724 {
1725         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1726         
1727         
1728         return AOP_SIZE(op);
1729         
1730         // tsd- in the pic port, the genptr size is 1, so this code here
1731         // fails. ( in the 8051 port, the size was 4).
1732 #if 0
1733         int size;
1734         size = AOP_SIZE(op);
1735         if (size == GPTRSIZE)
1736         {
1737                 sym_link *type = operandType(op);
1738                 if (IS_GENPTR(type))
1739                 {
1740                 /* generic pointer; arithmetic operations
1741                 * should ignore the high byte (pointer type).
1742                         */
1743                         size--;
1744                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1745                 }
1746         }
1747         return size;
1748 #endif
1749 }
1750
1751 /*-----------------------------------------------------------------*/
1752 /* pic14_outAcc - output Acc                                       */
1753 /*-----------------------------------------------------------------*/
1754 void pic14_outAcc(operand *result)
1755 {
1756         int size,offset;
1757         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1758         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1759         
1760         
1761         size = pic14_getDataSize(result);
1762         if(size){
1763                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1764                 size--;
1765                 offset = 1;
1766                 /* unsigned or positive */
1767                 while(size--)
1768                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1769         }
1770         
1771 }
1772
1773 /*-----------------------------------------------------------------*/
1774 /* pic14_outBitC - output a bit C                                  */
1775 /*-----------------------------------------------------------------*/
1776 void pic14_outBitC(operand *result)
1777 {
1778         
1779         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1780         /* if the result is bit */
1781         if (AOP_TYPE(result) == AOP_CRY) 
1782                 aopPut(AOP(result),"c",0);
1783         else {
1784                 pic14_emitcode("clr","a  ; %d", __LINE__);
1785                 pic14_emitcode("rlc","a");
1786                 pic14_outAcc(result);
1787         }
1788 }
1789
1790 /*-----------------------------------------------------------------*/
1791 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1792 /*-----------------------------------------------------------------*/
1793 void pic14_toBoolean(operand *oper)
1794 {
1795         int size = AOP_SIZE(oper) - 1;
1796         int offset = 1;
1797         
1798         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1799         
1800         if ( AOP_TYPE(oper) != AOP_ACC) {
1801                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1802         }
1803         while (size--) {
1804                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1805         }
1806 }
1807
1808
1809 /*-----------------------------------------------------------------*/
1810 /* genNot - generate code for ! operation                          */
1811 /*-----------------------------------------------------------------*/
1812 static void genNot (iCode *ic)
1813 {
1814         symbol *tlbl;
1815         int size;
1816         
1817         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1818         /* assign asmOps to operand & result */
1819         aopOp (IC_LEFT(ic),ic,FALSE);
1820         aopOp (IC_RESULT(ic),ic,TRUE);
1821         
1822         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1823         /* if in bit space then a special case */
1824         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1825                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1826                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1827                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1828                 } else {
1829                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1830                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1831                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1832                 }
1833                 goto release;
1834         }
1835         
1836         size = AOP_SIZE(IC_LEFT(ic));
1837         if(size == 1) {
1838                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1839                 emitpcode(POC_ANDLW,popGetLit(1));
1840                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1841                 goto release;
1842         }
1843         pic14_toBoolean(IC_LEFT(ic));
1844         
1845         tlbl = newiTempLabel(NULL);
1846         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1847         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1848         pic14_outBitC(IC_RESULT(ic));
1849         
1850 release:        
1851         /* release the aops */
1852         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1853         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1854 }
1855
1856
1857 /*-----------------------------------------------------------------*/
1858 /* genCpl - generate code for complement                                                   */
1859 /*-----------------------------------------------------------------*/
1860 static void genCpl (iCode *ic)
1861 {
1862         operand *left, *result;
1863         int size, offset=0;  
1864         
1865         
1866         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1867         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1868         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1869         
1870         /* if both are in bit space then 
1871         a special case */
1872         if (AOP_TYPE(result) == AOP_CRY &&
1873                 AOP_TYPE(left) == AOP_CRY ) { 
1874                 
1875                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1876                 pic14_emitcode("cpl","c"); 
1877                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1878                 goto release; 
1879         } 
1880         
1881         size = AOP_SIZE(result);
1882         while (size--) {
1883                 
1884                 if(AOP_TYPE(left) == AOP_ACC) 
1885                         emitpcode(POC_XORLW, popGetLit(0xff));
1886                 else
1887                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1888                 
1889                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1890                 offset++;
1891         }
1892         
1893         
1894 release:
1895         /* release the aops */
1896         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1897         freeAsmop(result,NULL,ic,TRUE);
1898 }
1899
1900 /*-----------------------------------------------------------------*/
1901 /* genUminusFloat - unary minus for floating points                        */
1902 /*-----------------------------------------------------------------*/
1903 static void genUminusFloat(operand *op,operand *result)
1904 {
1905         int size ,offset =0 ;
1906         char *l;
1907         
1908         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1909         /* for this we just need to flip the 
1910         first it then copy the rest in place */
1911         size = AOP_SIZE(op) - 1;
1912         l = aopGet(AOP(op),3,FALSE,FALSE);
1913         
1914         MOVA(l);          
1915         
1916         pic14_emitcode("cpl","acc.7");
1917         aopPut(AOP(result),"a",3);      
1918         
1919         while(size--) {
1920                 aopPut(AOP(result),
1921                         aopGet(AOP(op),offset,FALSE,FALSE),
1922                         offset);
1923                 offset++;
1924         }                
1925 }
1926
1927 /*-----------------------------------------------------------------*/
1928 /* genUminus - unary minus code generation                                                 */
1929 /*-----------------------------------------------------------------*/
1930 static void genUminus (iCode *ic)
1931 {
1932         int size, i;
1933         sym_link *optype, *rtype;
1934         
1935         
1936         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1937         /* assign asmops */
1938         aopOp(IC_LEFT(ic),ic,FALSE);
1939         aopOp(IC_RESULT(ic),ic,TRUE);
1940         
1941         /* if both in bit space then special
1942         case */
1943         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1944                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1945                 
1946                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
1947                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1948                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
1949                 
1950                 goto release; 
1951         } 
1952         
1953         optype = operandType(IC_LEFT(ic));
1954         rtype = operandType(IC_RESULT(ic));
1955         
1956         /* if float then do float stuff */
1957         if (IS_FLOAT(optype)) {
1958                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1959                 goto release;
1960         }
1961         
1962         /* otherwise subtract from zero by taking the 2's complement */
1963         size = AOP_SIZE(IC_LEFT(ic));
1964         
1965         for(i=0; i<size; i++) {
1966                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1967                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1968                 else {
1969                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1970                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1971                 }
1972         }
1973         
1974         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1975         for(i=1; i<size; i++) {
1976                 emitSKPNZ;
1977                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1978         }
1979         
1980 release:
1981         /* release the aops */
1982         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1983         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
1984 }
1985
1986 /*-----------------------------------------------------------------*/
1987 /* saveRegisters - will look for a call and save the registers     */
1988 /*-----------------------------------------------------------------*/
1989 static void saveRegisters(iCode *lic) 
1990 {
1991         int i;
1992         iCode *ic;
1993         bitVect *rsave;
1994         sym_link *dtype;
1995         
1996         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1997         /* look for call */
1998         for (ic = lic ; ic ; ic = ic->next) 
1999                 if (ic->op == CALL || ic->op == PCALL)
2000                         break;
2001                 
2002                 if (!ic) {
2003                         fprintf(stderr,"found parameter push with no function call\n");
2004                         return ;
2005                 }
2006                 
2007                 /* if the registers have been saved already then
2008                 do nothing */
2009                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2010                         return ;
2011                 
2012                         /* find the registers in use at this time 
2013                 and push them away to safety */
2014                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2015                         ic->rUsed);
2016                 
2017                 ic->regsSaved = 1;
2018                 if (options.useXstack) {
2019                         if (bitVectBitValue(rsave,R0_IDX))
2020                                 pic14_emitcode("mov","b,r0");
2021                         pic14_emitcode("mov","r0,%s",spname);
2022                         for (i = 0 ; i < pic14_nRegs ; i++) {
2023                                 if (bitVectBitValue(rsave,i)) {
2024                                         if (i == R0_IDX)
2025                                                 pic14_emitcode("mov","a,b");
2026                                         else
2027                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2028                                         pic14_emitcode("movx","@r0,a");
2029                                         pic14_emitcode("inc","r0");
2030                                 }
2031                         }
2032                         pic14_emitcode("mov","%s,r0",spname);
2033                         if (bitVectBitValue(rsave,R0_IDX))
2034                                 pic14_emitcode("mov","r0,b");     
2035                 }// else
2036                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2037                 //        if (bitVectBitValue(rsave,i))
2038                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2039                 //}
2040                 
2041                 dtype = operandType(IC_LEFT(ic));
2042                 if (currFunc && dtype && 
2043                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2044                         IFFUNC_ISISR(currFunc->type) &&
2045                         !ic->bankSaved) 
2046                         
2047                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2048                 
2049 }
2050 /*-----------------------------------------------------------------*/
2051 /* unsaveRegisters - pop the pushed registers                                      */
2052 /*-----------------------------------------------------------------*/
2053 static void unsaveRegisters (iCode *ic)
2054 {
2055         int i;
2056         bitVect *rsave;
2057         
2058         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2059         /* find the registers in use at this time 
2060         and push them away to safety */
2061         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2062                 ic->rUsed);
2063         
2064         if (options.useXstack) {
2065                 pic14_emitcode("mov","r0,%s",spname); 
2066                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2067                         if (bitVectBitValue(rsave,i)) {
2068                                 pic14_emitcode("dec","r0");
2069                                 pic14_emitcode("movx","a,@r0");
2070                                 if (i == R0_IDX)
2071                                         pic14_emitcode("mov","b,a");
2072                                 else
2073                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2074                         }       
2075                         
2076                 }
2077                 pic14_emitcode("mov","%s,r0",spname);
2078                 if (bitVectBitValue(rsave,R0_IDX))
2079                         pic14_emitcode("mov","r0,b");
2080         } //else
2081         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2082         //      if (bitVectBitValue(rsave,i))
2083         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2084         //}
2085         
2086 }  
2087
2088
2089 /*-----------------------------------------------------------------*/
2090 /* pushSide -                            */
2091 /*-----------------------------------------------------------------*/
2092 static void pushSide(operand * oper, int size)
2093 {
2094 #if 0
2095         int offset = 0;
2096         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2097         while (size--) {
2098                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2099                 if (AOP_TYPE(oper) != AOP_REG &&
2100                         AOP_TYPE(oper) != AOP_DIR &&
2101                         strcmp(l,"a") ) {
2102                         pic14_emitcode("mov","a,%s",l);
2103                         pic14_emitcode("push","acc");
2104                 } else
2105                         pic14_emitcode("push","%s",l);
2106         }
2107 #endif
2108 }
2109
2110 /*-----------------------------------------------------------------*/
2111 /* assignResultValue -                           */
2112 /*-----------------------------------------------------------------*/
2113 static void assignResultValue(operand * oper)
2114 {
2115         int size = AOP_SIZE(oper);
2116         
2117         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2118         
2119         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2120         
2121         while (size--) {
2122                 if (GpsuedoStkPtr++)
2123                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2124                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2125         }
2126 }
2127
2128
2129 /*-----------------------------------------------------------------*/
2130 /* genIpush - genrate code for pushing this gets a little complex  */
2131 /*-----------------------------------------------------------------*/
2132 static void genIpush (iCode *ic)
2133 {
2134         
2135         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2136 #if 0
2137         int size, offset = 0 ;
2138         char *l;
2139         
2140         
2141         /* if this is not a parm push : ie. it is spill push 
2142         and spill push is always done on the local stack */
2143         if (!ic->parmPush) {
2144                 
2145                 /* and the item is spilt then do nothing */
2146                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2147                         return ;
2148                 
2149                 aopOp(IC_LEFT(ic),ic,FALSE);
2150                 size = AOP_SIZE(IC_LEFT(ic));
2151                 /* push it on the stack */
2152                 while(size--) {
2153                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2154                         if (*l == '#') {
2155                                 MOVA(l);
2156                                 l = "acc";
2157                         }
2158                         pic14_emitcode("push","%s",l);
2159                 }
2160                 return ;                
2161         }
2162         
2163         /* this is a paramter push: in this case we call
2164         the routine to find the call and save those
2165         registers that need to be saved */   
2166         saveRegisters(ic);
2167         
2168         /* then do the push */
2169         aopOp(IC_LEFT(ic),ic,FALSE);
2170         
2171         
2172         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2173         size = AOP_SIZE(IC_LEFT(ic));
2174         
2175         while (size--) {
2176                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2177                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2178                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2179                         strcmp(l,"a") ) {
2180                         pic14_emitcode("mov","a,%s",l);
2181                         pic14_emitcode("push","acc");
2182                 } else
2183                         pic14_emitcode("push","%s",l);
2184         }         
2185         
2186         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2187 #endif
2188 }
2189
2190 /*-----------------------------------------------------------------*/
2191 /* genIpop - recover the registers: can happen only for spilling   */
2192 /*-----------------------------------------------------------------*/
2193 static void genIpop (iCode *ic)
2194 {
2195         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2196 #if 0
2197         int size,offset ;
2198         
2199         
2200         /* if the temp was not pushed then */
2201         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2202                 return ;
2203         
2204         aopOp(IC_LEFT(ic),ic,FALSE);
2205         size = AOP_SIZE(IC_LEFT(ic));
2206         offset = (size-1);
2207         while (size--) 
2208                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2209                 FALSE,TRUE));
2210         
2211         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2212 #endif
2213 }
2214
2215 /*-----------------------------------------------------------------*/
2216 /* unsaverbank - restores the resgister bank from stack                    */
2217 /*-----------------------------------------------------------------*/
2218 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2219 {
2220         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2221 #if 0
2222         int i;
2223         asmop *aop ;
2224         regs *r = NULL;
2225         
2226         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2227         if (popPsw) {
2228                 if (options.useXstack) {
2229                         aop = newAsmop(0);
2230                         r = getFreePtr(ic,&aop,FALSE);
2231                         
2232                         
2233                         pic14_emitcode("mov","%s,_spx",r->name);
2234                         pic14_emitcode("movx","a,@%s",r->name);
2235                         pic14_emitcode("mov","psw,a");
2236                         pic14_emitcode("dec","%s",r->name);
2237                         
2238                 }else
2239                         pic14_emitcode ("pop","psw");
2240         }
2241         
2242         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2243                 if (options.useXstack) {           
2244                         pic14_emitcode("movx","a,@%s",r->name);
2245                         //pic14_emitcode("mov","(%s+%d),a",
2246                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2247                         pic14_emitcode("dec","%s",r->name);
2248                         
2249                 } else 
2250                         pic14_emitcode("pop",""); //"(%s+%d)",
2251                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2252         }
2253         
2254         if (options.useXstack) {
2255                 
2256                 pic14_emitcode("mov","_spx,%s",r->name);
2257                 freeAsmop(NULL,aop,ic,TRUE);
2258                 
2259         }
2260 #endif 
2261 }
2262
2263 /*-----------------------------------------------------------------*/
2264 /* saverbank - saves an entire register bank on the stack                  */
2265 /*-----------------------------------------------------------------*/
2266 static void saverbank (int bank, iCode *ic, bool pushPsw)
2267 {
2268         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2269 #if 0
2270         int i;
2271         asmop *aop ;
2272         regs *r = NULL;
2273         
2274         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2275         if (options.useXstack) {
2276                 
2277                 aop = newAsmop(0);
2278                 r = getFreePtr(ic,&aop,FALSE);  
2279                 pic14_emitcode("mov","%s,_spx",r->name);
2280                 
2281         }
2282         
2283         for (i = 0 ; i < pic14_nRegs ;i++) {
2284                 if (options.useXstack) {
2285                         pic14_emitcode("inc","%s",r->name);
2286                         //pic14_emitcode("mov","a,(%s+%d)",
2287                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2288                         pic14_emitcode("movx","@%s,a",r->name);                 
2289                 } else 
2290                         pic14_emitcode("push","");// "(%s+%d)",
2291                 //regspic14[i].base,8*bank+regspic14[i].offset);
2292         }
2293         
2294         if (pushPsw) {
2295                 if (options.useXstack) {
2296                         pic14_emitcode("mov","a,psw");
2297                         pic14_emitcode("movx","@%s,a",r->name); 
2298                         pic14_emitcode("inc","%s",r->name);
2299                         pic14_emitcode("mov","_spx,%s",r->name);                 
2300                         freeAsmop (NULL,aop,ic,TRUE);
2301                         
2302                 } else
2303                         pic14_emitcode("push","psw");
2304                 
2305                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2306         }
2307         ic->bankSaved = 1;
2308 #endif
2309 }
2310
2311 /*-----------------------------------------------------------------*/
2312 /* genCall - generates a call statement                                                    */
2313 /*-----------------------------------------------------------------*/
2314 static void genCall (iCode *ic)
2315 {
2316         sym_link *dtype;         
2317         symbol *sym;
2318         unsigned char *name;
2319         int isExtern;
2320         
2321         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2322         
2323         /* if caller saves & we have not saved then */
2324         if (!ic->regsSaved)
2325                 saveRegisters(ic);
2326         
2327                 /* if we are calling a function that is not using
2328                 the same register bank then we need to save the
2329         destination registers on the stack */
2330         dtype = operandType(IC_LEFT(ic));
2331         if (currFunc && dtype && 
2332                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2333                 IFFUNC_ISISR(currFunc->type) &&
2334                 !ic->bankSaved) 
2335                 
2336                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2337         
2338         /* if send set is not empty the assign */
2339         if (_G.sendSet) {
2340                 iCode *sic;
2341                 /* For the Pic port, there is no data stack.
2342                 * So parameters passed to functions are stored
2343                 * in registers. (The pCode optimizer will get
2344                 * rid of most of these :).
2345                 */
2346                 int psuedoStkPtr=-1;
2347                 int firstTimeThruLoop = 1;
2348                 
2349                 _G.sendSet = reverseSet(_G.sendSet);
2350                 
2351                 /* First figure how many parameters are getting passed */
2352                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2353                 sic = setNextItem(_G.sendSet)) {
2354                         
2355                         aopOp(IC_LEFT(sic),sic,FALSE);
2356                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2357                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2358                 }
2359                 
2360                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2361                 sic = setNextItem(_G.sendSet)) {
2362                         int size, offset = 0;
2363                         
2364                         aopOp(IC_LEFT(sic),sic,FALSE);
2365                         size = AOP_SIZE(IC_LEFT(sic));
2366                         
2367                         while (size--) {
2368                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2369                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2370                                 
2371                                 if(!firstTimeThruLoop) {
2372                                 /* If this is not the first time we've been through the loop
2373                                 * then we need to save the parameter in a temporary
2374                                 * register. The last byte of the last parameter is
2375                                         * passed in W. */
2376                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2377                                         
2378                                 }
2379                                 firstTimeThruLoop=0;
2380                                 
2381                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2382                                 offset++;
2383                         }
2384                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2385                 }
2386                 _G.sendSet = NULL;
2387         }
2388         /* make the call */
2389         sym = OP_SYMBOL(IC_LEFT(ic));
2390         name = sym->rname[0] ? sym->rname : sym->name;
2391         isExtern = IS_EXTERN(sym->etype);
2392         if (isExtern) {
2393                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2394         }
2395         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2396         if (isExtern) {
2397                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2398         }
2399         GpsuedoStkPtr=0;
2400         /* if we need assign a result value */
2401         if ((IS_ITEMP(IC_RESULT(ic)) && 
2402                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2403                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2404                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2405                 
2406                 _G.accInUse++;
2407                 aopOp(IC_RESULT(ic),ic,FALSE);
2408                 _G.accInUse--;
2409                 
2410                 assignResultValue(IC_RESULT(ic));
2411                 
2412                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2413                         AopType(AOP_TYPE(IC_RESULT(ic))));
2414                 
2415                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2416         }
2417         
2418         /* adjust the stack for parameters if 
2419         required */
2420         if (ic->parmBytes) {
2421                 int i;
2422                 if (ic->parmBytes > 3) {
2423                         pic14_emitcode("mov","a,%s",spname);
2424                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2425                         pic14_emitcode("mov","%s,a",spname);
2426                 } else 
2427                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2428                                 pic14_emitcode("dec","%s",spname);
2429                         
2430         }
2431         
2432         /* if register bank was saved then pop them */
2433         if (ic->bankSaved)
2434                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2435         
2436         /* if we hade saved some registers then unsave them */
2437         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2438                 unsaveRegisters (ic);
2439         
2440         
2441 }
2442
2443 /*-----------------------------------------------------------------*/
2444 /* genPcall - generates a call by pointer statement                        */
2445 /*-----------------------------------------------------------------*/
2446 static void genPcall (iCode *ic)
2447 {
2448         sym_link *dtype;
2449         symbol *albl = newiTempLabel(NULL);
2450         symbol *blbl = newiTempLabel(NULL);
2451         PIC_OPCODE poc;
2452         pCodeOp *pcop;
2453         operand *left;
2454         
2455         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2456         /* if caller saves & we have not saved then */
2457         if (!ic->regsSaved)
2458                 saveRegisters(ic);
2459         
2460                 /* if we are calling a function that is not using
2461                 the same register bank then we need to save the
2462         destination registers on the stack */
2463         dtype = operandType(IC_LEFT(ic));
2464         if (currFunc && dtype && 
2465                 IFFUNC_ISISR(currFunc->type) &&
2466                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2467                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2468         
2469         left = IC_LEFT(ic);
2470         aopOp(left,ic,FALSE);
2471         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2472         
2473         pushSide(IC_LEFT(ic), FPTRSIZE);
2474         
2475         /* if send set is not empty, assign parameters */
2476         if (_G.sendSet) {
2477                 
2478                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2479                 /* no way to pass args - W always gets used to make the call */
2480         }
2481         /* first idea - factor out a common helper function and call it.
2482         But don't know how to get it generated only once in its own block
2483         
2484         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2485                 char *rname;
2486                 char *buffer;
2487                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2488                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2489                 buffer = Safe_calloc(1,strlen(rname)+16);
2490                 sprintf(buffer, "%s_goto_helper", rname);
2491                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2492                 free(buffer);
2493         }
2494         */
2495         emitpcode(POC_CALL,popGetLabel(albl->key));
2496         pcop = popGetLabel(blbl->key);
2497         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2498         emitpcode(POC_GOTO,pcop);
2499         emitpLabel(albl->key);
2500         
2501         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2502         
2503         emitpcode(poc,popGet(AOP(left),1));
2504         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2505         emitpcode(poc,popGet(AOP(left),0));
2506         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2507         
2508         emitpLabel(blbl->key);
2509         
2510         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2511         
2512         /* if we need to assign a result value */
2513         if ((IS_ITEMP(IC_RESULT(ic)) &&
2514                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2515                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2516                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2517                 
2518                 _G.accInUse++;
2519                 aopOp(IC_RESULT(ic),ic,FALSE);
2520                 _G.accInUse--;
2521                 
2522                 assignResultValue(IC_RESULT(ic));
2523                 
2524                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2525         }
2526         
2527         /* if register bank was saved then unsave them */
2528         if (currFunc && dtype && 
2529                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2530                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2531         
2532                 /* if we hade saved some registers then
2533         unsave them */
2534         if (ic->regsSaved)
2535                 unsaveRegisters (ic);
2536         
2537 }
2538
2539 /*-----------------------------------------------------------------*/
2540 /* resultRemat - result  is rematerializable                                       */
2541 /*-----------------------------------------------------------------*/
2542 static int resultRemat (iCode *ic)
2543 {
2544         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2545         if (SKIP_IC(ic) || ic->op == IFX)
2546                 return 0;
2547         
2548         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2549                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2550                 if (sym->remat && !POINTER_SET(ic)) 
2551                         return 1;
2552         }
2553         
2554         return 0;
2555 }
2556
2557 #if defined(__BORLANDC__) || defined(_MSC_VER)
2558 #define STRCASECMP stricmp
2559 #else
2560 #define STRCASECMP strcasecmp
2561 #endif
2562
2563 #if 0
2564 /*-----------------------------------------------------------------*/
2565 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2566 /*-----------------------------------------------------------------*/
2567 static bool inExcludeList(char *s)
2568 {
2569         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2570         int i =0;
2571         
2572         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2573         if (options.excludeRegs[i] &&
2574                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2575                 return FALSE ;
2576         
2577         for ( i = 0 ; options.excludeRegs[i]; i++) {
2578                 if (options.excludeRegs[i] &&
2579                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2580                         return TRUE;
2581         }
2582         return FALSE ;
2583 }
2584 #endif
2585
2586 /*-----------------------------------------------------------------*/
2587 /* genFunction - generated code for function entry                                 */
2588 /*-----------------------------------------------------------------*/
2589 static void genFunction (iCode *ic)
2590 {
2591         symbol *sym;
2592         sym_link *ftype;
2593         
2594         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2595         
2596         labelOffset += (max_key+4);
2597         max_key=0;
2598         GpsuedoStkPtr=0;
2599         _G.nRegsSaved = 0;
2600         /* create the function header */
2601         pic14_emitcode(";","-----------------------------------------");
2602         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2603         pic14_emitcode(";","-----------------------------------------");
2604         
2605         pic14_emitcode("","%s:",sym->rname);
2606         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2607         
2608         ftype = operandType(IC_LEFT(ic));
2609         
2610         /* if critical function then turn interrupts off */
2611         if (IFFUNC_ISCRITICAL(ftype))
2612                 pic14_emitcode("clr","ea");
2613         
2614                 /* here we need to generate the equates for the
2615         register bank if required */
2616 #if 0
2617         if (FUNC_REGBANK(ftype) != rbank) {
2618                 int i ;
2619                 
2620                 rbank = FUNC_REGBANK(ftype);
2621                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2622                         if (strcmp(regspic14[i].base,"0") == 0)
2623                                 pic14_emitcode("","%s = 0x%02x",
2624                                 regspic14[i].dname,
2625                                 8*rbank+regspic14[i].offset);
2626                         else
2627                                 pic14_emitcode ("","%s = %s + 0x%02x",
2628                                 regspic14[i].dname,
2629                                 regspic14[i].base,
2630                                 8*rbank+regspic14[i].offset);
2631                 }
2632         }
2633 #endif
2634         
2635         /* if this is an interrupt service routine */
2636         if (IFFUNC_ISISR(sym->type)) {
2637         /*  already done in pic14createInterruptVect() - delete me
2638         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2639         emitpcodeNULLop(POC_NOP);
2640         emitpcodeNULLop(POC_NOP);
2641         emitpcodeNULLop(POC_NOP);
2642                 */
2643                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2644                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2645                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2646                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2647                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2648                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2649                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2650                 
2651                 pBlockConvert2ISR(pb);
2652 #if 0  
2653                 if (!inExcludeList("acc"))              
2654                         pic14_emitcode ("push","acc");  
2655                 if (!inExcludeList("b"))
2656                         pic14_emitcode ("push","b");
2657                 if (!inExcludeList("dpl"))
2658                         pic14_emitcode ("push","dpl");
2659                 if (!inExcludeList("dph"))
2660                         pic14_emitcode ("push","dph");
2661                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2662                 {
2663                         pic14_emitcode ("push", "dpx");
2664                         /* Make sure we're using standard DPTR */
2665                         pic14_emitcode ("push", "dps");
2666                         pic14_emitcode ("mov", "dps, #0x00");
2667                         if (options.stack10bit)
2668                         { 
2669                                 /* This ISR could conceivably use DPTR2. Better save it. */
2670                                 pic14_emitcode ("push", "dpl1");
2671                                 pic14_emitcode ("push", "dph1");
2672                                 pic14_emitcode ("push", "dpx1");
2673                         }
2674                 }
2675                 /* if this isr has no bank i.e. is going to
2676                 run with bank 0 , then we need to save more
2677 registers :-) */
2678                 if (!FUNC_REGBANK(sym->type)) {
2679                         
2680                 /* if this function does not call any other
2681                 function then we can be economical and
2682                         save only those registers that are used */
2683                         if (! IFFUNC_HASFCALL(sym->type)) {
2684                                 int i;
2685                                 
2686                                 /* if any registers used */
2687                                 if (sym->regsUsed) {
2688                                         /* save the registers used */
2689                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2690                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2691                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2692                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2693                                         }
2694                                 }
2695                                 
2696                         } else {
2697                         /* this function has    a function call cannot
2698                         determines register usage so we will have the
2699                                 entire bank */
2700                                 saverbank(0,ic,FALSE);
2701                         }       
2702                 }
2703 #endif
2704         } else {
2705         /* if callee-save to be used for this function
2706                 then save the registers being used in this function */
2707                 if (IFFUNC_CALLEESAVES(sym->type)) {
2708                         int i;
2709                         
2710                         /* if any registers used */
2711                         if (sym->regsUsed) {
2712                                 /* save the registers used */
2713                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2714                                         if (bitVectBitValue(sym->regsUsed,i) ||
2715                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2716                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2717                                                 _G.nRegsSaved++;
2718                                         }
2719                                 }
2720                         }
2721                 }
2722         }
2723         
2724         /* set the register bank to the desired value */
2725         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2726                 pic14_emitcode("push","psw");
2727                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2728         }
2729         
2730         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2731                 
2732                 if (options.useXstack) {
2733                         pic14_emitcode("mov","r0,%s",spname);
2734                         pic14_emitcode("mov","a,_bp");
2735                         pic14_emitcode("movx","@r0,a");
2736                         pic14_emitcode("inc","%s",spname);
2737                 }
2738                 else
2739                 {
2740                         /* set up the stack */
2741                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2742                 }
2743                 pic14_emitcode ("mov","_bp,%s",spname);
2744         }
2745         
2746         /* adjust the stack for the function */
2747         if (sym->stack) {
2748                 
2749                 int i = sym->stack;
2750                 if (i > 256 ) 
2751                         werror(W_STACK_OVERFLOW,sym->name);
2752                 
2753                 if (i > 3 && sym->recvSize < 4) {                
2754                         
2755                         pic14_emitcode ("mov","a,sp");
2756                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2757                         pic14_emitcode ("mov","sp,a");
2758                         
2759                 }
2760                 else
2761                         while(i--)
2762                                 pic14_emitcode("inc","sp");
2763         }
2764         
2765         if (sym->xstack) {
2766                 
2767                 pic14_emitcode ("mov","a,_spx");
2768                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2769                 pic14_emitcode ("mov","_spx,a");
2770         }
2771         
2772 }
2773
2774 /*-----------------------------------------------------------------*/
2775 /* genEndFunction - generates epilogue for functions                       */
2776 /*-----------------------------------------------------------------*/
2777 static void genEndFunction (iCode *ic)
2778 {
2779         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2780         
2781         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2782         
2783         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2784         {
2785                 pic14_emitcode ("mov","%s,_bp",spname);
2786         }
2787         
2788         /* if use external stack but some variables were
2789         added to the local stack then decrement the
2790         local stack */
2791         if (options.useXstack && sym->stack) {    
2792                 pic14_emitcode("mov","a,sp");
2793                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2794                 pic14_emitcode("mov","sp,a");
2795         }
2796         
2797         
2798         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2799                 if (options.useXstack) {
2800                         pic14_emitcode("mov","r0,%s",spname);
2801                         pic14_emitcode("movx","a,@r0");
2802                         pic14_emitcode("mov","_bp,a");
2803                         pic14_emitcode("dec","%s",spname);
2804                 }
2805                 else
2806                 {
2807                         pic14_emitcode ("pop","_bp");
2808                 }
2809         }
2810         
2811         /* restore the register bank    */        
2812         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2813                 pic14_emitcode ("pop","psw");
2814         
2815         if (IFFUNC_ISISR(sym->type)) {
2816                 
2817                 /* now we need to restore the registers */
2818                 /* if this isr has no bank i.e. is going to
2819                 run with bank 0 , then we need to save more
2820 registers :-) */
2821                 if (!FUNC_REGBANK(sym->type)) {
2822                         
2823                 /* if this function does not call any other
2824                 function then we can be economical and
2825                         save only those registers that are used */
2826                         if (! IFFUNC_HASFCALL(sym->type)) {
2827                                 int i;
2828                                 
2829                                 /* if any registers used */
2830                                 if (sym->regsUsed) {
2831                                         /* save the registers used */
2832                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2833                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2834                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2835                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2836                                         }
2837                                 }
2838                                 
2839                         } else {
2840                         /* this function has    a function call cannot
2841                         determines register usage so we will have the
2842                                 entire bank */
2843                                 unsaverbank(0,ic,FALSE);
2844                         }       
2845                 }
2846 #if 0
2847                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2848                 {
2849                         if (options.stack10bit)
2850                         {
2851                                 pic14_emitcode ("pop", "dpx1");
2852                                 pic14_emitcode ("pop", "dph1");
2853                                 pic14_emitcode ("pop", "dpl1");
2854                         } 
2855                         pic14_emitcode ("pop", "dps");
2856                         pic14_emitcode ("pop", "dpx");
2857                 }
2858                 if (!inExcludeList("dph"))
2859                         pic14_emitcode ("pop","dph");
2860                 if (!inExcludeList("dpl"))
2861                         pic14_emitcode ("pop","dpl");
2862                 if (!inExcludeList("b"))
2863                         pic14_emitcode ("pop","b");
2864                 if (!inExcludeList("acc"))
2865                         pic14_emitcode ("pop","acc");
2866                 
2867                 if (IFFUNC_ISCRITICAL(sym->type))
2868                         pic14_emitcode("setb","ea");
2869 #endif
2870                 
2871                 /* if debug then send end of function */
2872                 /*      if (options.debug && currFunc) { */
2873                 if (currFunc) {
2874                         debugFile->writeEndFunction (currFunc, ic, 1);
2875                 }
2876                 
2877                 pic14_emitcode ("reti","");
2878                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2879                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2880                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2881                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2882                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2883                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2884                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2885                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2886                 emitpcodeNULLop(POC_RETFIE);
2887         }
2888         else {
2889                 if (IFFUNC_ISCRITICAL(sym->type))
2890                         pic14_emitcode("setb","ea");
2891                 
2892                 if (IFFUNC_CALLEESAVES(sym->type)) {
2893                         int i;
2894                         
2895                         /* if any registers used */
2896                         if (sym->regsUsed) {
2897                                 /* save the registers used */
2898                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2899                                         if (bitVectBitValue(sym->regsUsed,i) ||
2900                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2901                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2902                                 }
2903                         }
2904                         
2905                 }
2906                 
2907                 /* if debug then send end of function */
2908                 if (currFunc) {
2909                         debugFile->writeEndFunction (currFunc, ic, 1);
2910                 }
2911                 
2912                 pic14_emitcode ("return","");
2913                 emitpcodeNULLop(POC_RETURN);
2914                 
2915                 /* Mark the end of a function */
2916                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2917         }
2918         
2919 }
2920
2921 /*-----------------------------------------------------------------*/
2922 /* genRet - generate code for return statement                                     */
2923 /*-----------------------------------------------------------------*/
2924 static void genRet (iCode *ic)
2925 {
2926         int size,offset = 0 , pushed = 0;
2927         
2928         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2929         /* if we have no return value then
2930         just generate the "ret" */
2931         if (!IC_LEFT(ic)) 
2932                 goto jumpret;           
2933         
2934                 /* we have something to return then
2935         move the return value into place */
2936         aopOp(IC_LEFT(ic),ic,FALSE);
2937         size = AOP_SIZE(IC_LEFT(ic));
2938         
2939         while (size--) {
2940                 char *l ;
2941                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2942                         /* #NOCHANGE */
2943                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
2944                                 FALSE,TRUE);
2945                         pic14_emitcode("push","%s",l);
2946                         pushed++;
2947                 } else {
2948                         l = aopGet(AOP(IC_LEFT(ic)),offset,
2949                                 FALSE,FALSE);
2950                         if (strcmp(fReturn[offset],l)) {
2951                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
2952                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2953                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2954                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2955                                         emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2956                                 }else {
2957                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2958                                 }
2959                                 if(size) {
2960                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2961                                 }
2962                                 offset++;
2963                         }
2964                 }
2965         }
2966         
2967         if (pushed) {
2968                 while(pushed) {
2969                         pushed--;
2970                         if (strcmp(fReturn[pushed],"a"))
2971                                 pic14_emitcode("pop",fReturn[pushed]);
2972                         else
2973                                 pic14_emitcode("pop","acc");
2974                 }
2975         }
2976         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2977         
2978 jumpret:
2979 /* generate a jump to the return label
2980         if the next is not the return statement */
2981         if (!(ic->next && ic->next->op == LABEL &&
2982                 IC_LABEL(ic->next) == returnLabel)) {
2983                 
2984                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2985                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2986         }
2987         
2988 }
2989
2990 /*-----------------------------------------------------------------*/
2991 /* genLabel - generates a label                                                                    */
2992 /*-----------------------------------------------------------------*/
2993 static void genLabel (iCode *ic)
2994 {
2995         /* special case never generate */
2996         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2997         if (IC_LABEL(ic) == entryLabel)
2998                 return ;
2999         
3000         emitpLabel(IC_LABEL(ic)->key);
3001         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3002 }
3003
3004 /*-----------------------------------------------------------------*/
3005 /* genGoto - generates a goto                                                                      */
3006 /*-----------------------------------------------------------------*/
3007 //tsd
3008 static void genGoto (iCode *ic)
3009 {
3010         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3011         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3012 }
3013
3014
3015 /*-----------------------------------------------------------------*/
3016 /* genMultbits :- multiplication of bits                                                   */
3017 /*-----------------------------------------------------------------*/
3018 static void genMultbits (operand *left, 
3019                                                  operand *right, 
3020                                                  operand *result)
3021 {
3022         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3023         
3024         if(!pic14_sameRegs(AOP(result),AOP(right)))
3025                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3026         
3027         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3028         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3029         emitpcode(POC_BCF,  popGet(AOP(result),0));
3030         
3031 }
3032
3033
3034 /*-----------------------------------------------------------------*/
3035 /* genMultOneByte : 8 bit multiplication & division                        */
3036 /*-----------------------------------------------------------------*/
3037 static void genMultOneByte (operand *left,
3038                                                         operand *right,
3039                                                         operand *result)
3040 {
3041         sym_link *opetype = operandType(result);
3042         
3043         // symbol *lbl ;
3044         int size,offset;
3045         
3046         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3047         DEBUGpic14_AopType(__LINE__,left,right,result);
3048         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3049         
3050         /* (if two literals, the value is computed before) */
3051         /* if one literal, literal on the right */
3052         if (AOP_TYPE(left) == AOP_LIT){
3053                 operand *t = right;
3054                 right = left;
3055                 left = t;
3056         }
3057         
3058         size = AOP_SIZE(result);
3059         if(size == 1) {
3060                 
3061                 if (AOP_TYPE(right) == AOP_LIT){
3062                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3063                                 aopGet(AOP(right),0,FALSE,FALSE), 
3064                                 aopGet(AOP(left),0,FALSE,FALSE), 
3065                                 aopGet(AOP(result),0,FALSE,FALSE));
3066                         pic14_emitcode("call","genMultLit");
3067                 } else {
3068                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3069                                 aopGet(AOP(right),0,FALSE,FALSE), 
3070                                 aopGet(AOP(left),0,FALSE,FALSE), 
3071                                 aopGet(AOP(result),0,FALSE,FALSE));
3072                         pic14_emitcode("call","genMult8X8_8");
3073                         
3074                 }
3075                 genMult8X8_8 (left, right,result);
3076                 
3077                 
3078                 /* signed or unsigned */
3079                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3080                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3081                 //MOVA(l);               
3082                 //pic14_emitcode("mul","ab");
3083                 /* if result size = 1, mul signed = mul unsigned */
3084                 //aopPut(AOP(result),"a",0);
3085                 
3086         } else {        // (size > 1)
3087                 
3088                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3089                         aopGet(AOP(right),0,FALSE,FALSE), 
3090                         aopGet(AOP(left),0,FALSE,FALSE), 
3091                         aopGet(AOP(result),0,FALSE,FALSE));
3092                 
3093                 if (SPEC_USIGN(opetype)){
3094                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3095                         genUMult8X8_16 (left, right, result, NULL);
3096                         
3097                         if (size > 2) {
3098                                 /* for filling the MSBs */
3099                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3100                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3101                         }
3102                 }
3103                 else{
3104                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3105                         
3106                         pic14_emitcode("mov","a,b");
3107                         
3108                         /* adjust the MSB if left or right neg */
3109                         
3110                         /* if one literal */
3111                         if (AOP_TYPE(right) == AOP_LIT){
3112                                 pic14_emitcode("multiply ","right is a lit");
3113                                 /* AND literal negative */
3114                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3115                                         /* adjust MSB (c==0 after mul) */
3116                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3117                                 }
3118                         }
3119                         else{
3120                                 genSMult8X8_16 (left, right, result, NULL);
3121                         }
3122                         
3123                         if(size > 2){
3124                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3125                                 /* get the sign */
3126                                 pic14_emitcode("rlc","a");
3127                                 pic14_emitcode("subb","a,acc");
3128                         }
3129                 }
3130                 
3131                 size -= 2;
3132                 offset = 2;
3133                 if (size > 0)
3134                         while (size--)
3135                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3136                         //aopPut(AOP(result),"a",offset++);
3137         }
3138 }
3139
3140 /*-----------------------------------------------------------------*/
3141 /* genMult - generates code for multiplication                                     */
3142 /*-----------------------------------------------------------------*/
3143 static void genMult (iCode *ic)
3144 {
3145         operand *left = IC_LEFT(ic);
3146         operand *right = IC_RIGHT(ic);
3147         operand *result= IC_RESULT(ic); 
3148         
3149         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3150         /* assign the amsops */
3151         aopOp (left,ic,FALSE);
3152         aopOp (right,ic,FALSE);
3153         aopOp (result,ic,TRUE);
3154         
3155         DEBUGpic14_AopType(__LINE__,left,right,result);
3156         
3157         /* special cases first */
3158         /* both are bits */
3159         if (AOP_TYPE(left) == AOP_CRY &&
3160                 AOP_TYPE(right)== AOP_CRY) {
3161                 genMultbits(left,right,result);
3162                 goto release ;
3163         }
3164         
3165         /* if both are of size == 1 */
3166         if (AOP_SIZE(left) == 1 &&
3167                 AOP_SIZE(right) == 1 ) {
3168                 genMultOneByte(left,right,result);
3169                 goto release ;
3170         }
3171         
3172         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3173         
3174         /* should have been converted to function call */
3175         //assert(0) ;
3176         
3177 release :
3178         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3179         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3180         freeAsmop(result,NULL,ic,TRUE); 
3181 }
3182
3183 /*-----------------------------------------------------------------*/
3184 /* genDivbits :- division of bits                                                                  */
3185 /*-----------------------------------------------------------------*/
3186 static void genDivbits (operand *left, 
3187                                                 operand *right, 
3188                                                 operand *result)
3189 {
3190         
3191         char *l;
3192         
3193         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3194         /* the result must be bit */      
3195         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3196         l = aopGet(AOP(left),0,FALSE,FALSE);
3197         
3198         MOVA(l);          
3199         
3200         pic14_emitcode("div","ab");
3201         pic14_emitcode("rrc","a");
3202         aopPut(AOP(result),"c",0);
3203 }
3204
3205 /*-----------------------------------------------------------------*/
3206 /* genDivOneByte : 8 bit division                                                                  */
3207 /*-----------------------------------------------------------------*/
3208 static void genDivOneByte (operand *left,
3209                                                    operand *right,
3210                                                    operand *result)
3211 {
3212         sym_link *opetype = operandType(result);
3213         char *l ;
3214         symbol *lbl ;
3215         int size,offset;
3216         
3217         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3218         size = AOP_SIZE(result) - 1;
3219         offset = 1;
3220         /* signed or unsigned */
3221         if (SPEC_USIGN(opetype)) {
3222                 /* unsigned is easy */
3223                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3224                 l = aopGet(AOP(left),0,FALSE,FALSE);
3225                 MOVA(l);                
3226                 pic14_emitcode("div","ab");
3227                 aopPut(AOP(result),"a",0);
3228                 while (size--)
3229                         aopPut(AOP(result),zero,offset++);
3230                 return ;
3231         }
3232         
3233         /* signed is a little bit more difficult */
3234         
3235         /* save the signs of the operands */
3236         l = aopGet(AOP(left),0,FALSE,FALSE);      
3237         MOVA(l);          
3238         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3239         pic14_emitcode("push","acc"); /* save it on the stack */
3240         
3241         /* now sign adjust for both left & right */
3242         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3243         MOVA(l);                 
3244         lbl = newiTempLabel(NULL);
3245         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3246         pic14_emitcode("cpl","a");   
3247         pic14_emitcode("inc","a");
3248         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3249         pic14_emitcode("mov","b,a");
3250         
3251         /* sign adjust left side */
3252         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3253         MOVA(l);
3254         
3255         lbl = newiTempLabel(NULL);
3256         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3257         pic14_emitcode("cpl","a");
3258         pic14_emitcode("inc","a");
3259         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3260         
3261         /* now the division */
3262         pic14_emitcode("div","ab");
3263         /* we are interested in the lower order
3264         only */
3265         pic14_emitcode("mov","b,a");
3266         lbl = newiTempLabel(NULL);
3267         pic14_emitcode("pop","acc");     
3268         /* if there was an over flow we don't 
3269         adjust the sign of the result */
3270         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3271         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3272         CLRC;
3273         pic14_emitcode("clr","a");
3274         pic14_emitcode("subb","a,b");
3275         pic14_emitcode("mov","b,a");
3276         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3277         
3278         /* now we are done */
3279         aopPut(AOP(result),"b",0);
3280         if(size > 0){
3281                 pic14_emitcode("mov","c,b.7");
3282                 pic14_emitcode("subb","a,acc");   
3283         }
3284         while (size--)
3285                 aopPut(AOP(result),"a",offset++);
3286         
3287 }
3288
3289 /*-----------------------------------------------------------------*/
3290 /* genDiv - generates code for division                                                    */
3291 /*-----------------------------------------------------------------*/
3292 static void genDiv (iCode *ic)
3293 {
3294         operand *left = IC_LEFT(ic);
3295         operand *right = IC_RIGHT(ic);
3296         operand *result= IC_RESULT(ic); 
3297         
3298         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3299         /* assign the amsops */
3300         aopOp (left,ic,FALSE);
3301         aopOp (right,ic,FALSE);
3302         aopOp (result,ic,TRUE);
3303         
3304         /* special cases first */
3305         /* both are bits */
3306         if (AOP_TYPE(left) == AOP_CRY &&
3307                 AOP_TYPE(right)== AOP_CRY) {
3308                 genDivbits(left,right,result);
3309                 goto release ;
3310         }
3311         
3312         /* if both are of size == 1 */
3313         if (AOP_SIZE(left) == 1 &&
3314                 AOP_SIZE(right) == 1 ) {
3315                 genDivOneByte(left,right,result);
3316                 goto release ;
3317         }
3318         
3319         /* should have been converted to function call */
3320         assert(0);
3321 release :
3322         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3323         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3324         freeAsmop(result,NULL,ic,TRUE); 
3325 }
3326
3327 /*-----------------------------------------------------------------*/
3328 /* genModbits :- modulus of bits                                                                   */
3329 /*-----------------------------------------------------------------*/
3330 static void genModbits (operand *left, 
3331                                                 operand *right, 
3332                                                 operand *result)
3333 {
3334         
3335         char *l;
3336         
3337         /* the result must be bit */      
3338         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3339         l = aopGet(AOP(left),0,FALSE,FALSE);
3340         
3341         MOVA(l);
3342         
3343         pic14_emitcode("div","ab");
3344         pic14_emitcode("mov","a,b");
3345         pic14_emitcode("rrc","a");
3346         aopPut(AOP(result),"c",0);
3347 }
3348
3349 /*-----------------------------------------------------------------*/
3350 /* genModOneByte : 8 bit modulus                                                                   */
3351 /*-----------------------------------------------------------------*/
3352 static void genModOneByte (operand *left,
3353                                                    operand *right,
3354                                                    operand *result)
3355 {
3356         sym_link *opetype = operandType(result);
3357         char *l ;
3358         symbol *lbl ;
3359         
3360         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3361         /* signed or unsigned */
3362         if (SPEC_USIGN(opetype)) {
3363                 /* unsigned is easy */
3364                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3365                 l = aopGet(AOP(left),0,FALSE,FALSE);
3366                 MOVA(l);        
3367                 pic14_emitcode("div","ab");
3368                 aopPut(AOP(result),"b",0);
3369                 return ;
3370         }
3371         
3372         /* signed is a little bit more difficult */
3373         
3374         /* save the signs of the operands */
3375         l = aopGet(AOP(left),0,FALSE,FALSE);      
3376         MOVA(l);
3377         
3378         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3379         pic14_emitcode("push","acc"); /* save it on the stack */
3380         
3381         /* now sign adjust for both left & right */
3382         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3383         MOVA(l);
3384         
3385         lbl = newiTempLabel(NULL);
3386         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3387         pic14_emitcode("cpl","a");   
3388         pic14_emitcode("inc","a");
3389         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3390         pic14_emitcode("mov","b,a"); 
3391         
3392         /* sign adjust left side */
3393         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3394         MOVA(l);
3395         
3396         lbl = newiTempLabel(NULL);
3397         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3398         pic14_emitcode("cpl","a");   
3399         pic14_emitcode("inc","a");
3400         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3401         
3402         /* now the multiplication */
3403         pic14_emitcode("div","ab");
3404         /* we are interested in the lower order
3405         only */
3406         lbl = newiTempLabel(NULL);
3407         pic14_emitcode("pop","acc");     
3408         /* if there was an over flow we don't 
3409         adjust the sign of the result */
3410         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3411         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3412         CLRC ;
3413         pic14_emitcode("clr","a");
3414         pic14_emitcode("subb","a,b");
3415         pic14_emitcode("mov","b,a");
3416         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3417         
3418         /* now we are done */
3419         aopPut(AOP(result),"b",0);
3420         
3421 }
3422
3423 /*-----------------------------------------------------------------*/
3424 /* genMod - generates code for division                                                    */
3425 /*-----------------------------------------------------------------*/
3426 static void genMod (iCode *ic)
3427 {
3428         operand *left = IC_LEFT(ic);
3429         operand *right = IC_RIGHT(ic);
3430         operand *result= IC_RESULT(ic);  
3431         
3432         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3433         /* assign the amsops */
3434         aopOp (left,ic,FALSE);
3435         aopOp (right,ic,FALSE);
3436         aopOp (result,ic,TRUE);
3437         
3438         /* special cases first */
3439         /* both are bits */
3440         if (AOP_TYPE(left) == AOP_CRY &&
3441                 AOP_TYPE(right)== AOP_CRY) {
3442                 genModbits(left,right,result);
3443                 goto release ;
3444         }
3445         
3446         /* if both are of size == 1 */
3447         if (AOP_SIZE(left) == 1 &&
3448                 AOP_SIZE(right) == 1 ) {
3449                 genModOneByte(left,right,result);
3450                 goto release ;
3451         }
3452         
3453         /* should have been converted to function call */
3454         assert(0);
3455         
3456 release :
3457         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3458         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3459         freeAsmop(result,NULL,ic,TRUE); 
3460 }
3461
3462 /*-----------------------------------------------------------------*/
3463 /* genIfxJump :- will create a jump depending on the ifx                   */
3464 /*-----------------------------------------------------------------*/
3465 /*
3466 note: May need to add parameter to indicate when a variable is in bit space.
3467 */
3468 static void genIfxJump (iCode *ic, char *jval)
3469 {
3470         
3471         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3472         /* if true label then we jump if condition
3473         supplied is true */
3474         if ( IC_TRUE(ic) ) {
3475                 
3476                 if(strcmp(jval,"a") == 0)
3477                         emitSKPZ;
3478                 else if (strcmp(jval,"c") == 0)
3479                         emitSKPC;
3480                 else {
3481                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3482                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3483                 }
3484                 
3485                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3486                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3487                 
3488         }
3489         else {
3490                 /* false label is present */
3491                 if(strcmp(jval,"a") == 0)
3492                         emitSKPNZ;
3493                 else if (strcmp(jval,"c") == 0)
3494                         emitSKPNC;
3495                 else {
3496                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3497                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3498                 }
3499                 
3500                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3501                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3502                 
3503         }
3504         
3505         
3506         /* mark the icode as generated */
3507         ic->generated = 1;
3508 }
3509
3510 /*-----------------------------------------------------------------*/
3511 /* genSkip                                                                                                                 */
3512 /*-----------------------------------------------------------------*/
3513 static void genSkip(iCode *ifx,int status_bit)
3514 {
3515         if(!ifx)
3516                 return;
3517         
3518         if ( IC_TRUE(ifx) ) {
3519                 switch(status_bit) {
3520                 case 'z':
3521                         emitSKPNZ;
3522                         break;
3523                         
3524                 case 'c':
3525                         emitSKPNC;
3526                         break;
3527                         
3528                 case 'd':
3529                         emitSKPDC;
3530                         break;
3531                         
3532                 }
3533                 
3534                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3535                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3536                 
3537         } else {
3538                 
3539                 switch(status_bit) {
3540                         
3541                 case 'z':
3542                         emitSKPZ;
3543                         break;
3544                         
3545                 case 'c':
3546                         emitSKPC;
3547                         break;
3548                         
3549                 case 'd':
3550                         emitSKPDC;
3551                         break;
3552                 }
3553                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3554                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3555                 
3556         }
3557         
3558 }
3559
3560 /*-----------------------------------------------------------------*/
3561 /* genSkipc                                                                                                        */
3562 /*-----------------------------------------------------------------*/
3563 static void genSkipc(resolvedIfx *rifx)
3564 {
3565         if(!rifx)
3566                 return;
3567         
3568         if(rifx->condition)
3569                 emitSKPC;
3570         else
3571                 emitSKPNC;
3572         
3573         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3574         rifx->generated = 1;
3575 }
3576
3577 /*-----------------------------------------------------------------*/
3578 /* genSkipz2                                                                                                       */
3579 /*-----------------------------------------------------------------*/
3580 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3581 {
3582         if(!rifx)
3583                 return;
3584         
3585         if( (rifx->condition ^ invert_condition) & 1)
3586                 emitSKPZ;
3587         else
3588                 emitSKPNZ;
3589         
3590         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3591         rifx->generated = 1;
3592 }
3593
3594 /*-----------------------------------------------------------------*/
3595 /* genSkipz                                                        */
3596 /*-----------------------------------------------------------------*/
3597 static void genSkipz(iCode *ifx, int condition)
3598 {
3599         if(!ifx)
3600                 return;
3601         
3602         if(condition)
3603                 emitSKPNZ;
3604         else
3605                 emitSKPZ;
3606         
3607         if ( IC_TRUE(ifx) )
3608                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3609         else
3610                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3611         
3612         if ( IC_TRUE(ifx) )
3613                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3614         else
3615                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3616         
3617 }
3618 /*-----------------------------------------------------------------*/
3619 /* genSkipCond                                                     */
3620 /*-----------------------------------------------------------------*/
3621 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3622 {
3623         if(!rifx)
3624                 return;
3625         
3626         if(rifx->condition)
3627                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3628         else
3629                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3630         
3631         
3632         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3633         rifx->generated = 1;
3634 }
3635
3636 #if 0
3637 /*-----------------------------------------------------------------*/
3638 /* genChkZeroes :- greater or less than comparison                 */
3639 /*     For each byte in a literal that is zero, inclusive or the   */
3640 /*     the corresponding byte in the operand with W                */
3641 /*     returns true if any of the bytes are zero                   */
3642 /*-----------------------------------------------------------------*/
3643 static int genChkZeroes(operand *op, int lit,  int size)
3644 {
3645         
3646         int i;
3647         int flag =1;
3648         
3649         while(size--) {
3650                 i = (lit >> (size*8)) & 0xff;
3651                 
3652                 if(i==0) {
3653                         if(flag) 
3654                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3655                         else
3656                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3657                         flag = 0;
3658                 }
3659         }
3660         
3661         return (flag==0);
3662 }
3663 #endif
3664
3665 /*-----------------------------------------------------------------*/
3666 /* genCmp :- greater or less than comparison                       */
3667 /*-----------------------------------------------------------------*/
3668 static void genCmp (operand *left,operand *right,
3669                                         operand *result, iCode *ifx, int sign)
3670 {
3671         int size; //, offset = 0 ;
3672         unsigned long lit = 0L,i = 0;
3673         resolvedIfx rFalseIfx;
3674         //  resolvedIfx rTrueIfx;
3675         symbol *truelbl;
3676         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3677         /*
3678         if(ifx) {
3679         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3680         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3681         }
3682         */
3683         
3684         resolveIfx(&rFalseIfx,ifx);
3685         truelbl  = newiTempLabel(NULL);
3686         size = max(AOP_SIZE(left),AOP_SIZE(right));
3687         
3688         DEBUGpic14_AopType(__LINE__,left,right,result);
3689         
3690 #define _swapp
3691         
3692         /* if literal is on the right then swap with left */
3693         if ((AOP_TYPE(right) == AOP_LIT)) {
3694                 operand *tmp = right ;
3695                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3696                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3697 #ifdef _swapp
3698                 
3699                 lit = (lit - 1) & mask;
3700                 right = left;
3701                 left = tmp;
3702                 rFalseIfx.condition ^= 1;
3703 #endif
3704                 
3705         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3706                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3707         }
3708         
3709         
3710         //if(IC_TRUE(ifx) == NULL)
3711         /* if left & right are bit variables */
3712         if (AOP_TYPE(left) == AOP_CRY &&
3713                 AOP_TYPE(right) == AOP_CRY ) {
3714                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3715                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3716         } else {
3717         /* subtract right from left if at the
3718         end the carry flag is set then we know that
3719                 left is greater than right */
3720                 
3721                 symbol *lbl  = newiTempLabel(NULL);
3722                 
3723 #ifndef _swapp
3724                 if(AOP_TYPE(right) == AOP_LIT) {
3725                         
3726                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3727                         
3728                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3729                         
3730                         /* special cases */
3731                         
3732                         if(lit == 0) {
3733                                 
3734                                 if(sign != 0) 
3735                                         genSkipCond(&rFalseIfx,left,size-1,7);
3736                                 else 
3737                                         /* no need to compare to 0...*/
3738                                         /* NOTE: this is a de-generate compare that most certainly 
3739                                         *       creates some dead code. */
3740                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3741                                 
3742                                 if(ifx) ifx->generated = 1;
3743                                 return;
3744                                 
3745                         }
3746                         size--;
3747                         
3748                         if(size == 0) {
3749                                 //i = (lit >> (size*8)) & 0xff;
3750                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3751                                 
3752                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3753                                 
3754                                 i = ((0-lit) & 0xff);
3755                                 if(sign) {
3756                                         if( i == 0x81) { 
3757                                         /* lit is 0x7f, all signed chars are less than
3758                                                 * this except for 0x7f itself */
3759                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3760                                                 genSkipz2(&rFalseIfx,0);
3761                                         } else {
3762                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3763                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3764                                                 genSkipc(&rFalseIfx);
3765                                         }
3766                                         
3767                                 } else {
3768                                         if(lit == 1) {
3769                                                 genSkipz2(&rFalseIfx,1);
3770                                         } else {
3771                                                 emitpcode(POC_ADDLW, popGetLit(i));
3772                                                 genSkipc(&rFalseIfx);
3773                                         }
3774                                 }
3775                                 
3776                                 if(ifx) ifx->generated = 1;
3777                                 return;
3778                         }
3779                         
3780                         /* chars are out of the way. now do ints and longs */
3781                         
3782                         
3783                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3784                         
3785                         /* special cases */
3786                         
3787                         if(sign) {
3788                                 
3789                                 if(lit == 0) {
3790                                         genSkipCond(&rFalseIfx,left,size,7);
3791                                         if(ifx) ifx->generated = 1;
3792                                         return;
3793                                 }
3794                                 
3795                                 if(lit <0x100) {
3796                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3797                                         
3798                                         //rFalseIfx.condition ^= 1;
3799                                         //genSkipCond(&rFalseIfx,left,size,7);
3800                                         //rFalseIfx.condition ^= 1;
3801                                         
3802                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3803                                         if(rFalseIfx.condition)
3804                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3805                                         else
3806                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3807                                         
3808                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3809                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3810                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3811                                         
3812                                         while(size > 1)
3813                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3814                                         
3815                                         if(rFalseIfx.condition) {
3816                                                 emitSKPZ;
3817                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3818                                                 
3819                                         } else {
3820                                                 emitSKPNZ;
3821                                         }
3822                                         
3823                                         genSkipc(&rFalseIfx);
3824                                         emitpLabel(truelbl->key);
3825                                         if(ifx) ifx->generated = 1;
3826                                         return;
3827                                         
3828                                 }
3829                                 
3830                                 if(size == 1) {
3831                                         
3832                                         if( (lit & 0xff) == 0) {
3833                                                 /* lower byte is zero */
3834                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3835                                                 i = ((lit >> 8) & 0xff) ^0x80;
3836                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3837                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3838                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3839                                                 genSkipc(&rFalseIfx);
3840                                                 
3841                                                 
3842                                                 if(ifx) ifx->generated = 1;
3843                                                 return;
3844                                                 
3845                                         }
3846                                 } else {
3847                                         /* Special cases for signed longs */
3848                                         if( (lit & 0xffffff) == 0) {
3849                                                 /* lower byte is zero */
3850                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3851                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3852                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3853                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3854                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3855                                                 genSkipc(&rFalseIfx);
3856                                                 
3857                                                 
3858                                                 if(ifx) ifx->generated = 1;
3859                                                 return;
3860                                                 
3861                                         }
3862                                         
3863                                 }
3864                                 
3865                                 
3866                                 if(lit & (0x80 << (size*8))) {
3867                                         /* lit is negative */
3868                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3869                                         
3870                                         //genSkipCond(&rFalseIfx,left,size,7);
3871                                         
3872                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3873                                         
3874                                         if(rFalseIfx.condition)
3875                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3876                                         else
3877                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3878                                         
3879                                         
3880                                 } else {
3881                                         /* lit is positive */
3882                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3883                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3884                                         if(rFalseIfx.condition)
3885                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3886                                         else
3887                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3888                                         
3889                                 }
3890                                 
3891                                 /* There are no more special cases, so perform a general compare */
3892                                 
3893                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3894                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3895                                 
3896                                 while(size--) {
3897                                         
3898                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3899                                         emitSKPNZ;
3900                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3901                                 }
3902                                 //rFalseIfx.condition ^= 1;
3903                                 genSkipc(&rFalseIfx);
3904                                 
3905                                 emitpLabel(truelbl->key);
3906                                 
3907                                 if(ifx) ifx->generated = 1;
3908                                 return;
3909                                 
3910                                 
3911                         }
3912
3913
3914                         /* sign is out of the way. So now do an unsigned compare */
3915                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3916
3917
3918                         /* General case - compare to an unsigned literal on the right.*/
3919
3920                         i = (lit >> (size*8)) & 0xff;
3921                         emitpcode(POC_MOVLW, popGetLit(i));
3922                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3923                         while(size--) {
3924                                 i = (lit >> (size*8)) & 0xff;
3925                                 
3926                                 if(i) {
3927                                         emitpcode(POC_MOVLW, popGetLit(i));
3928                                         emitSKPNZ;
3929                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3930                                 } else {
3931                                 /* this byte of the lit is zero, 
3932                                         *if it's not the last then OR in the variable */
3933                                         if(size)
3934                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
3935                                 }
3936                         }
3937
3938
3939                 emitpLabel(lbl->key);
3940                 //if(emitFinalCheck)
3941                 genSkipc(&rFalseIfx);
3942                 if(sign)
3943                         emitpLabel(truelbl->key);
3944
3945                 if(ifx) ifx->generated = 1;
3946                 return;
3947
3948
3949                 }
3950 #endif  // _swapp
3951
3952                 if(AOP_TYPE(left) == AOP_LIT) {
3953                         //symbol *lbl = newiTempLabel(NULL);
3954                         
3955                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3956                         
3957                         
3958                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3959                         
3960                         /* Special cases */
3961                         if((lit == 0) && (sign == 0)){
3962                                 
3963                                 size--;
3964                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3965                                 while(size) 
3966                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
3967                                 
3968                                 genSkipz2(&rFalseIfx,0);
3969                                 if(ifx) ifx->generated = 1;
3970                                 return;
3971                         }
3972                         
3973                         if(size==1) {
3974                                 /* Special cases */
3975                                 lit &= 0xff;
3976                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3977                                         /* degenerate compare can never be true */
3978                                         if(rFalseIfx.condition == 0)
3979                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3980                                         
3981                                         if(ifx) ifx->generated = 1;
3982                                         return;
3983                                 }
3984                                 
3985                                 if(sign) {
3986                                         /* signed comparisons to a literal byte */
3987                                         
3988                                         int lp1 = (lit+1) & 0xff;
3989                                         
3990                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3991                                         switch (lp1) {
3992                                         case 0:
3993                                                 rFalseIfx.condition ^= 1;
3994                                                 genSkipCond(&rFalseIfx,right,0,7);
3995                                                 break;
3996                                         case 0x7f:
3997                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3998                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3999                                                 genSkipz2(&rFalseIfx,1);
4000                                                 break;
4001                                         default:
4002                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4003                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4004                                                 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4005                                                 rFalseIfx.condition ^= 1;
4006                                                 genSkipc(&rFalseIfx);
4007                                                 break;
4008                                         }
4009                                         if(ifx) ifx->generated = 1;
4010                                 } else {
4011                                         /* unsigned comparisons to a literal byte */
4012                                         
4013                                         switch(lit & 0xff ) {
4014                                         case 0:
4015                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4016                                                 genSkipz2(&rFalseIfx,0);
4017                                                 if(ifx) ifx->generated = 1;
4018                                                 break;
4019                                         case 0x7f:
4020                                                 genSkipCond(&rFalseIfx,right,0,7);
4021                                                 if(ifx) ifx->generated = 1;
4022                                                 break;
4023                                                 
4024                                         default:
4025                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4026                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4027                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4028                                                 rFalseIfx.condition ^= 1;
4029                                                 if (AOP_TYPE(result) == AOP_CRY) {
4030                                                         genSkipc(&rFalseIfx);
4031                                                         if(ifx) ifx->generated = 1;
4032                                                 } else {
4033                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4034                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4035                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4036                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4037                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4038                                                 }       
4039                                                 break;
4040                                         }
4041                                 }
4042                                 
4043                                 //goto check_carry;
4044                                 return;
4045                                 
4046                         } else {
4047                                 
4048                                 /* Size is greater than 1 */
4049                                 
4050                                 if(sign) {
4051                                         int lp1 = lit+1;
4052                                         
4053                                         size--;
4054                                         
4055                                         if(lp1 == 0) {
4056                                                 /* this means lit = 0xffffffff, or -1 */
4057                                                 
4058                                                 
4059                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4060                                                 rFalseIfx.condition ^= 1;
4061                                                 genSkipCond(&rFalseIfx,right,size,7);
4062                                                 if(ifx) ifx->generated = 1;
4063                                                 return;
4064                                         }
4065                                         
4066                                         if(lit == 0) {
4067                                                 int s = size;
4068                                                 
4069                                                 if(rFalseIfx.condition) {
4070                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4071                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4072                                                 }
4073                                                 
4074                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4075                                                 while(size--)
4076                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4077                                                 
4078                                                 
4079                                                 emitSKPZ;
4080                                                 if(rFalseIfx.condition) {
4081                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4082                                                         emitpLabel(truelbl->key);
4083                                                 }else {
4084                                                         rFalseIfx.condition ^= 1;
4085                                                         genSkipCond(&rFalseIfx,right,s,7);
4086                                                 }
4087                                                 
4088                                                 if(ifx) ifx->generated = 1;
4089                                                 return;
4090                                         }
4091                                         
4092                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4093                                                 /* lower byte of signed word is zero */
4094                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4095                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4096                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4097                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4098                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4099                                                 rFalseIfx.condition ^= 1;
4100                                                 genSkipc(&rFalseIfx);
4101                                                 
4102                                                 
4103                                                 if(ifx) ifx->generated = 1;
4104                                                 return;
4105                                         }
4106                                         
4107                                         if(lit & (0x80 << (size*8))) {
4108                                                 /* Lit is less than zero */
4109                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4110                                                 //rFalseIfx.condition ^= 1;
4111                                                 //genSkipCond(&rFalseIfx,left,size,7);
4112                                                 //rFalseIfx.condition ^= 1;
4113                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4114                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4115                                                 
4116                                                 if(rFalseIfx.condition)
4117                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4118                                                 else
4119                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4120                                                 
4121                                                 
4122                                         } else {
4123                                                 /* Lit is greater than or equal to zero */
4124                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4125                                                 //rFalseIfx.condition ^= 1;
4126                                                 //genSkipCond(&rFalseIfx,right,size,7);
4127                                                 //rFalseIfx.condition ^= 1;
4128                                                 
4129                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4130                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4131                                                 
4132                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4133                                                 if(rFalseIfx.condition)
4134                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4135                                                 else
4136                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4137                                                 
4138                                         }
4139                                         
4140                                         
4141                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4142                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4143                                         
4144                                         while(size--) {
4145                                                 
4146                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4147                                                 emitSKPNZ;
4148                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4149                                         }
4150                                         rFalseIfx.condition ^= 1;
4151                                         //rFalseIfx.condition = 1;
4152                                         genSkipc(&rFalseIfx);
4153                                         
4154                                         emitpLabel(truelbl->key);
4155                                         
4156                                         if(ifx) ifx->generated = 1;
4157                                         return;
4158                                         // end of if (sign)
4159                                 } else {
4160                                         
4161                                         /* compare word or long to an unsigned literal on the right.*/
4162                                         
4163                                         
4164                                         size--;
4165                                         if(lit < 0xff) {
4166                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4167                                                 switch (lit) {
4168                                                 case 0:
4169                                                         break; /* handled above */
4170                                                 /*
4171                                                 case 0xff:
4172                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4173                                                         while(size--)
4174                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4175                                                         genSkipz2(&rFalseIfx,0);
4176                                                         break;
4177                                                 */
4178                                                 default:
4179                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4180                                                         while(--size)
4181                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4182                                                         
4183                                                         emitSKPZ;
4184                                                         if(rFalseIfx.condition)
4185                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4186                                                         else
4187                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4188                                                         
4189                                                         
4190                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4191                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4192                                                         
4193                                                         rFalseIfx.condition ^= 1;
4194                                                         genSkipc(&rFalseIfx);
4195                                                 }
4196                                                 
4197                                                 emitpLabel(truelbl->key);
4198                                                 
4199                                                 if(ifx) ifx->generated = 1;
4200                                                 return;
4201                                         }
4202                                         
4203                                         
4204                                         lit++;
4205                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4206                                         i = (lit >> (size*8)) & 0xff;
4207                                         
4208                                         emitpcode(POC_MOVLW, popGetLit(i));
4209                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4210                                         
4211                                         while(size--) {
4212                                                 i = (lit >> (size*8)) & 0xff;
4213                                                 
4214                                                 if(i) {
4215                                                         emitpcode(POC_MOVLW, popGetLit(i));
4216                                                         emitSKPNZ;
4217                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4218                                                 } else {
4219                                                 /* this byte of the lit is zero, 
4220                                                         *if it's not the last then OR in the variable */
4221                                                         if(size)
4222                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4223                                                 }
4224                                         }
4225                                         
4226                                         
4227                                         emitpLabel(lbl->key);
4228                                         
4229                                         rFalseIfx.condition ^= 1;
4230                                         genSkipc(&rFalseIfx);
4231                                 }
4232                                 
4233                                 if(sign)
4234                                         emitpLabel(truelbl->key);
4235                                 if(ifx) ifx->generated = 1;
4236                                 return;
4237                         }
4238                 }
4239                 /* Compare two variables */
4240                 
4241                 DEBUGpic14_emitcode(";sign","%d",sign);
4242                 
4243                 size--;
4244                 if(sign) {
4245                         /* Sigh. thus sucks... */
4246                         if(size) {
4247                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4248                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4249                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4250                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4251                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4252                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4253                         } else {
4254                                 /* Signed char comparison */
4255                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4256                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4257                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4258                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4259                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4260                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4261                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4262                                 
4263                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4264                                 genSkipc(&rFalseIfx);
4265                                 
4266                                 if(ifx) ifx->generated = 1;
4267                                 return;
4268                         }
4269                         
4270                 } else {
4271                         
4272                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4273                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4274                 }
4275                 
4276                 
4277                 /* The rest of the bytes of a multi-byte compare */
4278                 while (size) {
4279                         
4280                         emitSKPZ;
4281                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4282                         size--;
4283                         
4284                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4285                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4286                         
4287                         
4288                 }
4289                 
4290                 emitpLabel(lbl->key);
4291                 
4292                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4293                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4294                         (AOP_TYPE(result) == AOP_REG)) {
4295                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4296                         emitpcode(POC_RLF, popGet(AOP(result),0));
4297                 } else {
4298                         genSkipc(&rFalseIfx);
4299                 }       
4300                 //genSkipc(&rFalseIfx);
4301                 if(ifx) ifx->generated = 1;
4302                 
4303                 return;
4304                 
4305         }
4306         
4307         // check_carry:
4308         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4309                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4310                 pic14_outBitC(result);
4311         } else {
4312                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4313                 /* if the result is used in the next
4314                 ifx conditional branch then generate
4315                 code a little differently */
4316                 if (ifx )
4317                         genIfxJump (ifx,"c");
4318                 else
4319                         pic14_outBitC(result);
4320                 /* leave the result in acc */
4321         }
4322         
4323 }
4324
4325 /*-----------------------------------------------------------------*/
4326 /* genCmpGt :- greater than comparison                             */
4327 /*-----------------------------------------------------------------*/
4328 static void genCmpGt (iCode *ic, iCode *ifx)
4329 {
4330         operand *left, *right, *result;
4331         sym_link *letype , *retype;
4332         int sign ;
4333         
4334         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4335         left = IC_LEFT(ic);
4336         right= IC_RIGHT(ic);
4337         result = IC_RESULT(ic);
4338         
4339         letype = getSpec(operandType(left));
4340         retype =getSpec(operandType(right));
4341         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4342         /* assign the amsops */
4343         aopOp (left,ic,FALSE);
4344         aopOp (right,ic,FALSE);
4345         aopOp (result,ic,TRUE);
4346         
4347         genCmp(right, left, result, ifx, sign);
4348         
4349         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4350         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4351         freeAsmop(result,NULL,ic,TRUE); 
4352 }
4353
4354 /*-----------------------------------------------------------------*/
4355 /* genCmpLt - less than comparisons                                */
4356 /*-----------------------------------------------------------------*/
4357 static void genCmpLt (iCode *ic, iCode *ifx)
4358 {
4359         operand *left, *right, *result;
4360         sym_link *letype , *retype;
4361         int sign ;
4362         
4363         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4364         left = IC_LEFT(ic);
4365         right= IC_RIGHT(ic);
4366         result = IC_RESULT(ic);
4367         
4368         letype = getSpec(operandType(left));
4369         retype =getSpec(operandType(right));
4370         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4371         
4372         /* assign the amsops */
4373         aopOp (left,ic,FALSE);
4374         aopOp (right,ic,FALSE);
4375         aopOp (result,ic,TRUE);
4376         
4377         genCmp(left, right, result, ifx, sign);
4378         
4379         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4381         freeAsmop(result,NULL,ic,TRUE); 
4382 }
4383
4384 /*-----------------------------------------------------------------*/
4385 /* genc16bit2lit - compare a 16 bit value to a literal             */
4386 /*-----------------------------------------------------------------*/
4387 static void genc16bit2lit(operand *op, int lit, int offset)
4388 {
4389         int i;
4390         
4391         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4392         if( (lit&0xff) == 0) 
4393                 i=1;
4394         else
4395                 i=0;
4396         
4397         switch( BYTEofLONG(lit,i)) { 
4398         case 0:
4399                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4400                 break;
4401         case 1:
4402                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4403                 break;
4404         case 0xff:
4405                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4406                 break;
4407         default:
4408                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4409                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4410         }
4411         
4412         i ^= 1;
4413         
4414         switch( BYTEofLONG(lit,i)) { 
4415         case 0:
4416                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4417                 break;
4418         case 1:
4419                 emitSKPNZ;
4420                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4421                 break;
4422         case 0xff:
4423                 emitSKPNZ;
4424                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4425                 break;
4426         default:
4427                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4428                 emitSKPNZ;
4429                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4430                 
4431         }
4432         
4433 }
4434
4435 /*-----------------------------------------------------------------*/
4436 /* gencjneshort - compare and jump if not equal                    */
4437 /*-----------------------------------------------------------------*/
4438 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4439 {
4440         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4441         int offset = 0;
4442         int res_offset = 0;  /* the result may be a different size then left or right */
4443         int res_size = AOP_SIZE(result);
4444         resolvedIfx rIfx;
4445         symbol *lbl;
4446         
4447         unsigned long lit = 0L;
4448         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4449         DEBUGpic14_AopType(__LINE__,left,right,result);
4450         if(result)
4451                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4452         resolveIfx(&rIfx,ifx);
4453         lbl =  newiTempLabel(NULL);
4454         
4455         
4456         /* if the left side is a literal or 
4457         if the right is in a pointer register and left 
4458         is not */
4459         if ((AOP_TYPE(left) == AOP_LIT) || 
4460                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4461                 operand *t = right;
4462                 right = left;
4463                 left = t;
4464         }
4465         if(AOP_TYPE(right) == AOP_LIT)
4466                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4467         
4468         /* if the right side is a literal then anything goes */
4469         if (AOP_TYPE(right) == AOP_LIT &&
4470                 AOP_TYPE(left) != AOP_DIR ) {
4471                 switch(size) {
4472                 case 2:
4473                         genc16bit2lit(left, lit, 0);
4474                         emitSKPNZ;
4475                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4476                         break;
4477                 default:
4478                         while (size--) {
4479                                 if(lit & 0xff) {
4480                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4481                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4482                                 } else {
4483                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4484                                 }
4485                                 
4486                                 emitSKPNZ;
4487                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4488                                 offset++;
4489                                 if(res_offset < res_size-1)
4490                                         res_offset++;
4491                                 lit >>= 8;
4492                         }
4493                         break;
4494                 }
4495         }
4496         
4497         /* if the right side is in a register or in direct space or
4498         if the left is a pointer register & right is not */    
4499         else if (AOP_TYPE(right) == AOP_REG ||
4500                 AOP_TYPE(right) == AOP_DIR || 
4501                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4502                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4503                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4504                 int lbl_key = lbl->key;
4505                 
4506                 if(result) {
4507                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4508                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4509                 }else {
4510                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4511                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4512                                 __FUNCTION__,__LINE__);
4513                         return;
4514                 }
4515                 
4516                 /*     switch(size) { */
4517                 /*     case 2: */
4518                 /*       genc16bit2lit(left, lit, 0); */
4519                 /*       emitSKPNZ; */
4520                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4521                 /*       break; */
4522                 /*     default: */
4523                 while (size--) {
4524                         int emit_skip=1;
4525                         if((AOP_TYPE(left) == AOP_DIR) && 
4526                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4527                                 
4528                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4529                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4530                                 
4531                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4532                                 
4533                                 switch (lit & 0xff) {
4534                                 case 0:
4535                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4536                                         break;
4537                                 case 1:
4538                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4539                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4540                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4541                                         emit_skip=0;
4542                                         break;
4543                                 case 0xff:
4544                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4545                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4546                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4547                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4548                                         emit_skip=0;
4549                                         break;
4550                                 default:
4551                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4552                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4553                                 }
4554                                 lit >>= 8;
4555                                 
4556                         } else {
4557                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4558                         }
4559                         if(emit_skip) {
4560                                 if(AOP_TYPE(result) == AOP_CRY) {
4561                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4562                                         if(rIfx.condition)
4563                                                 emitSKPNZ;
4564                                         else
4565                                                 emitSKPZ;
4566                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4567                                 } else {
4568                                         /* fix me. probably need to check result size too */
4569                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4570                                         if(rIfx.condition)
4571                                                 emitSKPZ;
4572                                         else
4573                                                 emitSKPNZ;
4574                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4575                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4576                                 }
4577                                 if(ifx)
4578                                         ifx->generated=1;
4579                         }
4580                         emit_skip++;
4581                         offset++;
4582                         if(res_offset < res_size-1)
4583                                 res_offset++;
4584                 }
4585                 /*       break; */
4586                 /*     } */
4587         } else if(AOP_TYPE(right) == AOP_REG &&
4588                 AOP_TYPE(left) != AOP_DIR){
4589                 
4590                 while(size--) {
4591                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4592                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4593                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4594                         if(rIfx.condition)
4595                                 emitSKPNZ;
4596                         else
4597                                 emitSKPZ;
4598                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4599                         offset++;
4600                         if(res_offset < res_size-1)
4601                                 res_offset++;
4602                 }
4603                 
4604         }else{
4605                 /* right is a pointer reg need both a & b */
4606                 while(size--) {
4607                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4608                         if(strcmp(l,"b"))
4609                                 pic14_emitcode("mov","b,%s",l);
4610                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4611                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4612                         offset++;
4613                 }
4614         }
4615         
4616         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4617         if(!rIfx.condition)
4618                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4619         
4620         emitpLabel(lbl->key);
4621         
4622         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4623         
4624         if(ifx)
4625                 ifx->generated = 1;
4626 }
4627
4628 #if 0
4629 /*-----------------------------------------------------------------*/
4630 /* gencjne - compare and jump if not equal                         */
4631 /*-----------------------------------------------------------------*/
4632 static void gencjne(operand *left, operand *right, iCode *ifx)
4633 {
4634         symbol *tlbl  = newiTempLabel(NULL);
4635         
4636         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4637         gencjneshort(left, right, lbl);
4638         
4639         pic14_emitcode("mov","a,%s",one);
4640         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4641         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4642         pic14_emitcode("clr","a");
4643         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4644         
4645         emitpLabel(lbl->key);
4646         emitpLabel(tlbl->key);
4647         
4648 }
4649 #endif
4650
4651 /*-----------------------------------------------------------------*/
4652 /* genCmpEq - generates code for equal to                          */
4653 /*-----------------------------------------------------------------*/
4654 static void genCmpEq (iCode *ic, iCode *ifx)
4655 {
4656         operand *left, *right, *result;
4657         unsigned long lit = 0L;
4658         int size,offset=0;
4659         
4660         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4661         
4662         if(ifx)
4663                 DEBUGpic14_emitcode ("; ifx is non-null","");
4664         else
4665                 DEBUGpic14_emitcode ("; ifx is null","");
4666         
4667         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4668         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4669         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4670         
4671         size = max(AOP_SIZE(left),AOP_SIZE(right));
4672         
4673         DEBUGpic14_AopType(__LINE__,left,right,result);
4674         
4675         /* if literal, literal on the right or 
4676         if the right is in a pointer register and left 
4677         is not */
4678         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4679                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4680                 operand *tmp = right ;
4681                 right = left;
4682                 left = tmp;
4683         }
4684         
4685         
4686         if(ifx && !AOP_SIZE(result)){
4687                 symbol *tlbl;
4688                 /* if they are both bit variables */
4689                 if (AOP_TYPE(left) == AOP_CRY &&
4690                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4691                         if(AOP_TYPE(right) == AOP_LIT){
4692                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4693                                 if(lit == 0L){
4694                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4695                                         pic14_emitcode("cpl","c");
4696                                 } else if(lit == 1L) {
4697                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4698                                 } else {
4699                                         pic14_emitcode("clr","c");
4700                                 }
4701                                 /* AOP_TYPE(right) == AOP_CRY */
4702                         } else {
4703                                 symbol *lbl = newiTempLabel(NULL);
4704                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4705                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4706                                 pic14_emitcode("cpl","c");
4707                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4708                         }
4709                         /* if true label then we jump if condition
4710                         supplied is true */
4711                         tlbl = newiTempLabel(NULL);
4712                         if ( IC_TRUE(ifx) ) {
4713                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4714                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4715                         } else {
4716                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4717                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4718                         }
4719                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4720                         
4721                         {
4722                                 /* left and right are both bit variables, result is carry */
4723                                 resolvedIfx rIfx;
4724                                 
4725                                 resolveIfx(&rIfx,ifx);
4726                                 
4727                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4728                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4729                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4730                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4731                                 genSkipz2(&rIfx,0);
4732                         }
4733                 } else {
4734                         
4735                         /* They're not both bit variables. Is the right a literal? */
4736                         if(AOP_TYPE(right) == AOP_LIT) {
4737                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4738                                 
4739                                 switch(size) {
4740                                         
4741                                 case 1:
4742                                         switch(lit & 0xff) {
4743                                         case 1:
4744                                                 if ( IC_TRUE(ifx) ) {
4745                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4746                                                         emitSKPNZ;
4747                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4748                                                 } else {
4749                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4750                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4751                                                 }
4752                                                 break;
4753                                         case 0xff:
4754                                                 if ( IC_TRUE(ifx) ) {
4755                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4756                                                         emitSKPNZ;
4757                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4758                                                 } else {
4759                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4760                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4761                                                 }
4762                                                 break;
4763                                         default:
4764                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4765                                                 if(lit)
4766                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4767                                                 genSkip(ifx,'z');
4768                                         }
4769                                         
4770                                         
4771                                         /* end of size == 1 */
4772                                         break;
4773                                         
4774                                         case 2:
4775                                                 genc16bit2lit(left,lit,offset);
4776                                                 genSkip(ifx,'z');
4777                                                 break;
4778                                                 /* end of size == 2 */
4779                                                 
4780                                         default:
4781                                                 /* size is 4 */
4782                                                 if(lit==0) {
4783                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4784                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4785                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4786                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4787                                                         
4788                                                 } else {
4789                                                         
4790                                                         /* search for patterns that can be optimized */
4791                                                         
4792                                                         genc16bit2lit(left,lit,0);
4793                                                         lit >>= 16;
4794                                                         if(lit) {
4795                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4796                                                                 //genSkip(ifx,'z');
4797                                                                 genc16bit2lit(left,lit,2);
4798                                                         } else {
4799                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4800                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4801                                                                 
4802                                                         }
4803                                                         
4804                                                 }
4805                                                 
4806                                                 genSkip(ifx,'z');
4807                                 }
4808                                 
4809                                 ifx->generated = 1;
4810                                 goto release ;
4811                                 
4812                                 
4813                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4814                                 /* we know the left is not a bit, but that the right is */
4815                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4816                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4817                                         popGet(AOP(right),offset));
4818                                 emitpcode(POC_XORLW,popGetLit(1));
4819                                 
4820                                 /* if the two are equal, then W will be 0 and the Z bit is set
4821                                 * we could test Z now, or go ahead and check the high order bytes if
4822                                 * the variable we're comparing is larger than a byte. */
4823                                 
4824                                 while(--size)
4825                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4826                                 
4827                                 if ( IC_TRUE(ifx) ) {
4828                                         emitSKPNZ;
4829                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4830                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4831                                 } else {
4832                                         emitSKPZ;
4833                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4834                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4835                                 }
4836                                 
4837                         } else {
4838                                 /* They're both variables that are larger than bits */
4839                                 int s = size;
4840                                 
4841                                 tlbl = newiTempLabel(NULL);
4842                                 
4843                                 while(size--) {
4844                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4845                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4846                                         
4847                                         if ( IC_TRUE(ifx) ) {
4848                                                 if(size) {
4849                                                         emitSKPZ;
4850                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4851                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4852                                                 } else {
4853                                                         emitSKPNZ;
4854                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4855                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4856                                                 }
4857                                         } else {
4858                                                 emitSKPZ;
4859                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4860                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4861                                         }
4862                                         offset++;
4863                                 }
4864                                 if(s>1 && IC_TRUE(ifx)) {
4865                                         emitpLabel(tlbl->key);
4866                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4867                                 }
4868                         }
4869                 }
4870                 /* mark the icode as generated */
4871                 ifx->generated = 1;
4872                 goto release ;
4873         }
4874   
4875   /* if they are both bit variables */
4876   if (AOP_TYPE(left) == AOP_CRY &&
4877           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4878           if(AOP_TYPE(right) == AOP_LIT){
4879                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4880                   if(lit == 0L){
4881                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4882                           pic14_emitcode("cpl","c");
4883                   } else if(lit == 1L) {
4884                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4885                   } else {
4886                           pic14_emitcode("clr","c");
4887                   }
4888                   /* AOP_TYPE(right) == AOP_CRY */
4889           } else {
4890                   symbol *lbl = newiTempLabel(NULL);
4891                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4892                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4893                   pic14_emitcode("cpl","c");
4894                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4895           }
4896           /* c = 1 if egal */
4897           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4898                   pic14_outBitC(result);
4899                   goto release ;
4900           }
4901           if (ifx) {
4902                   genIfxJump (ifx,"c");
4903                   goto release ;
4904           }
4905           /* if the result is used in an arithmetic operation
4906           then put the result in place */
4907           pic14_outBitC(result);
4908   } else {
4909           
4910           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4911           gencjne(left,right,result,ifx);
4912           /*
4913           if(ifx) 
4914           gencjne(left,right,newiTempLabel(NULL));
4915           else {
4916           if(IC_TRUE(ifx)->key)
4917           gencjne(left,right,IC_TRUE(ifx)->key);
4918           else
4919           gencjne(left,right,IC_FALSE(ifx)->key);
4920           ifx->generated = 1;
4921           goto release ;
4922           }
4923           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4924           aopPut(AOP(result),"a",0);
4925           goto release ;
4926           }
4927           
4928                 if (ifx) {
4929                 genIfxJump (ifx,"a");
4930                 goto release ;
4931                 }
4932           */
4933           /* if the result is used in an arithmetic operation
4934           then put the result in place */
4935           /*
4936           if (AOP_TYPE(result) != AOP_CRY) 
4937           pic14_outAcc(result);
4938           */
4939           /* leave the result in acc */
4940   }
4941   
4942 release:
4943   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4944   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4945   freeAsmop(result,NULL,ic,TRUE);
4946 }
4947
4948 /*-----------------------------------------------------------------*/
4949 /* ifxForOp - returns the icode containing the ifx for operand     */
4950 /*-----------------------------------------------------------------*/
4951 static iCode *ifxForOp ( operand *op, iCode *ic )
4952 {
4953         /* if true symbol then needs to be assigned */
4954         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4955         if (IS_TRUE_SYMOP(op))
4956                 return NULL ;
4957         
4958                 /* if this has register type condition and
4959                 the next instruction is ifx with the same operand
4960         and live to of the operand is upto the ifx only then */
4961         if (ic->next &&
4962                 ic->next->op == IFX &&
4963                 IC_COND(ic->next)->key == op->key &&
4964                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4965                 return ic->next;
4966         
4967         if (ic->next &&
4968                 ic->next->op == IFX &&
4969                 IC_COND(ic->next)->key == op->key) {
4970                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4971                 return ic->next;
4972         }
4973         
4974         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4975         if (ic->next &&
4976                 ic->next->op == IFX)
4977                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4978         
4979         if (ic->next &&
4980                 ic->next->op == IFX &&
4981                 IC_COND(ic->next)->key == op->key) {
4982                 DEBUGpic14_emitcode ("; "," key is okay");
4983                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4984                         OP_SYMBOL(op)->liveTo,
4985                         ic->next->seq);
4986         }
4987         
4988         
4989         return NULL;
4990 }
4991 /*-----------------------------------------------------------------*/
4992 /* genAndOp - for && operation                                     */
4993 /*-----------------------------------------------------------------*/
4994 static void genAndOp (iCode *ic)
4995 {
4996         operand *left,*right, *result;
4997         /*     symbol *tlbl; */
4998         
4999         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5000         /* note here that && operations that are in an
5001         if statement are taken away by backPatchLabels
5002         only those used in arthmetic operations remain */
5003         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5004         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5005         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5006         
5007         DEBUGpic14_AopType(__LINE__,left,right,result);
5008         
5009         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5010         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5011         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5012         
5013         /* if both are bit variables */
5014         /*     if (AOP_TYPE(left) == AOP_CRY && */
5015         /*         AOP_TYPE(right) == AOP_CRY ) { */
5016         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5017         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5018         /*         pic14_outBitC(result); */
5019         /*     } else { */
5020         /*         tlbl = newiTempLabel(NULL); */
5021         /*         pic14_toBoolean(left);     */
5022         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5023         /*         pic14_toBoolean(right); */
5024         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5025         /*         pic14_outBitAcc(result); */
5026         /*     } */
5027         
5028         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5029         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5030         freeAsmop(result,NULL,ic,TRUE);
5031 }
5032
5033
5034 /*-----------------------------------------------------------------*/
5035 /* genOrOp - for || operation                                      */
5036 /*-----------------------------------------------------------------*/
5037 /*
5038 tsd pic port -
5039 modified this code, but it doesn't appear to ever get called
5040 */
5041
5042 static void genOrOp (iCode *ic)
5043 {
5044         operand *left,*right, *result;
5045         symbol *tlbl;
5046         
5047         /* note here that || operations that are in an
5048         if statement are taken away by backPatchLabels
5049         only those used in arthmetic operations remain */
5050         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5051         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5052         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5053         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5054         
5055         DEBUGpic14_AopType(__LINE__,left,right,result);
5056         
5057         /* if both are bit variables */
5058         if (AOP_TYPE(left) == AOP_CRY &&
5059                 AOP_TYPE(right) == AOP_CRY ) {
5060                 pic14_emitcode("clrc","");
5061                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5062                         AOP(left)->aopu.aop_dir,
5063                         AOP(left)->aopu.aop_dir);
5064                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5065                         AOP(right)->aopu.aop_dir,
5066                         AOP(right)->aopu.aop_dir);
5067                 pic14_emitcode("setc","");
5068                 
5069         } else {
5070                 tlbl = newiTempLabel(NULL);
5071                 pic14_toBoolean(left);
5072                 emitSKPZ;
5073                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5074                 pic14_toBoolean(right);
5075                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5076                 
5077                 pic14_outBitAcc(result);
5078         }
5079         
5080         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5081         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5082         freeAsmop(result,NULL,ic,TRUE);            
5083 }
5084
5085 /*-----------------------------------------------------------------*/
5086 /* isLiteralBit - test if lit == 2^n                               */
5087 /*-----------------------------------------------------------------*/
5088 static int isLiteralBit(unsigned long lit)
5089 {
5090         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5091                 0x100L,0x200L,0x400L,0x800L,
5092                 0x1000L,0x2000L,0x4000L,0x8000L,
5093                 0x10000L,0x20000L,0x40000L,0x80000L,
5094                 0x100000L,0x200000L,0x400000L,0x800000L,
5095                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5096                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5097         int idx;
5098         
5099         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5100         for(idx = 0; idx < 32; idx++)
5101                 if(lit == pw[idx])
5102                         return idx+1;
5103                 return 0;
5104 }
5105
5106 /*-----------------------------------------------------------------*/
5107 /* continueIfTrue -                                                */
5108 /*-----------------------------------------------------------------*/
5109 static void continueIfTrue (iCode *ic)
5110 {
5111         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5112         if(IC_TRUE(ic))
5113                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5114         ic->generated = 1;
5115 }
5116
5117 /*-----------------------------------------------------------------*/
5118 /* jmpIfTrue -                                                     */
5119 /*-----------------------------------------------------------------*/
5120 static void jumpIfTrue (iCode *ic)
5121 {
5122         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5123         if(!IC_TRUE(ic))
5124                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5125         ic->generated = 1;
5126 }
5127
5128 /*-----------------------------------------------------------------*/
5129 /* jmpTrueOrFalse -                                                */
5130 /*-----------------------------------------------------------------*/
5131 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5132 {
5133         // ugly but optimized by peephole
5134         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5135         if(IC_TRUE(ic)){
5136                 symbol *nlbl = newiTempLabel(NULL);
5137                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5138                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5139                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5140                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5141         }
5142         else{
5143                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5144                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5145         }
5146         ic->generated = 1;
5147 }
5148
5149 /*-----------------------------------------------------------------*/
5150 /* genAnd  - code for and                                          */
5151 /*-----------------------------------------------------------------*/
5152 static void genAnd (iCode *ic, iCode *ifx)
5153 {
5154         operand *left, *right, *result;
5155         int size, offset=0;  
5156         unsigned long lit = 0L;
5157         int bytelit = 0;
5158         resolvedIfx rIfx;
5159         
5160         
5161         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5162         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5163         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5164         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5165         
5166         resolveIfx(&rIfx,ifx);
5167         
5168         /* if left is a literal & right is not then exchange them */
5169         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5170                 AOP_NEEDSACC(left)) {
5171                 operand *tmp = right ;
5172                 right = left;
5173                 left = tmp;
5174         }
5175         
5176         /* if result = right then exchange them */
5177         if(pic14_sameRegs(AOP(result),AOP(right))){
5178                 operand *tmp = right ;
5179                 right = left;
5180                 left = tmp;
5181         }
5182         
5183         /* if right is bit then exchange them */
5184         if (AOP_TYPE(right) == AOP_CRY &&
5185                 AOP_TYPE(left) != AOP_CRY){
5186                 operand *tmp = right ;
5187                 right = left;
5188                 left = tmp;
5189         }
5190         if(AOP_TYPE(right) == AOP_LIT)
5191                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5192         
5193         size = AOP_SIZE(result);
5194         
5195         DEBUGpic14_AopType(__LINE__,left,right,result);
5196         
5197         // if(bit & yy)
5198         // result = bit & yy;
5199         if (AOP_TYPE(left) == AOP_CRY){
5200                 // c = bit & literal;
5201                 if(AOP_TYPE(right) == AOP_LIT){
5202                         if(lit & 1) {
5203                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5204                                         // no change
5205                                         goto release;
5206                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5207                         } else {
5208                                 // bit(result) = 0;
5209                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5210                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5211                                         goto release;
5212                                 }
5213                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5214                                         jumpIfTrue(ifx);
5215                                         goto release;
5216                                 }
5217                                 pic14_emitcode("clr","c");
5218                         }
5219                 } else {
5220                         if (AOP_TYPE(right) == AOP_CRY){
5221                                 // c = bit & bit;
5222                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5223                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5224                         } else {
5225                                 // c = bit & val;
5226                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5227                                 // c = lsb
5228                                 pic14_emitcode("rrc","a");
5229                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5230                         }
5231                 }
5232                 // bit = c
5233                 // val = c
5234                 if(size)
5235                         pic14_outBitC(result);
5236                 // if(bit & ...)
5237                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5238                         genIfxJump(ifx, "c");           
5239                 goto release ;
5240         }
5241         
5242         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5243         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5244         if((AOP_TYPE(right) == AOP_LIT) &&
5245                 (AOP_TYPE(result) == AOP_CRY) &&
5246                 (AOP_TYPE(left) != AOP_CRY)){
5247                 int posbit = isLiteralBit(lit);
5248                 /* left &  2^n */
5249                 if(posbit){
5250                         posbit--;
5251                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5252                         // bit = left & 2^n
5253                         if(size)
5254                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5255                         // if(left &  2^n)
5256                         else{
5257                                 if(ifx){
5258                                         int offset = 0;
5259                                         while (posbit > 7) {
5260                                                 posbit -= 8;
5261                                                 offset++;
5262                                         }
5263                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5264                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5265                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5266                                         
5267                                         ifx->generated = 1;
5268                                 }
5269                                 goto release;
5270                         }
5271                 } else {
5272                         symbol *tlbl = newiTempLabel(NULL);
5273                         int sizel = AOP_SIZE(left);
5274                         if(size)
5275                                 pic14_emitcode("setb","c");
5276                         while(sizel--){
5277                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5278                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5279                                         // byte ==  2^n ?
5280                                         if((posbit = isLiteralBit(bytelit)) != 0)
5281                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5282                                         else{
5283                                                 if(bytelit != 0x0FFL)
5284                                                         pic14_emitcode("anl","a,%s",
5285                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5286                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5287                                         }
5288                                 }
5289                                 offset++;
5290                         }
5291                         // bit = left & literal
5292                         if(size){
5293                                 pic14_emitcode("clr","c");
5294                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5295                         }
5296                         // if(left & literal)
5297                         else{
5298                                 if(ifx)
5299                                         jmpTrueOrFalse(ifx, tlbl);
5300                                 goto release ;
5301                         }
5302                 }
5303                 pic14_outBitC(result);
5304                 goto release ;
5305         }
5306         
5307         /* if left is same as result */
5308         if(pic14_sameRegs(AOP(result),AOP(left))){
5309                 int know_W = -1;
5310                 for(;size--; offset++,lit>>=8) {
5311                         if(AOP_TYPE(right) == AOP_LIT){
5312                                 switch(lit & 0xff) {
5313                                 case 0x00:
5314                                         /*  and'ing with 0 has clears the result */
5315                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5316                                         break;
5317                                 case 0xff:
5318                                         /* and'ing with 0xff is a nop when the result and left are the same */
5319                                         break;
5320                                         
5321                                 default:
5322                                         {
5323                                                 int p = my_powof2( (~lit) & 0xff );
5324                                                 if(p>=0) {
5325                                                         /* only one bit is set in the literal, so use a bcf instruction */
5326                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5327                                                         
5328                                                 } else {
5329                                                         if(know_W != (int)(lit&0xff))
5330                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5331                                                         know_W = lit &0xff;
5332                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5333                                                 }
5334                                         }    
5335                                 }
5336                         } else {
5337                                 if (AOP_TYPE(left) == AOP_ACC) {
5338                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5339                                 } else {        
5340                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5341                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5342                                         
5343                                 }
5344                         }
5345                 }
5346                 
5347         } else {
5348                 // left & result in different registers
5349                 if(AOP_TYPE(result) == AOP_CRY){
5350                         // result = bit
5351                         // if(size), result in bit
5352                         // if(!size && ifx), conditional oper: if(left & right)
5353                         symbol *tlbl = newiTempLabel(NULL);
5354                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5355                         if(size)
5356                                 pic14_emitcode("setb","c");
5357                         while(sizer--){
5358                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5359                                 pic14_emitcode("anl","a,%s",
5360                                         aopGet(AOP(left),offset,FALSE,FALSE));
5361                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5362                                 offset++;
5363                         }
5364                         if(size){
5365                                 CLRC;
5366                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5367                                 pic14_outBitC(result);
5368                         } else if(ifx)
5369                                 jmpTrueOrFalse(ifx, tlbl);
5370                 } else {
5371                         for(;(size--);offset++) {
5372                                 // normal case
5373                                 // result = left & right
5374                                 if(AOP_TYPE(right) == AOP_LIT){
5375                                         int t = (lit >> (offset*8)) & 0x0FFL;
5376                                         switch(t) { 
5377                                         case 0x00:
5378                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5379                                                 break;
5380                                         case 0xff:
5381                                                 if(AOP_TYPE(left) != AOP_ACC) {
5382                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5383                                                 }
5384                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5385                                                 break;
5386                                         default:
5387                                                 if(AOP_TYPE(left) == AOP_ACC) {
5388                                                         emitpcode(POC_ANDLW, popGetLit(t));
5389                                                 } else {
5390                                                         emitpcode(POC_MOVLW, popGetLit(t));
5391                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5392                                                 }
5393                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5394                                         }
5395                                         continue;
5396                                 }
5397                                 
5398                                 if (AOP_TYPE(left) == AOP_ACC) {
5399                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5400                                 } else {
5401                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5402                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5403                                 }
5404                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5405                         }
5406                 }
5407         }
5408         
5409 release :
5410         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5411         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5412         freeAsmop(result,NULL,ic,TRUE);     
5413 }
5414
5415 /*-----------------------------------------------------------------*/
5416 /* genOr  - code for or                                            */
5417 /*-----------------------------------------------------------------*/
5418 static void genOr (iCode *ic, iCode *ifx)
5419 {
5420         operand *left, *right, *result;
5421         int size, offset=0;
5422         unsigned long lit = 0L;
5423         
5424         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5425         
5426         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5427         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5428         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5429         
5430         DEBUGpic14_AopType(__LINE__,left,right,result);
5431         
5432         /* if left is a literal & right is not then exchange them */
5433         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5434                 AOP_NEEDSACC(left)) {
5435                 operand *tmp = right ;
5436                 right = left;
5437                 left = tmp;
5438         }
5439         
5440         /* if result = right then exchange them */
5441         if(pic14_sameRegs(AOP(result),AOP(right))){
5442                 operand *tmp = right ;
5443                 right = left;
5444                 left = tmp;
5445         }
5446         
5447         /* if right is bit then exchange them */
5448         if (AOP_TYPE(right) == AOP_CRY &&
5449                 AOP_TYPE(left) != AOP_CRY){
5450                 operand *tmp = right ;
5451                 right = left;
5452                 left = tmp;
5453         }
5454         
5455         DEBUGpic14_AopType(__LINE__,left,right,result);
5456         
5457         if(AOP_TYPE(right) == AOP_LIT)
5458                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5459         
5460         size = AOP_SIZE(result);
5461         
5462         // if(bit | yy)
5463         // xx = bit | yy;
5464         if (AOP_TYPE(left) == AOP_CRY){
5465                 if(AOP_TYPE(right) == AOP_LIT){
5466                         // c = bit & literal;
5467                         if(lit){
5468                                 // lit != 0 => result = 1
5469                                 if(AOP_TYPE(result) == AOP_CRY){
5470                                         if(size)
5471                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5472                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5473                                         //   AOP(result)->aopu.aop_dir,
5474                                         //   AOP(result)->aopu.aop_dir);
5475                                         else if(ifx)
5476                                                 continueIfTrue(ifx);
5477                                         goto release;
5478                                 }
5479                         } else {
5480                                 // lit == 0 => result = left
5481                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5482                                         goto release;
5483                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5484                         }
5485                 } else {
5486                         if (AOP_TYPE(right) == AOP_CRY){
5487                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5488                                         // c = bit | bit;
5489                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5490                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5491                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5492                                         
5493                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5494                                                 AOP(result)->aopu.aop_dir,
5495                                                 AOP(result)->aopu.aop_dir);
5496                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5497                                                 AOP(right)->aopu.aop_dir,
5498                                                 AOP(right)->aopu.aop_dir);
5499                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5500                                                 AOP(result)->aopu.aop_dir,
5501                                                 AOP(result)->aopu.aop_dir);
5502                                 } else {
5503                                         if( AOP_TYPE(result) == AOP_ACC) {
5504                                                 emitpcode(POC_MOVLW, popGetLit(0));
5505                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5506                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5507                                                 emitpcode(POC_MOVLW, popGetLit(1));
5508                                                 
5509                                         } else {
5510                                                 
5511                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5512                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5513                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5514                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5515                                                 
5516                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5517                                                         AOP(result)->aopu.aop_dir,
5518                                                         AOP(result)->aopu.aop_dir);
5519                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5520                                                         AOP(right)->aopu.aop_dir,
5521                                                         AOP(right)->aopu.aop_dir);
5522                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5523                                                         AOP(left)->aopu.aop_dir,
5524                                                         AOP(left)->aopu.aop_dir);
5525                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5526                                                         AOP(result)->aopu.aop_dir,
5527                                                         AOP(result)->aopu.aop_dir);
5528                                         }
5529                                 }
5530                         } else {
5531                                 // c = bit | val;
5532                                 symbol *tlbl = newiTempLabel(NULL);
5533                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5534                                 
5535                                 
5536                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5537                                 if( AOP_TYPE(right) == AOP_ACC) {
5538                                         emitpcode(POC_IORLW, popGetLit(0));
5539                                         emitSKPNZ;
5540                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5541                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5542                                 }
5543                                 
5544                                 
5545                                 
5546                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5547                                         pic14_emitcode(";XXX setb","c");
5548                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5549                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5550                                 pic14_toBoolean(right);
5551                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5552                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5553                                         jmpTrueOrFalse(ifx, tlbl);
5554                                         goto release;
5555                                 } else {
5556                                         CLRC;
5557                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5558                                 }
5559                         }
5560                 }
5561                 // bit = c
5562                 // val = c
5563                 if(size)
5564                         pic14_outBitC(result);
5565                 // if(bit | ...)
5566                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5567                         genIfxJump(ifx, "c");           
5568                 goto release ;
5569   }
5570   
5571   // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5572   // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5573   if((AOP_TYPE(right) == AOP_LIT) &&
5574           (AOP_TYPE(result) == AOP_CRY) &&
5575           (AOP_TYPE(left) != AOP_CRY)){
5576           if(lit){
5577                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5578                   // result = 1
5579                   if(size)
5580                           pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5581                   else 
5582                           continueIfTrue(ifx);
5583                   goto release;
5584           } else {
5585                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5586                   // lit = 0, result = boolean(left)
5587                   if(size)
5588                           pic14_emitcode(";XXX setb","c");
5589                   pic14_toBoolean(right);
5590                   if(size){
5591                           symbol *tlbl = newiTempLabel(NULL);
5592                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5593                           CLRC;
5594                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5595                   } else {
5596                           genIfxJump (ifx,"a");
5597                           goto release;
5598                   }
5599           }
5600           pic14_outBitC(result);
5601           goto release ;
5602   }
5603   
5604   /* if left is same as result */
5605   if(pic14_sameRegs(AOP(result),AOP(left))){
5606           int know_W = -1;
5607           for(;size--; offset++,lit>>=8) {
5608                   if(AOP_TYPE(right) == AOP_LIT){
5609                           if((lit & 0xff) == 0)
5610                                   /*  or'ing with 0 has no effect */
5611                                   continue;
5612                           else {
5613                                   int p = my_powof2(lit & 0xff);
5614                                   if(p>=0) {
5615                                           /* only one bit is set in the literal, so use a bsf instruction */
5616                                           emitpcode(POC_BSF,
5617                                                   newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5618                                   } else {
5619                                           if(know_W != (int)(lit & 0xff))
5620                                                   emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5621                                           know_W = lit & 0xff;
5622                                           emitpcode(POC_IORWF, popGet(AOP(left),offset));
5623                                   }
5624                                   
5625                           }
5626                   } else {
5627                           if (AOP_TYPE(left) == AOP_ACC) {
5628                                   emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5629                                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5630                           } else {        
5631                                   emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5632                                   emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5633                                   
5634                                   pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5635                                   pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5636                                   
5637                           }
5638                   }
5639           }
5640   } else {
5641           // left & result in different registers
5642           if(AOP_TYPE(result) == AOP_CRY){
5643                   // result = bit
5644                   // if(size), result in bit
5645                   // if(!size && ifx), conditional oper: if(left | right)
5646                   symbol *tlbl = newiTempLabel(NULL);
5647                   int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5648                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5649                   
5650                   
5651                   if(size)
5652                           pic14_emitcode(";XXX setb","c");
5653                   while(sizer--){
5654                           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5655                           pic14_emitcode(";XXX orl","a,%s",
5656                                   aopGet(AOP(left),offset,FALSE,FALSE));
5657                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5658                           offset++;
5659                   }
5660                   if(size){
5661                           CLRC;
5662                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5663                           pic14_outBitC(result);
5664                   } else if(ifx)
5665                           jmpTrueOrFalse(ifx, tlbl);
5666           } else for(;(size--);offset++){
5667                   // normal case
5668                   // result = left & right
5669                   if(AOP_TYPE(right) == AOP_LIT){
5670                           int t = (lit >> (offset*8)) & 0x0FFL;
5671                           switch(t) { 
5672                           case 0x00:
5673                                   if (AOP_TYPE(left) != AOP_ACC) {
5674                                           emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5675                                   }
5676                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5677                                   
5678                                   break;
5679                           default:
5680                                   if (AOP_TYPE(left) == AOP_ACC) {
5681                                           emitpcode(POC_IORLW,  popGetLit(t));
5682                                   } else {
5683                                           emitpcode(POC_MOVLW,  popGetLit(t));
5684                                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5685                                   }
5686                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5687                           }
5688                           continue;
5689                   }
5690                   
5691                   // faster than result <- left, anl result,right
5692                   // and better if result is SFR
5693                   if (AOP_TYPE(left) == AOP_ACC) {
5694                           emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5695                           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5696                   } else {
5697                           emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5698                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5699                           
5700                           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5701                           pic14_emitcode("iorwf","%s,w",
5702                                   aopGet(AOP(left),offset,FALSE,FALSE));
5703                   }
5704                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5705                   pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5706           }
5707   }
5708   
5709 release :
5710   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5711   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5712   freeAsmop(result,NULL,ic,TRUE);     
5713 }
5714
5715 /*-----------------------------------------------------------------*/
5716 /* genXor - code for xclusive or                                   */
5717 /*-----------------------------------------------------------------*/
5718 static void genXor (iCode *ic, iCode *ifx)
5719 {
5720         operand *left, *right, *result;
5721         int size, offset=0;
5722         unsigned long lit = 0L;
5723         
5724         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5725         
5726         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5727         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5728         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5729         
5730         /* if left is a literal & right is not ||
5731         if left needs acc & right does not */
5732         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5733                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5734                 operand *tmp = right ;
5735                 right = left;
5736                 left = tmp;
5737         }
5738         
5739         /* if result = right then exchange them */
5740         if(pic14_sameRegs(AOP(result),AOP(right))){
5741                 operand *tmp = right ;
5742                 right = left;
5743                 left = tmp;
5744         }
5745         
5746         /* if right is bit then exchange them */
5747         if (AOP_TYPE(right) == AOP_CRY &&
5748                 AOP_TYPE(left) != AOP_CRY){
5749                 operand *tmp = right ;
5750                 right = left;
5751                 left = tmp;
5752         }
5753         if(AOP_TYPE(right) == AOP_LIT)
5754                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5755         
5756         size = AOP_SIZE(result);
5757         
5758         // if(bit ^ yy)
5759         // xx = bit ^ yy;
5760         if (AOP_TYPE(left) == AOP_CRY){
5761                 if(AOP_TYPE(right) == AOP_LIT){
5762                         // c = bit & literal;
5763                         if(lit>>1){
5764                                 // lit>>1  != 0 => result = 1
5765                                 if(AOP_TYPE(result) == AOP_CRY){
5766                                         if(size)
5767                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5768                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5769                                         else if(ifx)
5770                                                 continueIfTrue(ifx);
5771                                         goto release;
5772                                 }
5773                                 pic14_emitcode("setb","c");
5774                         } else{
5775                                 // lit == (0 or 1)
5776                                 if(lit == 0){
5777                                         // lit == 0, result = left
5778                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5779                                                 goto release;
5780                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5781                                 } else{
5782                                         // lit == 1, result = not(left)
5783                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5784                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5785                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5786                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5787                                                 goto release;
5788                                         } else {
5789                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5790                                                 pic14_emitcode("cpl","c");
5791                                         }
5792                                 }
5793                         }
5794                         
5795                 } else {
5796                         // right != literal
5797                         symbol *tlbl = newiTempLabel(NULL);
5798                         if (AOP_TYPE(right) == AOP_CRY){
5799                                 // c = bit ^ bit;
5800                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5801                         }
5802                         else{
5803                                 int sizer = AOP_SIZE(right);
5804                                 // c = bit ^ val
5805                                 // if val>>1 != 0, result = 1
5806                                 pic14_emitcode("setb","c");
5807                                 while(sizer){
5808                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5809                                         if(sizer == 1)
5810                                                 // test the msb of the lsb
5811                                                 pic14_emitcode("anl","a,#0xfe");
5812                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5813                                         sizer--;
5814                                 }
5815                                 // val = (0,1)
5816                                 pic14_emitcode("rrc","a");
5817                         }
5818                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5819                         pic14_emitcode("cpl","c");
5820                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5821                 }
5822                 // bit = c
5823                 // val = c
5824                 if(size)
5825                         pic14_outBitC(result);
5826                 // if(bit | ...)
5827                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5828                         genIfxJump(ifx, "c");           
5829                 goto release ;
5830         }
5831         
5832         if(pic14_sameRegs(AOP(result),AOP(left))){
5833                 /* if left is same as result */
5834                 for(;size--; offset++) {
5835                         if(AOP_TYPE(right) == AOP_LIT){
5836                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5837                                 if(t == 0x00L)
5838                                         continue;
5839                                 else
5840                                         if (IS_AOP_PREG(left)) {
5841                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5842                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5843                                                 aopPut(AOP(result),"a",offset);
5844                                         } else {
5845                                                 emitpcode(POC_MOVLW, popGetLit(t));
5846                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5847                                                 pic14_emitcode("xrl","%s,%s",
5848                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5849                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5850                                         }
5851                         } else {
5852                                 if (AOP_TYPE(left) == AOP_ACC)
5853                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5854                                 else {
5855                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5856                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5857                                         /*
5858                                         if (IS_AOP_PREG(left)) {
5859                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5860                                         aopPut(AOP(result),"a",offset);
5861                                         } else
5862                                         pic14_emitcode("xrl","%s,a",
5863                                         aopGet(AOP(left),offset,FALSE,TRUE));
5864                                         */
5865                                 }
5866                         }
5867                 }
5868         } else {
5869                 // left & result in different registers
5870                 if(AOP_TYPE(result) == AOP_CRY){
5871                         // result = bit
5872                         // if(size), result in bit
5873                         // if(!size && ifx), conditional oper: if(left ^ right)
5874                         symbol *tlbl = newiTempLabel(NULL);
5875                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5876                         if(size)
5877                                 pic14_emitcode("setb","c");
5878                         while(sizer--){
5879                                 if((AOP_TYPE(right) == AOP_LIT) &&
5880                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5881                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5882                                 } else {
5883                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5884                                         pic14_emitcode("xrl","a,%s",
5885                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5886                                 }
5887                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5888                                 offset++;
5889                         }
5890                         if(size){
5891                                 CLRC;
5892                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5893                                 pic14_outBitC(result);
5894                         } else if(ifx)
5895                                 jmpTrueOrFalse(ifx, tlbl);
5896                 } else for(;(size--);offset++){
5897                         // normal case
5898                         // result = left & right
5899                         if(AOP_TYPE(right) == AOP_LIT){
5900                                 int t = (lit >> (offset*8)) & 0x0FFL;
5901                                 switch(t) { 
5902                                 case 0x00:
5903                                         if (AOP_TYPE(left) != AOP_ACC) {
5904                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5905                                         }
5906                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5907                                         pic14_emitcode("movf","%s,w",
5908                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5909                                         pic14_emitcode("movwf","%s",
5910                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5911                                         break;
5912                                 case 0xff:
5913                                         if (AOP_TYPE(left) == AOP_ACC) {
5914                                                 emitpcode(POC_XORLW, popGetLit(t));
5915                                         } else {
5916                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5917                                         }
5918                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5919                                         break;
5920                                 default:
5921                                         if (AOP_TYPE(left) == AOP_ACC) {
5922                                                 emitpcode(POC_XORLW, popGetLit(t));
5923                                         } else {
5924                                                 emitpcode(POC_MOVLW, popGetLit(t));
5925                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5926                                         }
5927                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5928                                         pic14_emitcode("movlw","0x%x",t);
5929                                         pic14_emitcode("xorwf","%s,w",
5930                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5931                                         pic14_emitcode("movwf","%s",
5932                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5933                                         
5934                                 }
5935                                 continue;
5936                         }
5937                         
5938                         // faster than result <- left, anl result,right
5939                         // and better if result is SFR
5940                         if (AOP_TYPE(left) == AOP_ACC) {
5941                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5942                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5943                         } else {
5944                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5945                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5946                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5947                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5948                         }
5949                         if ( AOP_TYPE(result) != AOP_ACC){
5950                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5951                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5952                         }
5953                 }
5954         }
5955         
5956 release :
5957         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5958         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5959         freeAsmop(result,NULL,ic,TRUE);     
5960 }
5961
5962 /*-----------------------------------------------------------------*/
5963 /* genInline - write the inline code out                           */
5964 /*-----------------------------------------------------------------*/
5965 static void genInline (iCode *ic)
5966 {
5967         char *buffer, *bp, *bp1;
5968         
5969         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5970         
5971         _G.inLine += (!options.asmpeep);
5972         
5973         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5974         strcpy(buffer,IC_INLINE(ic));
5975         
5976         /* emit each line as a code */
5977         while (*bp) {
5978                 if (*bp == '\n') {
5979                         *bp++ = '\0';
5980                         
5981                         if(*bp1)
5982                                 addpCode2pBlock(pb,AssembleLine(bp1));
5983                         bp1 = bp;
5984                 } else {
5985                         if (*bp == ':') {
5986                                 bp++;
5987                                 *bp = '\0';
5988                                 bp++;
5989                                 pic14_emitcode(bp1,"");
5990                                 bp1 = bp;
5991                         } else
5992                                 bp++;
5993                 }
5994         }
5995         if ((bp1 != bp) && *bp1)
5996                 addpCode2pBlock(pb,AssembleLine(bp1));
5997         
5998         Safe_free(buffer);
5999         
6000         _G.inLine -= (!options.asmpeep);
6001 }
6002
6003 /*-----------------------------------------------------------------*/
6004 /* genRRC - rotate right with carry                                */
6005 /*-----------------------------------------------------------------*/
6006 static void genRRC (iCode *ic)
6007 {
6008         operand *left , *result ;
6009         int size, offset = 0, same;
6010         
6011         /* rotate right with carry */
6012         left = IC_LEFT(ic);
6013         result=IC_RESULT(ic);
6014         aopOp (left,ic,FALSE);
6015         aopOp (result,ic,FALSE);
6016         
6017         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6018         
6019         same = pic14_sameRegs(AOP(result),AOP(left));
6020         
6021         size = AOP_SIZE(result);    
6022         
6023         /* get the lsb and put it into the carry */
6024         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6025         
6026         offset = 0 ;
6027         
6028         while(size--) {
6029                 
6030                 if(same) {
6031                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6032                 } else {
6033                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6034                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6035                 }
6036                 
6037                 offset++;
6038         }
6039         
6040         freeAsmop(left,NULL,ic,TRUE);
6041         freeAsmop(result,NULL,ic,TRUE);
6042 }
6043
6044 /*-----------------------------------------------------------------*/
6045 /* genRLC - generate code for rotate left with carry               */
6046 /*-----------------------------------------------------------------*/
6047 static void genRLC (iCode *ic)
6048 {    
6049         operand *left , *result ;
6050         int size, offset = 0;
6051         int same;
6052         
6053         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6054         /* rotate right with carry */
6055         left = IC_LEFT(ic);
6056         result=IC_RESULT(ic);
6057         aopOp (left,ic,FALSE);
6058         aopOp (result,ic,FALSE);
6059         
6060         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6061         
6062         same = pic14_sameRegs(AOP(result),AOP(left));
6063         
6064         /* move it to the result */
6065         size = AOP_SIZE(result);    
6066         
6067         /* get the msb and put it into the carry */
6068         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6069         
6070         offset = 0 ;
6071         
6072         while(size--) {
6073                 
6074                 if(same) {
6075                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6076                 } else {
6077                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6078                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6079                 }
6080                 
6081                 offset++;
6082         }
6083         
6084         
6085         freeAsmop(left,NULL,ic,TRUE);
6086         freeAsmop(result,NULL,ic,TRUE);
6087 }
6088
6089 /*-----------------------------------------------------------------*/
6090 /* genGetHbit - generates code get highest order bit               */
6091 /*-----------------------------------------------------------------*/
6092 static void genGetHbit (iCode *ic)
6093 {
6094         operand *left, *result;
6095         left = IC_LEFT(ic);
6096         result=IC_RESULT(ic);
6097         aopOp (left,ic,FALSE);
6098         aopOp (result,ic,FALSE);
6099         
6100         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6101         /* get the highest order byte into a */
6102         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6103         if(AOP_TYPE(result) == AOP_CRY){
6104                 pic14_emitcode("rlc","a");
6105                 pic14_outBitC(result);
6106         }
6107         else{
6108                 pic14_emitcode("rl","a");
6109                 pic14_emitcode("anl","a,#0x01");
6110                 pic14_outAcc(result);
6111         }
6112         
6113         
6114         freeAsmop(left,NULL,ic,TRUE);
6115         freeAsmop(result,NULL,ic,TRUE);
6116 }
6117
6118 /*-----------------------------------------------------------------*/
6119 /* AccRol - rotate left accumulator by known count                 */
6120 /*-----------------------------------------------------------------*/
6121 static void AccRol (int shCount)
6122 {
6123         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6124         shCount &= 0x0007;              // shCount : 0..7
6125         switch(shCount){
6126         case 0 :
6127                 break;
6128         case 1 :
6129                 pic14_emitcode("rl","a");
6130                 break;
6131         case 2 :
6132                 pic14_emitcode("rl","a");
6133                 pic14_emitcode("rl","a");
6134                 break;
6135         case 3 :
6136                 pic14_emitcode("swap","a");
6137                 pic14_emitcode("rr","a");
6138                 break;
6139         case 4 :
6140                 pic14_emitcode("swap","a");
6141                 break;
6142         case 5 :
6143                 pic14_emitcode("swap","a");
6144                 pic14_emitcode("rl","a");
6145                 break;
6146         case 6 :
6147                 pic14_emitcode("rr","a");
6148                 pic14_emitcode("rr","a");
6149                 break;
6150         case 7 :
6151                 pic14_emitcode("rr","a");
6152                 break;
6153         }
6154 }
6155
6156 /*-----------------------------------------------------------------*/
6157 /* AccLsh - left shift accumulator by known count                  */
6158 /*-----------------------------------------------------------------*/
6159 static void AccLsh (int shCount)
6160 {
6161         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6162         if(shCount != 0){
6163                 if(shCount == 1)
6164                         pic14_emitcode("add","a,acc");
6165                 else 
6166                         if(shCount == 2) {
6167                                 pic14_emitcode("add","a,acc");
6168                                 pic14_emitcode("add","a,acc");
6169                         } else {
6170                                 /* rotate left accumulator */
6171                                 AccRol(shCount);
6172                                 /* and kill the lower order bits */
6173                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6174                         }
6175         }
6176 }
6177
6178 /*-----------------------------------------------------------------*/
6179 /* AccRsh - right shift accumulator by known count                 */
6180 /*-----------------------------------------------------------------*/
6181 static void AccRsh (int shCount)
6182 {
6183         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6184         if(shCount != 0){
6185                 if(shCount == 1){
6186                         CLRC;
6187                         pic14_emitcode("rrc","a");
6188                 } else {
6189                         /* rotate right accumulator */
6190                         AccRol(8 - shCount);
6191                         /* and kill the higher order bits */
6192                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6193                 }
6194         }
6195 }
6196
6197 #if 0
6198 /*-----------------------------------------------------------------*/
6199 /* AccSRsh - signed right shift accumulator by known count                 */
6200 /*-----------------------------------------------------------------*/
6201 static void AccSRsh (int shCount)
6202 {
6203         symbol *tlbl ;
6204         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6205         if(shCount != 0){
6206                 if(shCount == 1){
6207                         pic14_emitcode("mov","c,acc.7");
6208                         pic14_emitcode("rrc","a");
6209                 } else if(shCount == 2){
6210                         pic14_emitcode("mov","c,acc.7");
6211                         pic14_emitcode("rrc","a");
6212                         pic14_emitcode("mov","c,acc.7");
6213                         pic14_emitcode("rrc","a");
6214                 } else {
6215                         tlbl = newiTempLabel(NULL);
6216                         /* rotate right accumulator */
6217                         AccRol(8 - shCount);
6218                         /* and kill the higher order bits */
6219                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6220                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6221                         pic14_emitcode("orl","a,#0x%02x",
6222                                 (unsigned char)~SRMask[shCount]);
6223                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6224                 }
6225         }
6226 }
6227 #endif
6228 /*-----------------------------------------------------------------*/
6229 /* shiftR1Left2Result - shift right one byte from left to result   */
6230 /*-----------------------------------------------------------------*/
6231 static void shiftR1Left2ResultSigned (operand *left, int offl,
6232                                                                           operand *result, int offr,
6233                                                                           int shCount)
6234 {
6235         int same;
6236         
6237         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6238         
6239         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6240         
6241         switch(shCount) {
6242         case 1:
6243                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6244                 if(same) 
6245                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6246                 else {
6247                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6248                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6249                 }
6250                 
6251                 break;
6252         case 2:
6253                 
6254                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6255                 if(same) 
6256                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6257                 else {
6258                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6259                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6260                 }
6261                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6262                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6263                 
6264                 break;
6265                 
6266         case 3:
6267                 if(same)
6268                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6269                 else {
6270                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6271                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6272                 }
6273                 
6274                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6275                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6276                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6277                 
6278                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6279                 emitpcode(POC_IORLW, popGetLit(0xe0));
6280                 
6281                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6282                 break;
6283                 
6284         case 4:
6285                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6286                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6287                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6288                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6289                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6290                 break;
6291         case 5:
6292                 if(same) {
6293                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6294                 } else {
6295                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6296                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6297                 }
6298                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6299                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6300                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6301                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6302                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6303                 break;
6304                 
6305         case 6:
6306                 if(same) {
6307                         emitpcode(POC_MOVLW, popGetLit(0x00));
6308                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6309                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6310                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6311                         emitpcode(POC_IORLW, popGetLit(0x01));
6312                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6313                 } else {
6314                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6315                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6316                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6317                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6318                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6319                 }
6320                 break;
6321                 
6322         case 7:
6323                 if(same) {
6324                         emitpcode(POC_MOVLW, popGetLit(0x00));
6325                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6326                         emitpcode(POC_MOVLW, popGetLit(0xff));
6327                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6328                 } else {
6329                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6330                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6331                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6332                 }
6333                 
6334         default:
6335                 break;
6336         }
6337 }
6338
6339 /*-----------------------------------------------------------------*/
6340 /* shiftR1Left2Result - shift right one byte from left to result   */
6341 /*-----------------------------------------------------------------*/
6342 static void shiftR1Left2Result (operand *left, int offl,
6343                                                                 operand *result, int offr,
6344                                                                 int shCount, int sign)
6345 {
6346         int same;
6347         
6348         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6349         
6350         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6351         
6352         /* Copy the msb into the carry if signed. */
6353         if(sign) {
6354                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6355                 return;
6356         }
6357         
6358         
6359         
6360         switch(shCount) {
6361         case 1:
6362                 emitCLRC;
6363                 if(same) 
6364                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6365                 else {
6366                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6367                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6368                 }
6369                 break;
6370         case 2:
6371                 emitCLRC;
6372                 if(same) {
6373                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6374                 } else {
6375                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6376                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6377                 }
6378                 emitCLRC;
6379                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6380                 
6381                 break;
6382         case 3:
6383                 if(same)
6384                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6385                 else {
6386                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6387                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6388                 }
6389                 
6390                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6391                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6392                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6393                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6394                 break;
6395                 
6396         case 4:
6397                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6398                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6399                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6400                 break;
6401                 
6402         case 5:
6403                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6404                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6405                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406                 emitCLRC;
6407                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6408                 
6409                 break;
6410         case 6:
6411                 
6412                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6413                 emitpcode(POC_ANDLW, popGetLit(0x80));
6414                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6416                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6417                 break;
6418                 
6419         case 7:
6420                 
6421                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6422                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6423                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6424                 
6425                 break;
6426                 
6427         default:
6428                 break;
6429         }
6430 }
6431
6432 /*-----------------------------------------------------------------*/
6433 /* shiftL1Left2Result - shift left one byte from left to result    */
6434 /*-----------------------------------------------------------------*/
6435 static void shiftL1Left2Result (operand *left, int offl,
6436                                                                 operand *result, int offr, int shCount)
6437 {
6438         int same;
6439         
6440         //    char *l;
6441         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6442         
6443         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6444         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6445         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6446         //    MOVA(l);
6447         /* shift left accumulator */
6448         //AccLsh(shCount); // don't comment out just yet...
6449         //    aopPut(AOP(result),"a",offr);
6450         
6451         switch(shCount) {
6452         case 1:
6453                 /* Shift left 1 bit position */
6454                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6455                 if(same) {
6456                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6457                 } else {
6458                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6459                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6460                 }
6461                 break;
6462         case 2:
6463                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6464                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6465                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6466                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6467                 break;
6468         case 3:
6469                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6470                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6471                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6472                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6473                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6474                 break;
6475         case 4:
6476                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6477                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6478                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6479                 break;
6480         case 5:
6481                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6482                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6483                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6484                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6485                 break;
6486         case 6:
6487                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6488                 emitpcode(POC_ANDLW, popGetLit(0x30));
6489                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6490                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6491                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6492                 break;
6493         case 7:
6494                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6495                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6496                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6497                 break;
6498                 
6499         default:
6500                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6501         }
6502         
6503 }
6504
6505 /*-----------------------------------------------------------------*/
6506 /* movLeft2Result - move byte from left to result                  */
6507 /*-----------------------------------------------------------------*/
6508 static void movLeft2Result (operand *left, int offl,
6509                                                         operand *result, int offr)
6510 {
6511         char *l;
6512         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6513         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6514                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6515                 
6516                 if (*l == '@' && (IS_AOP_PREG(result))) {
6517                         pic14_emitcode("mov","a,%s",l);
6518                         aopPut(AOP(result),"a",offr);
6519                 } else {
6520                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6521                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6522                 }
6523         }
6524 }
6525
6526 /*-----------------------------------------------------------------*/
6527 /* shiftL2Left2Result - shift left two bytes from left to result   */
6528 /*-----------------------------------------------------------------*/
6529 static void shiftL2Left2Result (operand *left, int offl,
6530                                                                 operand *result, int offr, int shCount)
6531 {
6532         
6533         
6534         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6535         
6536         if(pic14_sameRegs(AOP(result), AOP(left))) {
6537                 switch(shCount) {
6538                 case 0:
6539                         break;
6540                 case 1:
6541                 case 2:
6542                 case 3:
6543                         
6544                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6545                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6546                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6547                         
6548                         while(--shCount) {
6549                                 emitCLRC;
6550                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6551                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6552                         }
6553                         
6554                         break;
6555                 case 4:
6556                 case 5:
6557                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6558                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6559                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6560                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6561                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6562                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6563                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6564                         if(shCount >=5) {
6565                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6566                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6567                         }
6568                         break;
6569                 case 6:
6570                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6571                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6572                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6573                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6574                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6575                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6576                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6577                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6578                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6579                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6580                         break;
6581                 case 7:
6582                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6583                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6584                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6585                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6586                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6587                 }
6588                 
6589         } else {
6590                 switch(shCount) {
6591                 case 0:
6592                         break;
6593                 case 1:
6594                 case 2:
6595                 case 3:
6596                 /* note, use a mov/add for the shift since the mov has a
6597                         chance of getting optimized out */
6598                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6599                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6600                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6601                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6602                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6603                         
6604                         while(--shCount) {
6605                                 emitCLRC;
6606                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6607                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6608                         }
6609                         break;
6610                         
6611                 case 4:
6612                 case 5:
6613                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6614                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6615                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6616                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6617                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6618                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6619                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6620                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6621                         
6622                         
6623                         if(shCount == 5) {
6624                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6625                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6626                         }
6627                         break;
6628                 case 6:
6629                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6630                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6631                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6632                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6633                         
6634                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6635                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6636                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6637                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6638                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6639                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6640                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6641                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6642                         break;
6643                 case 7:
6644                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6645                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6646                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6647                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6648                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6649                 }
6650         }
6651         
6652 }
6653 /*-----------------------------------------------------------------*/
6654 /* shiftR2Left2Result - shift right two bytes from left to result  */
6655 /*-----------------------------------------------------------------*/
6656 static void shiftR2Left2Result (operand *left, int offl,
6657                                                                 operand *result, int offr,
6658                                                                 int shCount, int sign)
6659 {
6660         int same=0;
6661         
6662         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6663         same = pic14_sameRegs(AOP(result), AOP(left));
6664         
6665         if(same && ((offl + MSB16) == offr)){
6666                 same=1;
6667                 /* don't crash result[offr] */
6668                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6669                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6670         }
6671         /* else {
6672         movLeft2Result(left,offl, result, offr);
6673         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6674         }
6675         */
6676         /* a:x >> shCount (x = lsb(result))*/
6677         /*
6678         if(sign)
6679         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6680         else {
6681         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6682         */
6683         switch(shCount) {
6684         case 0:
6685                 break;
6686         case 1:
6687         case 2:
6688         case 3:
6689                 if(sign)
6690                         emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6691                 else
6692                         emitCLRC;
6693                 
6694                 if(same) {
6695                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6696                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6697                 } else {
6698                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6699                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6700                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6701                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6702                 }
6703                 
6704                 while(--shCount) {
6705                         if(sign)
6706                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6707                         else
6708                                 emitCLRC;
6709                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6710                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6711                 }
6712                 break;
6713         case 4:
6714         case 5:
6715                 if(same) {
6716                         
6717                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6718                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6719                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6720                         
6721                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6722                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6723                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6724                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6725                 } else {
6726                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6727                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6728                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6729                         
6730                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6731                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6732                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6733                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6734                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6735                 }
6736                 
6737                 if(shCount >=5) {
6738                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6739                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6740                 }
6741                 
6742                 if(sign) {
6743                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6744                         emitpcode(POC_BTFSC, 
6745                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6746                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6747                 }
6748                 
6749                 break;
6750                 
6751         case 6:
6752                 if(same) {
6753                         
6754                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6755                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6756                         
6757                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6758                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6759                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6760                         emitpcode(POC_ANDLW,popGetLit(0x03));
6761                         if(sign) {
6762                                 emitpcode(POC_BTFSC, 
6763                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6764                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6765                         }
6766                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6767                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6768                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6769                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6770                 } else {
6771                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6772                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6773                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6774                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6775                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6776                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6777                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6778                         emitpcode(POC_ANDLW,popGetLit(0x03));
6779                         if(sign) {
6780                                 emitpcode(POC_BTFSC, 
6781                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6782                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6783                         }
6784                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6785                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6786                         
6787                         
6788                 }
6789                 
6790                 break;
6791         case 7:
6792                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6793                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6794                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6795                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6796                 if(sign) {
6797                         emitSKPNC;
6798                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6799                 } else 
6800                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6801   }
6802 }
6803
6804
6805 /*-----------------------------------------------------------------*/
6806 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6807 /*-----------------------------------------------------------------*/
6808 static void shiftLLeftOrResult (operand *left, int offl,
6809                                                                 operand *result, int offr, int shCount)
6810 {
6811         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6812         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6813         /* shift left accumulator */
6814         AccLsh(shCount);
6815         /* or with result */
6816         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6817         /* back to result */
6818         aopPut(AOP(result),"a",offr);
6819 }
6820
6821 /*-----------------------------------------------------------------*/
6822 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6823 /*-----------------------------------------------------------------*/
6824 static void shiftRLeftOrResult (operand *left, int offl,
6825                                                                 operand *result, int offr, int shCount)
6826 {
6827         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6828         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6829         /* shift right accumulator */
6830         AccRsh(shCount);
6831         /* or with result */
6832         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6833         /* back to result */
6834         aopPut(AOP(result),"a",offr);
6835 }
6836
6837 /*-----------------------------------------------------------------*/
6838 /* genlshOne - left shift a one byte quantity by known count       */
6839 /*-----------------------------------------------------------------*/
6840 static void genlshOne (operand *result, operand *left, int shCount)
6841 {       
6842         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6843         shiftL1Left2Result(left, LSB, result, LSB, shCount);
6844 }
6845
6846 /*-----------------------------------------------------------------*/
6847 /* genlshTwo - left shift two bytes by known amount != 0           */
6848 /*-----------------------------------------------------------------*/
6849 static void genlshTwo (operand *result,operand *left, int shCount)
6850 {
6851         int size;
6852         
6853         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6854         size = pic14_getDataSize(result);
6855         
6856         /* if shCount >= 8 */
6857         if (shCount >= 8) {
6858                 shCount -= 8 ;
6859                 
6860                 if (size > 1){
6861                         if (shCount)
6862                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6863                         else 
6864                                 movLeft2Result(left, LSB, result, MSB16);
6865                 }
6866                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6867         }
6868         
6869         /*  1 <= shCount <= 7 */
6870         else {  
6871                 if(size == 1)
6872                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6873                 else 
6874                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6875         }
6876 }
6877
6878 /*-----------------------------------------------------------------*/
6879 /* shiftLLong - shift left one long from left to result            */
6880 /* offl = LSB or MSB16                                             */
6881 /*-----------------------------------------------------------------*/
6882 static void shiftLLong (operand *left, operand *result, int offr )
6883 {
6884         char *l;
6885         int size = AOP_SIZE(result);
6886         
6887         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6888         if(size >= LSB+offr){
6889                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6890                 MOVA(l);
6891                 pic14_emitcode("add","a,acc");
6892                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6893                         size >= MSB16+offr && offr != LSB )
6894                         pic14_emitcode("xch","a,%s",
6895                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6896                 else      
6897                         aopPut(AOP(result),"a",LSB+offr);
6898         }
6899         
6900         if(size >= MSB16+offr){
6901                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6902                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6903                         MOVA(l);
6904                 }
6905                 pic14_emitcode("rlc","a");
6906                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6907                         size >= MSB24+offr && offr != LSB)
6908                         pic14_emitcode("xch","a,%s",
6909                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6910                 else      
6911                         aopPut(AOP(result),"a",MSB16+offr);
6912         }
6913         
6914         if(size >= MSB24+offr){
6915                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6916                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6917                         MOVA(l);
6918                 }
6919                 pic14_emitcode("rlc","a");
6920                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6921                         size >= MSB32+offr && offr != LSB )
6922                         pic14_emitcode("xch","a,%s",
6923                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6924                 else      
6925                         aopPut(AOP(result),"a",MSB24+offr);
6926         }
6927         
6928         if(size > MSB32+offr){
6929                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6930                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6931                         MOVA(l);  
6932                 }
6933                 pic14_emitcode("rlc","a");
6934                 aopPut(AOP(result),"a",MSB32+offr);
6935         }
6936         if(offr != LSB)
6937                 aopPut(AOP(result),zero,LSB);       
6938 }
6939
6940 /*-----------------------------------------------------------------*/
6941 /* genlshFour - shift four byte by a known amount != 0             */
6942 /*-----------------------------------------------------------------*/
6943 static void genlshFour (operand *result, operand *left, int shCount)
6944 {
6945         int size;
6946         
6947         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6948         size = AOP_SIZE(result);
6949         
6950         /* if shifting more that 3 bytes */
6951         if (shCount >= 24 ) {
6952                 shCount -= 24;
6953                 if (shCount)
6954                 /* lowest order of left goes to the highest
6955                 order of the destination */
6956                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6957                 else
6958                         movLeft2Result(left, LSB, result, MSB32);
6959                 aopPut(AOP(result),zero,LSB);
6960                 aopPut(AOP(result),zero,MSB16);
6961                 aopPut(AOP(result),zero,MSB32);
6962                 return;
6963         }
6964         
6965         /* more than two bytes */
6966         else if ( shCount >= 16 ) {
6967                 /* lower order two bytes goes to higher order two bytes */
6968                 shCount -= 16;
6969                 /* if some more remaining */
6970                 if (shCount)
6971                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6972                 else {
6973                         movLeft2Result(left, MSB16, result, MSB32);
6974                         movLeft2Result(left, LSB, result, MSB24);
6975                 }
6976                 aopPut(AOP(result),zero,MSB16);
6977                 aopPut(AOP(result),zero,LSB);
6978                 return;
6979         }    
6980         
6981         /* if more than 1 byte */
6982         else if ( shCount >= 8 ) {
6983                 /* lower order three bytes goes to higher order  three bytes */
6984                 shCount -= 8;
6985                 if(size == 2){
6986                         if(shCount)
6987                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6988                         else
6989                                 movLeft2Result(left, LSB, result, MSB16);
6990                 }
6991                 else{   /* size = 4 */
6992                         if(shCount == 0){
6993                                 movLeft2Result(left, MSB24, result, MSB32);
6994                                 movLeft2Result(left, MSB16, result, MSB24);
6995                                 movLeft2Result(left, LSB, result, MSB16);
6996                                 aopPut(AOP(result),zero,LSB);
6997                         }
6998                         else if(shCount == 1)
6999                                 shiftLLong(left, result, MSB16);
7000                         else{
7001                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7002                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7003                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7004                                 aopPut(AOP(result),zero,LSB);
7005                         }
7006                 }
7007         }
7008         
7009         /* 1 <= shCount <= 7 */
7010         else if(shCount <= 2){
7011                 shiftLLong(left, result, LSB);
7012                 if(shCount == 2)
7013                         shiftLLong(result, result, LSB);
7014         }
7015         /* 3 <= shCount <= 7, optimize */
7016         else{
7017                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7018                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7019                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7020         }
7021 }
7022
7023 /*-----------------------------------------------------------------*/
7024 /* genLeftShiftLiteral - left shifting by known count              */
7025 /*-----------------------------------------------------------------*/
7026 static void genLeftShiftLiteral (operand *left,
7027                                                                  operand *right,
7028                                                                  operand *result,
7029                                                                  iCode *ic)
7030 {    
7031         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7032         int size;
7033         
7034         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7035         freeAsmop(right,NULL,ic,TRUE);
7036         
7037         aopOp(left,ic,FALSE);
7038         aopOp(result,ic,FALSE);
7039         
7040         size = getSize(operandType(result));
7041         
7042 #if VIEW_SIZE
7043         pic14_emitcode("; shift left ","result %d, left %d",size,
7044                 AOP_SIZE(left));
7045 #endif
7046         
7047         /* I suppose that the left size >= result size */
7048         if(shCount == 0){
7049                 while(size--){
7050                         movLeft2Result(left, size, result, size);
7051                 }
7052         }
7053         
7054         else if(shCount >= (size * 8))
7055                 while(size--)
7056                         aopPut(AOP(result),zero,size);
7057                 else{
7058                         switch (size) {
7059                         case 1:
7060                                 genlshOne (result,left,shCount);
7061                                 break;
7062                                 
7063                         case 2:
7064                         case 3:
7065                                 genlshTwo (result,left,shCount);
7066                                 break;
7067                                 
7068                         case 4:
7069                                 genlshFour (result,left,shCount);
7070                                 break;
7071                         }
7072                 }
7073                 freeAsmop(left,NULL,ic,TRUE);
7074                 freeAsmop(result,NULL,ic,TRUE);
7075 }
7076
7077 /*-----------------------------------------------------------------*
7078 * genMultiAsm - repeat assembly instruction for size of register.
7079 * if endian == 1, then the high byte (i.e base address + size of 
7080 * register) is used first else the low byte is used first;
7081 *-----------------------------------------------------------------*/
7082 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7083 {
7084         
7085         int offset = 0;
7086         
7087         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7088         
7089         if(!reg)
7090                 return;
7091         
7092         if(!endian) {
7093                 endian = 1;
7094         } else {
7095                 endian = -1;
7096                 offset = size-1;
7097         }
7098         
7099         while(size--) {
7100                 emitpcode(poc,    popGet(AOP(reg),offset));
7101                 offset += endian;
7102         }
7103         
7104 }
7105 /*-----------------------------------------------------------------*/
7106 /* genLeftShift - generates code for left shifting                 */
7107 /*-----------------------------------------------------------------*/
7108 static void genLeftShift (iCode *ic)
7109 {
7110         operand *left,*right, *result;
7111         int size, offset;
7112         char *l;
7113         symbol *tlbl , *tlbl1;
7114         pCodeOp *pctemp;
7115         
7116         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7117         
7118         right = IC_RIGHT(ic);
7119         left  = IC_LEFT(ic);
7120         result = IC_RESULT(ic);
7121         
7122         aopOp(right,ic,FALSE);
7123         
7124         /* if the shift count is known then do it 
7125         as efficiently as possible */
7126         if (AOP_TYPE(right) == AOP_LIT) {
7127                 genLeftShiftLiteral (left,right,result,ic);
7128                 return ;
7129         }
7130         
7131         /* shift count is unknown then we have to form 
7132         a loop get the loop count in B : Note: we take
7133         only the lower order byte since shifting
7134         more that 32 bits make no sense anyway, ( the
7135         largest size of an object can be only 32 bits ) */  
7136         
7137         
7138         aopOp(left,ic,FALSE);
7139         aopOp(result,ic,FALSE);
7140         
7141         /* now move the left to the result if they are not the
7142         same */
7143         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7144                 AOP_SIZE(result) > 1) {
7145                 
7146                 size = AOP_SIZE(result);
7147                 offset=0;
7148                 while (size--) {
7149                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7150                         if (*l == '@' && (IS_AOP_PREG(result))) {
7151                                 
7152                                 pic14_emitcode("mov","a,%s",l);
7153                                 aopPut(AOP(result),"a",offset);
7154                         } else {
7155                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7156                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7157                                 //aopPut(AOP(result),l,offset);
7158                         }
7159                         offset++;
7160                 }
7161         }
7162         
7163         size = AOP_SIZE(result);
7164         
7165         /* if it is only one byte then */
7166         if (size == 1) {
7167                 if(optimized_for_speed) {
7168                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7169                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7170                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7171                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7172                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7173                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7174                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7175                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7176                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7177                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7178                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7179                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7180                 } else {
7181                         
7182                         tlbl = newiTempLabel(NULL);
7183                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7184                                 emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7185                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7186                         }
7187                         
7188                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7189                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7190                         emitpLabel(tlbl->key);
7191                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7192                         emitpcode(POC_ADDLW,  popGetLit(1));
7193                         emitSKPC;
7194                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7195                 }
7196                 goto release ;
7197         }
7198         
7199         if (pic14_sameRegs(AOP(left),AOP(result))) {
7200                 
7201                 tlbl = newiTempLabel(NULL);
7202                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7203                 genMultiAsm(POC_RRF, result, size,1);
7204                 emitpLabel(tlbl->key);
7205                 genMultiAsm(POC_RLF, result, size,0);
7206                 emitpcode(POC_ADDLW,  popGetLit(1));
7207                 emitSKPC;
7208                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7209                 goto release;
7210         }
7211         
7212         //tlbl = newiTempLabel(NULL);
7213         //offset = 0 ;   
7214         //tlbl1 = newiTempLabel(NULL);
7215         
7216         //reAdjustPreg(AOP(result));    
7217         
7218         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7219         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7220         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7221         //MOVA(l);
7222         //pic14_emitcode("add","a,acc");         
7223         //aopPut(AOP(result),"a",offset++);
7224         //while (--size) {
7225         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7226         //  MOVA(l);
7227         //  pic14_emitcode("rlc","a");         
7228         //  aopPut(AOP(result),"a",offset++);
7229         //}
7230         //reAdjustPreg(AOP(result));
7231         
7232         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7233         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7234         
7235         
7236         tlbl = newiTempLabel(NULL);
7237         tlbl1= newiTempLabel(NULL);
7238         
7239         size = AOP_SIZE(result);
7240         offset = 1;
7241         
7242         pctemp = popGetTempReg();  /* grab a temporary working register. */
7243         
7244         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7245         
7246         /* offset should be 0, 1 or 3 */
7247         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7248         emitSKPNZ;
7249         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7250         
7251         emitpcode(POC_MOVWF, pctemp);
7252         
7253         
7254         emitpLabel(tlbl->key);
7255         
7256         emitCLRC;
7257         emitpcode(POC_RLF,  popGet(AOP(result),0));
7258         while(--size)
7259                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7260         
7261         emitpcode(POC_DECFSZ,  pctemp);
7262         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7263         emitpLabel(tlbl1->key);
7264         
7265         popReleaseTempReg(pctemp);
7266         
7267         
7268 release:
7269         freeAsmop (right,NULL,ic,TRUE);
7270         freeAsmop(left,NULL,ic,TRUE);
7271         freeAsmop(result,NULL,ic,TRUE);
7272 }
7273
7274 /*-----------------------------------------------------------------*/
7275 /* genrshOne - right shift a one byte quantity by known count      */
7276 /*-----------------------------------------------------------------*/
7277 static void genrshOne (operand *result, operand *left,
7278                                            int shCount, int sign)
7279 {
7280         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7281         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7282 }
7283
7284 /*-----------------------------------------------------------------*/
7285 /* genrshTwo - right shift two bytes by known amount != 0          */
7286 /*-----------------------------------------------------------------*/
7287 static void genrshTwo (operand *result,operand *left,
7288                                            int shCount, int sign)
7289 {
7290         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7291         /* if shCount >= 8 */
7292         if (shCount >= 8) {
7293                 shCount -= 8 ;
7294                 if (shCount)
7295                         shiftR1Left2Result(left, MSB16, result, LSB,
7296                         shCount, sign);
7297                 else
7298                         movLeft2Result(left, MSB16, result, LSB);
7299                 
7300                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7301                 
7302                 if(sign) {
7303                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7304                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7305                 }
7306         }
7307         
7308         /*  1 <= shCount <= 7 */
7309         else
7310                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7311 }
7312
7313 /*-----------------------------------------------------------------*/
7314 /* shiftRLong - shift right one long from left to result           */
7315 /* offl = LSB or MSB16                                             */
7316 /*-----------------------------------------------------------------*/
7317 static void shiftRLong (operand *left, int offl,
7318                                                 operand *result, int sign)
7319 {
7320         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7321         if(!sign)
7322                 pic14_emitcode("clr","c");
7323         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7324         if(sign)
7325                 pic14_emitcode("mov","c,acc.7");
7326         pic14_emitcode("rrc","a");
7327         aopPut(AOP(result),"a",MSB32-offl);
7328         if(offl == MSB16)
7329                 /* add sign of "a" */
7330                 addSign(result, MSB32, sign);
7331         
7332         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7333         pic14_emitcode("rrc","a");
7334         aopPut(AOP(result),"a",MSB24-offl);
7335         
7336         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7337         pic14_emitcode("rrc","a");
7338         aopPut(AOP(result),"a",MSB16-offl);
7339         
7340         if(offl == LSB){
7341                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7342                 pic14_emitcode("rrc","a");
7343                 aopPut(AOP(result),"a",LSB);
7344         }
7345 }
7346
7347 /*-----------------------------------------------------------------*/
7348 /* genrshFour - shift four byte by a known amount != 0             */
7349 /*-----------------------------------------------------------------*/
7350 static void genrshFour (operand *result, operand *left,
7351                                                 int shCount, int sign)
7352 {
7353         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7354         /* if shifting more that 3 bytes */
7355         if(shCount >= 24 ) {
7356                 shCount -= 24;
7357                 if(shCount)
7358                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7359                 else
7360                         movLeft2Result(left, MSB32, result, LSB);
7361                 
7362                 addSign(result, MSB16, sign);
7363         }
7364         else if(shCount >= 16){
7365                 shCount -= 16;
7366                 if(shCount)
7367                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7368                 else{
7369                         movLeft2Result(left, MSB24, result, LSB);
7370                         movLeft2Result(left, MSB32, result, MSB16);
7371                 }
7372                 addSign(result, MSB24, sign);
7373         }
7374         else if(shCount >= 8){
7375                 shCount -= 8;
7376                 if(shCount == 1)
7377                         shiftRLong(left, MSB16, result, sign);
7378                 else if(shCount == 0){
7379                         movLeft2Result(left, MSB16, result, LSB);
7380                         movLeft2Result(left, MSB24, result, MSB16);
7381                         movLeft2Result(left, MSB32, result, MSB24);
7382                         addSign(result, MSB32, sign);
7383                 }
7384                 else{
7385                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7386                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7387                         /* the last shift is signed */
7388                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7389                         addSign(result, MSB32, sign);
7390                 }
7391         }
7392         else{   /* 1 <= shCount <= 7 */
7393                 if(shCount <= 2){
7394                         shiftRLong(left, LSB, result, sign);
7395                         if(shCount == 2)
7396                                 shiftRLong(result, LSB, result, sign);
7397                 }
7398                 else{
7399                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7400                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7401                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7402                 }
7403         }
7404 }
7405
7406 /*-----------------------------------------------------------------*/
7407 /* genRightShiftLiteral - right shifting by known count            */
7408 /*-----------------------------------------------------------------*/
7409 static void genRightShiftLiteral (operand *left,
7410                                                                   operand *right,
7411                                                                   operand *result,
7412                                                                   iCode *ic,
7413                                                                   int sign)
7414 {    
7415         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7416         int lsize,res_size;
7417         
7418         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7419         freeAsmop(right,NULL,ic,TRUE);
7420         
7421         aopOp(left,ic,FALSE);
7422         aopOp(result,ic,FALSE);
7423         
7424 #if VIEW_SIZE
7425         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7426                 AOP_SIZE(left));
7427 #endif
7428         
7429         lsize = pic14_getDataSize(left);
7430         res_size = pic14_getDataSize(result);
7431         /* test the LEFT size !!! */
7432         
7433         /* I suppose that the left size >= result size */
7434         if(shCount == 0){
7435                 while(res_size--)
7436                         movLeft2Result(left, lsize, result, res_size);
7437         }
7438         
7439         else if(shCount >= (lsize * 8)){
7440                 
7441                 if(res_size == 1) {
7442                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7443                         if(sign) {
7444                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7445                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7446                         }
7447                 } else {
7448                         
7449                         if(sign) {
7450                                 emitpcode(POC_MOVLW, popGetLit(0));
7451                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7452                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7453                                 while(res_size--)
7454                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7455                                 
7456                         } else {
7457                                 
7458                                 while(res_size--)
7459                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7460                         }
7461                 }
7462         } else {
7463                 
7464                 switch (res_size) {
7465                 case 1:
7466                         genrshOne (result,left,shCount,sign);
7467                         break;
7468                         
7469                 case 2:
7470                         genrshTwo (result,left,shCount,sign);
7471                         break;
7472                         
7473                 case 4:
7474                         genrshFour (result,left,shCount,sign);
7475                         break;
7476                 default :
7477                         break;
7478                 }
7479                 
7480         }
7481         
7482         freeAsmop(left,NULL,ic,TRUE);
7483         freeAsmop(result,NULL,ic,TRUE);
7484 }
7485
7486 /*-----------------------------------------------------------------*/
7487 /* genSignedRightShift - right shift of signed number              */
7488 /*-----------------------------------------------------------------*/
7489 static void genSignedRightShift (iCode *ic)
7490 {
7491         operand *right, *left, *result;
7492         int size, offset;
7493         //  char *l;
7494         symbol *tlbl, *tlbl1 ;
7495         pCodeOp *pctemp;
7496         
7497         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7498         
7499         /* we do it the hard way put the shift count in b
7500         and loop thru preserving the sign */
7501         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7502         
7503         right = IC_RIGHT(ic);
7504         left  = IC_LEFT(ic);
7505         result = IC_RESULT(ic);
7506         
7507         aopOp(right,ic,FALSE);  
7508         aopOp(left,ic,FALSE);
7509         aopOp(result,ic,FALSE);
7510         
7511         
7512         if ( AOP_TYPE(right) == AOP_LIT) {
7513                 genRightShiftLiteral (left,right,result,ic,1);
7514                 return ;
7515         }
7516         /* shift count is unknown then we have to form 
7517         a loop get the loop count in B : Note: we take
7518         only the lower order byte since shifting
7519         more that 32 bits make no sense anyway, ( the
7520         largest size of an object can be only 32 bits ) */  
7521         
7522         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7523         //pic14_emitcode("inc","b");
7524         //freeAsmop (right,NULL,ic,TRUE);
7525         //aopOp(left,ic,FALSE);
7526         //aopOp(result,ic,FALSE);
7527         
7528         /* now move the left to the result if they are not the
7529         same */
7530         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7531                 AOP_SIZE(result) > 1) {
7532                 
7533                 size = AOP_SIZE(result);
7534                 offset=0;
7535                 while (size--) { 
7536                 /*
7537                 l = aopGet(AOP(left),offset,FALSE,TRUE);
7538                 if (*l == '@' && IS_AOP_PREG(result)) {
7539                 
7540                   pic14_emitcode("mov","a,%s",l);
7541                   aopPut(AOP(result),"a",offset);
7542                   } else
7543                   aopPut(AOP(result),l,offset);
7544                         */
7545                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7546                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7547                         
7548                         offset++;
7549                 }
7550         }
7551         
7552         /* mov the highest order bit to OVR */    
7553         tlbl = newiTempLabel(NULL);
7554         tlbl1= newiTempLabel(NULL);
7555         
7556         size = AOP_SIZE(result);
7557         offset = size - 1;
7558         
7559         pctemp = popGetTempReg();  /* grab a temporary working register. */
7560         
7561         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7562         
7563         /* offset should be 0, 1 or 3 */
7564         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7565         emitSKPNZ;
7566         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7567         
7568         emitpcode(POC_MOVWF, pctemp);
7569         
7570         
7571         emitpLabel(tlbl->key);
7572         
7573         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7574         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7575         
7576         while(--size) {
7577                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7578         }
7579         
7580         emitpcode(POC_DECFSZ,  pctemp);
7581         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7582         emitpLabel(tlbl1->key);
7583         
7584         popReleaseTempReg(pctemp);
7585 #if 0
7586         size = AOP_SIZE(result);
7587         offset = size - 1;
7588         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7589         pic14_emitcode("rlc","a");
7590         pic14_emitcode("mov","ov,c");
7591         /* if it is only one byte then */
7592         if (size == 1) {
7593                 l = aopGet(AOP(left),0,FALSE,FALSE);
7594                 MOVA(l);
7595                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7596                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7597                 pic14_emitcode("mov","c,ov");
7598                 pic14_emitcode("rrc","a");
7599                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7600                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7601                 aopPut(AOP(result),"a",0);
7602                 goto release ;
7603         }
7604         
7605         reAdjustPreg(AOP(result));
7606         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7607         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7608         pic14_emitcode("mov","c,ov");
7609         while (size--) {
7610                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7611                 MOVA(l);
7612                 pic14_emitcode("rrc","a");         
7613                 aopPut(AOP(result),"a",offset--);
7614         }
7615         reAdjustPreg(AOP(result));
7616         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7617         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7618         
7619 release:
7620 #endif
7621         
7622         freeAsmop(left,NULL,ic,TRUE);
7623         freeAsmop(result,NULL,ic,TRUE);
7624         freeAsmop(right,NULL,ic,TRUE);
7625 }
7626
7627 /*-----------------------------------------------------------------*/
7628 /* genRightShift - generate code for right shifting                */
7629 /*-----------------------------------------------------------------*/
7630 static void genRightShift (iCode *ic)
7631 {
7632         operand *right, *left, *result;
7633         sym_link *retype ;
7634         int size, offset;
7635         char *l;
7636         symbol *tlbl, *tlbl1 ;
7637         
7638         /* if signed then we do it the hard way preserve the
7639         sign bit moving it inwards */
7640         retype = getSpec(operandType(IC_RESULT(ic)));
7641         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7642         
7643         if (!SPEC_USIGN(retype)) {
7644                 genSignedRightShift (ic);
7645                 return ;
7646         }
7647         
7648         /* signed & unsigned types are treated the same : i.e. the
7649         signed is NOT propagated inwards : quoting from the
7650         ANSI - standard : "for E1 >> E2, is equivalent to division
7651         by 2**E2 if unsigned or if it has a non-negative value,
7652         otherwise the result is implementation defined ", MY definition
7653         is that the sign does not get propagated */
7654         
7655         right = IC_RIGHT(ic);
7656         left  = IC_LEFT(ic);
7657         result = IC_RESULT(ic);
7658         
7659         aopOp(right,ic,FALSE);
7660         
7661         /* if the shift count is known then do it 
7662         as efficiently as possible */
7663         if (AOP_TYPE(right) == AOP_LIT) {
7664                 genRightShiftLiteral (left,right,result,ic, 0);
7665                 return ;
7666         }
7667         
7668         /* shift count is unknown then we have to form 
7669         a loop get the loop count in B : Note: we take
7670         only the lower order byte since shifting
7671         more that 32 bits make no sense anyway, ( the
7672         largest size of an object can be only 32 bits ) */  
7673         
7674         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7675         pic14_emitcode("inc","b");
7676         aopOp(left,ic,FALSE);
7677         aopOp(result,ic,FALSE);
7678         
7679         /* now move the left to the result if they are not the
7680         same */
7681         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7682                 AOP_SIZE(result) > 1) {
7683                 
7684                 size = AOP_SIZE(result);
7685                 offset=0;
7686                 while (size--) {
7687                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7688                         if (*l == '@' && IS_AOP_PREG(result)) {
7689                                 
7690                                 pic14_emitcode("mov","a,%s",l);
7691                                 aopPut(AOP(result),"a",offset);
7692                         } else
7693                                 aopPut(AOP(result),l,offset);
7694                         offset++;
7695                 }
7696         }
7697         
7698         tlbl = newiTempLabel(NULL);
7699         tlbl1= newiTempLabel(NULL);
7700         size = AOP_SIZE(result);
7701         offset = size - 1;
7702         
7703         /* if it is only one byte then */
7704         if (size == 1) {
7705                 
7706                 tlbl = newiTempLabel(NULL);
7707                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7708                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7709                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7710                 }
7711                 
7712                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7713                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7714                 emitpLabel(tlbl->key);
7715                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7716                 emitpcode(POC_ADDLW,  popGetLit(1));
7717                 emitSKPC;
7718                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7719                 
7720                 goto release ;
7721         }
7722         
7723         reAdjustPreg(AOP(result));
7724         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7725         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7726         CLRC;
7727         while (size--) {
7728                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7729                 MOVA(l);
7730                 pic14_emitcode("rrc","a");         
7731                 aopPut(AOP(result),"a",offset--);
7732         }
7733         reAdjustPreg(AOP(result));
7734         
7735         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7736         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7737         
7738 release:
7739         freeAsmop(left,NULL,ic,TRUE);
7740         freeAsmop (right,NULL,ic,TRUE);
7741         freeAsmop(result,NULL,ic,TRUE);
7742 }
7743
7744 /*-----------------------------------------------------------------*/
7745 /* genUnpackBits - generates code for unpacking bits               */
7746 /*-----------------------------------------------------------------*/
7747 static void genUnpackBits (operand *result, char *rname, int ptype)
7748 {    
7749         int shCnt ;
7750         int rlen = 0 ;
7751         sym_link *etype;
7752         int offset = 0 ;
7753         
7754         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7755         etype = getSpec(operandType(result));
7756         
7757         /* read the first byte  */
7758         switch (ptype) {
7759                 
7760         case POINTER:
7761         case IPOINTER:
7762                 pic14_emitcode("mov","a,@%s",rname);
7763                 break;
7764                 
7765         case PPOINTER:
7766                 pic14_emitcode("movx","a,@%s",rname);
7767                 break;
7768                 
7769         case FPOINTER:
7770                 pic14_emitcode("movx","a,@dptr");
7771                 break;
7772                 
7773         case CPOINTER:
7774                 pic14_emitcode("clr","a");
7775                 pic14_emitcode("movc","a","@a+dptr");
7776                 break;
7777                 
7778         case GPOINTER:
7779                 pic14_emitcode("lcall","__gptrget");
7780                 break;
7781         }
7782         
7783         /* if we have bitdisplacement then it fits   */
7784         /* into this byte completely or if length is */
7785         /* less than a byte                          */
7786         if ((shCnt = SPEC_BSTR(etype)) || 
7787                 (SPEC_BLEN(etype) <= 8))  {
7788                 
7789                 /* shift right acc */
7790                 AccRsh(shCnt);
7791                 
7792                 pic14_emitcode("anl","a,#0x%02x",
7793                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7794                 aopPut(AOP(result),"a",offset);
7795                 return ;
7796         }
7797         
7798         /* bit field did not fit in a byte  */
7799         rlen = SPEC_BLEN(etype) - 8;
7800         aopPut(AOP(result),"a",offset++);
7801         
7802         while (1)  {
7803                 
7804                 switch (ptype) {
7805                 case POINTER:
7806                 case IPOINTER:
7807                         pic14_emitcode("inc","%s",rname);
7808                         pic14_emitcode("mov","a,@%s",rname);
7809                         break;
7810                         
7811                 case PPOINTER:
7812                         pic14_emitcode("inc","%s",rname);
7813                         pic14_emitcode("movx","a,@%s",rname);
7814                         break;
7815                         
7816                 case FPOINTER:
7817                         pic14_emitcode("inc","dptr");
7818                         pic14_emitcode("movx","a,@dptr");
7819                         break;
7820                         
7821                 case CPOINTER:
7822                         pic14_emitcode("clr","a");
7823                         pic14_emitcode("inc","dptr");
7824                         pic14_emitcode("movc","a","@a+dptr");
7825                         break;
7826                         
7827                 case GPOINTER:
7828                         pic14_emitcode("inc","dptr");
7829                         pic14_emitcode("lcall","__gptrget");
7830                         break;
7831                 }
7832                 
7833                 rlen -= 8;            
7834                 /* if we are done */
7835                 if ( rlen <= 0 )
7836                         break ;
7837                 
7838                 aopPut(AOP(result),"a",offset++);
7839                 
7840         }
7841         
7842         if (rlen) {
7843                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7844                 aopPut(AOP(result),"a",offset);        
7845         }
7846         
7847         return ;
7848 }
7849
7850 #if 0
7851 /*-----------------------------------------------------------------*/
7852 /* genDataPointerGet - generates code when ptr offset is known     */
7853 /*-----------------------------------------------------------------*/
7854 static void genDataPointerGet (operand *left, 
7855                                                            operand *result, 
7856                                                            iCode *ic)
7857 {
7858         int size , offset = 0;
7859         
7860         
7861         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7862         
7863         
7864         /* optimization - most of the time, left and result are the same
7865         * address, but different types. for the pic code, we could omit
7866         * the following
7867         */
7868         
7869         aopOp(result,ic,TRUE);
7870         
7871         DEBUGpic14_AopType(__LINE__,left,NULL,result);
7872         
7873         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7874         
7875         size = AOP_SIZE(result);
7876         
7877         while (size--) {
7878                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7879                 offset++;
7880         }
7881         
7882         freeAsmop(left,NULL,ic,TRUE);
7883         freeAsmop(result,NULL,ic,TRUE);
7884 }
7885 #endif
7886 /*-----------------------------------------------------------------*/
7887 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7888 /*-----------------------------------------------------------------*/
7889 static void genNearPointerGet (operand *left, 
7890                                                            operand *result, 
7891                                                            iCode *ic)
7892 {
7893         asmop *aop = NULL;
7894         //regs *preg = NULL ;
7895         char *rname ;
7896         sym_link *rtype, *retype;
7897         sym_link *ltype = operandType(left);    
7898         //char buffer[80];
7899         
7900         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7901         
7902         rtype = operandType(result);
7903         retype= getSpec(rtype);
7904         
7905         aopOp(left,ic,FALSE);
7906         
7907         /* if left is rematerialisable and
7908         result is not bit variable type and
7909         the left is pointer to data space i.e
7910         lower 128 bytes of space */
7911         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7912                 !IS_BITVAR(retype)         &&
7913                 DCL_TYPE(ltype) == POINTER) {
7914                 //genDataPointerGet (left,result,ic);
7915                 return ;
7916         }
7917         
7918         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7919         
7920         /* if the value is already in a pointer register
7921         then don't need anything more */
7922         if (!AOP_INPREG(AOP(left))) {
7923                 /* otherwise get a free pointer register */
7924                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7925                 /*
7926                 aop = newAsmop(0);
7927                 preg = getFreePtr(ic,&aop,FALSE);
7928                 pic14_emitcode("mov","%s,%s",
7929                 preg->name,
7930                 aopGet(AOP(left),0,FALSE,TRUE));
7931                 rname = preg->name ;
7932                 */
7933                 rname ="BAD";
7934         } else
7935                 rname = aopGet(AOP(left),0,FALSE,FALSE);
7936         
7937         aopOp (result,ic,FALSE);
7938         
7939         /* if bitfield then unpack the bits */
7940         if (IS_BITFIELD(retype)) 
7941                 genUnpackBits (result,rname,POINTER);
7942         else {
7943                 /* we have can just get the values */
7944                 int size = AOP_SIZE(result);
7945                 int offset = 0 ;  
7946                 
7947                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7948                 
7949                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7950                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7951                 while(size--) {
7952                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7953                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7954                         if(size)
7955                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7956                 }
7957                 /*
7958                 while (size--) {
7959                 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7960                 
7961                   pic14_emitcode("mov","a,@%s",rname);
7962                   aopPut(AOP(result),"a",offset);
7963                   } else {
7964                   sprintf(buffer,"@%s",rname);
7965                   aopPut(AOP(result),buffer,offset);
7966                   }
7967                   offset++ ;
7968                   if (size)
7969                   pic14_emitcode("inc","%s",rname);
7970                   }
7971                 */
7972         }
7973         
7974         /* now some housekeeping stuff */
7975         if (aop) {
7976                 /* we had to allocate for this iCode */
7977                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7978                 freeAsmop(NULL,aop,ic,TRUE);
7979         } else { 
7980         /* we did not allocate which means left
7981         already in a pointer register, then
7982         if size > 0 && this could be used again
7983         we have to point it back to where it 
7984                 belongs */
7985                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7986                 if (AOP_SIZE(result) > 1 &&
7987                         !OP_SYMBOL(left)->remat &&
7988                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
7989                         ic->depth )) {
7990                         int size = AOP_SIZE(result) - 1;
7991                         while (size--)
7992                                 pic14_emitcode("dec","%s",rname);
7993                 }
7994         }
7995         
7996         /* done */
7997         freeAsmop(left,NULL,ic,TRUE);
7998         freeAsmop(result,NULL,ic,TRUE);
7999         
8000 }
8001
8002 /*-----------------------------------------------------------------*/
8003 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8004 /*-----------------------------------------------------------------*/
8005 static void genPagedPointerGet (operand *left, 
8006                                                                 operand *result, 
8007                                                                 iCode *ic)
8008 {
8009         asmop *aop = NULL;
8010         regs *preg = NULL ;
8011         char *rname ;
8012         sym_link *rtype, *retype;    
8013         
8014         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8015         
8016         rtype = operandType(result);
8017         retype= getSpec(rtype);
8018         
8019         aopOp(left,ic,FALSE);
8020         
8021         /* if the value is already in a pointer register
8022         then don't need anything more */
8023         if (!AOP_INPREG(AOP(left))) {
8024                 /* otherwise get a free pointer register */
8025                 aop = newAsmop(0);
8026                 preg = getFreePtr(ic,&aop,FALSE);
8027                 pic14_emitcode("mov","%s,%s",
8028                         preg->name,
8029                         aopGet(AOP(left),0,FALSE,TRUE));
8030                 rname = preg->name ;
8031         } else
8032                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8033         
8034         freeAsmop(left,NULL,ic,TRUE);
8035         aopOp (result,ic,FALSE);
8036         
8037         /* if bitfield then unpack the bits */
8038         if (IS_BITFIELD(retype)) 
8039                 genUnpackBits (result,rname,PPOINTER);
8040         else {
8041                 /* we have can just get the values */
8042                 int size = AOP_SIZE(result);
8043                 int offset = 0 ;  
8044                 
8045                 while (size--) {
8046                         
8047                         pic14_emitcode("movx","a,@%s",rname);
8048                         aopPut(AOP(result),"a",offset);
8049                         
8050                         offset++ ;
8051                         
8052                         if (size)
8053                                 pic14_emitcode("inc","%s",rname);
8054                 }
8055         }
8056         
8057         /* now some housekeeping stuff */
8058         if (aop) {
8059                 /* we had to allocate for this iCode */
8060                 freeAsmop(NULL,aop,ic,TRUE);
8061         } else { 
8062         /* we did not allocate which means left
8063         already in a pointer register, then
8064         if size > 0 && this could be used again
8065         we have to point it back to where it 
8066                 belongs */
8067                 if (AOP_SIZE(result) > 1 &&
8068                         !OP_SYMBOL(left)->remat &&
8069                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8070                         ic->depth )) {
8071                         int size = AOP_SIZE(result) - 1;
8072                         while (size--)
8073                                 pic14_emitcode("dec","%s",rname);
8074                 }
8075         }
8076         
8077         /* done */
8078         freeAsmop(result,NULL,ic,TRUE);
8079         
8080         
8081 }
8082
8083 /*-----------------------------------------------------------------*/
8084 /* genFarPointerGet - gget value from far space                    */
8085 /*-----------------------------------------------------------------*/
8086 static void genFarPointerGet (operand *left,
8087                                                           operand *result, iCode *ic)
8088 {
8089         int size, offset ;
8090         sym_link *retype = getSpec(operandType(result));
8091         
8092         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8093         
8094         aopOp(left,ic,FALSE);
8095         
8096         /* if the operand is already in dptr 
8097         then we do nothing else we move the value to dptr */
8098         if (AOP_TYPE(left) != AOP_STR) {
8099                 /* if this is remateriazable */
8100                 if (AOP_TYPE(left) == AOP_IMMD)
8101                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8102                 else { /* we need to get it byte by byte */
8103                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8104                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8105                         if (options.model == MODEL_FLAT24)
8106                         {
8107                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8108                         }
8109                 }
8110         }
8111         /* so dptr know contains the address */
8112         freeAsmop(left,NULL,ic,TRUE);
8113         aopOp(result,ic,FALSE);
8114         
8115         /* if bit then unpack */
8116         if (IS_BITFIELD(retype)) 
8117                 genUnpackBits(result,"dptr",FPOINTER);
8118         else {
8119                 size = AOP_SIZE(result);
8120                 offset = 0 ;
8121                 
8122                 while (size--) {
8123                         pic14_emitcode("movx","a,@dptr");
8124                         aopPut(AOP(result),"a",offset++);
8125                         if (size)
8126                                 pic14_emitcode("inc","dptr");
8127                 }
8128         }
8129         
8130         freeAsmop(result,NULL,ic,TRUE);
8131 }
8132 #if 0
8133 /*-----------------------------------------------------------------*/
8134 /* genCodePointerGet - get value from code space                  */
8135 /*-----------------------------------------------------------------*/
8136 static void genCodePointerGet (operand *left,
8137                                                            operand *result, iCode *ic)
8138 {
8139         int size, offset ;
8140         sym_link *retype = getSpec(operandType(result));
8141         
8142         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8143         
8144         aopOp(left,ic,FALSE);
8145         
8146         /* if the operand is already in dptr 
8147         then we do nothing else we move the value to dptr */
8148         if (AOP_TYPE(left) != AOP_STR) {
8149                 /* if this is remateriazable */
8150                 if (AOP_TYPE(left) == AOP_IMMD)
8151                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8152                 else { /* we need to get it byte by byte */
8153                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8154                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8155                         if (options.model == MODEL_FLAT24)
8156                         {
8157                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8158                         }
8159                 }
8160         }
8161         /* so dptr know contains the address */
8162         freeAsmop(left,NULL,ic,TRUE);
8163         aopOp(result,ic,FALSE);
8164         
8165         /* if bit then unpack */
8166         if (IS_BITFIELD(retype)) 
8167                 genUnpackBits(result,"dptr",CPOINTER);
8168         else {
8169                 size = AOP_SIZE(result);
8170                 offset = 0 ;
8171                 
8172                 while (size--) {
8173                         pic14_emitcode("clr","a");
8174                         pic14_emitcode("movc","a,@a+dptr");
8175                         aopPut(AOP(result),"a",offset++);
8176                         if (size)
8177                                 pic14_emitcode("inc","dptr");
8178                 }
8179         }
8180         
8181         freeAsmop(result,NULL,ic,TRUE);
8182 }
8183 #endif
8184 /*-----------------------------------------------------------------*/
8185 /* genGenPointerGet - gget value from generic pointer space        */
8186 /*-----------------------------------------------------------------*/
8187 static void genGenPointerGet (operand *left,
8188                                                           operand *result, iCode *ic)
8189 {
8190         int size, offset ;
8191         sym_link *retype = getSpec(operandType(result));
8192         
8193         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8194         aopOp(left,ic,FALSE);
8195         aopOp(result,ic,FALSE);
8196         
8197         
8198         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8199         
8200         /* if the operand is already in dptr 
8201         then we do nothing else we move the value to dptr */
8202         //  if (AOP_TYPE(left) != AOP_STR) {
8203         /* if this is remateriazable */
8204         if (AOP_TYPE(left) == AOP_IMMD) {
8205                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8206                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8207         }
8208         else { /* we need to get it byte by byte */
8209                 
8210                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8211                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8212                 
8213                 size = AOP_SIZE(result);
8214                 offset = 0 ;
8215                 
8216                 while(size--) {
8217                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8218                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8219                         if(size)
8220                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8221                 }
8222                 goto release;
8223         }
8224         //}
8225         /* so dptr know contains the address */
8226         
8227         /* if bit then unpack */
8228         //if (IS_BITFIELD(retype)) 
8229         //  genUnpackBits(result,"dptr",GPOINTER);
8230         
8231 release:
8232         freeAsmop(left,NULL,ic,TRUE);
8233         freeAsmop(result,NULL,ic,TRUE);
8234         
8235 }
8236
8237 /*-----------------------------------------------------------------*/
8238 /* genConstPointerGet - get value from const generic pointer space */
8239 /*-----------------------------------------------------------------*/
8240 static void genConstPointerGet (operand *left,
8241                                                                 operand *result, iCode *ic)
8242 {
8243         //sym_link *retype = getSpec(operandType(result));
8244         symbol *albl = newiTempLabel(NULL);
8245         symbol *blbl = newiTempLabel(NULL);
8246         PIC_OPCODE poc;
8247         pCodeOp *pcop;
8248         
8249         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8250         aopOp(left,ic,FALSE);
8251         aopOp(result,ic,FALSE);
8252         
8253         
8254         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8255         
8256         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8257         
8258         emitpcode(POC_CALL,popGetLabel(albl->key));
8259         pcop = popGetLabel(blbl->key);
8260         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8261         emitpcode(POC_GOTO,pcop);
8262         emitpLabel(albl->key);
8263         
8264         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8265         
8266         emitpcode(poc,popGet(AOP(left),1));
8267         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8268         emitpcode(poc,popGet(AOP(left),0));
8269         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8270         
8271         emitpLabel(blbl->key);
8272         
8273         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8274         
8275         
8276         freeAsmop(left,NULL,ic,TRUE);
8277         freeAsmop(result,NULL,ic,TRUE);
8278         
8279 }
8280 /*-----------------------------------------------------------------*/
8281 /* genPointerGet - generate code for pointer get                   */
8282 /*-----------------------------------------------------------------*/
8283 static void genPointerGet (iCode *ic)
8284 {
8285         operand *left, *result ;
8286         sym_link *type, *etype;
8287         int p_type;
8288         
8289         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8290         
8291         left = IC_LEFT(ic);
8292         result = IC_RESULT(ic) ;
8293         
8294         /* depending on the type of pointer we need to
8295         move it to the correct pointer register */
8296         type = operandType(left);
8297         etype = getSpec(type);
8298         
8299         if (IS_PTR_CONST(type))
8300                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8301         
8302         /* if left is of type of pointer then it is simple */
8303         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8304                 p_type = DCL_TYPE(type);
8305         else {
8306                 /* we have to go by the storage class */
8307                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8308                 
8309                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8310                 
8311                 if (SPEC_OCLS(etype)->codesp ) {
8312                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8313                         //p_type = CPOINTER ; 
8314                 }
8315                 else
8316                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8317                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8318                         /*p_type = FPOINTER ;*/ 
8319                         else
8320                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8321                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8322                                 /*        p_type = PPOINTER; */
8323                                 else
8324                                         if (SPEC_OCLS(etype) == idata )
8325                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8326                                         /*      p_type = IPOINTER; */
8327                                         else
8328                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8329                                         /*      p_type = POINTER ; */
8330         }
8331         
8332         /* now that we have the pointer type we assign
8333         the pointer values */
8334         switch (p_type) {
8335                 
8336         case POINTER: 
8337         case IPOINTER:
8338                 genNearPointerGet (left,result,ic);
8339                 break;
8340                 
8341         case PPOINTER:
8342                 genPagedPointerGet(left,result,ic);
8343                 break;
8344                 
8345         case FPOINTER:
8346                 genFarPointerGet (left,result,ic);
8347                 break;
8348                 
8349         case CPOINTER:
8350                 genConstPointerGet (left,result,ic);
8351                 //pic14_emitcodePointerGet (left,result,ic);
8352                 break;
8353                 
8354         case GPOINTER:
8355                 if (IS_PTR_CONST(type))
8356                         genConstPointerGet (left,result,ic);
8357                 else
8358                         genGenPointerGet (left,result,ic);
8359                 break;
8360         }
8361         
8362 }
8363
8364 /*-----------------------------------------------------------------*/
8365 /* genPackBits - generates code for packed bit storage             */
8366 /*-----------------------------------------------------------------*/
8367 static void genPackBits (sym_link    *etype ,
8368                                                  operand *right ,
8369                                                  char *rname, int p_type)
8370 {
8371         int shCount = 0 ;
8372         int offset = 0  ;
8373         int rLen = 0 ;
8374         int blen, bstr ;   
8375         char *l ;
8376         
8377         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8378         blen = SPEC_BLEN(etype);
8379         bstr = SPEC_BSTR(etype);
8380         
8381         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8382         MOVA(l);   
8383         
8384         /* if the bit lenth is less than or    */
8385         /* it exactly fits a byte then         */
8386         if (SPEC_BLEN(etype) <= 8 )  {
8387                 shCount = SPEC_BSTR(etype) ;
8388                 
8389                 /* shift left acc */
8390                 AccLsh(shCount);
8391                 
8392                 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8393                         
8394                         
8395                         switch (p_type) {
8396                         case POINTER:
8397                                 pic14_emitcode ("mov","b,a");
8398                                 pic14_emitcode("mov","a,@%s",rname);
8399                                 break;
8400                                 
8401                         case FPOINTER:
8402                                 pic14_emitcode ("mov","b,a");
8403                                 pic14_emitcode("movx","a,@dptr");
8404                                 break;
8405                                 
8406                         case GPOINTER:
8407                                 pic14_emitcode ("push","b");
8408                                 pic14_emitcode ("push","acc");
8409                                 pic14_emitcode ("lcall","__gptrget");
8410                                 pic14_emitcode ("pop","b");
8411                                 break;
8412                         }
8413                         
8414                         pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8415                                 ((unsigned char)(0xFF << (blen+bstr)) | 
8416                                 (unsigned char)(0xFF >> (8-bstr)) ) );
8417                         pic14_emitcode ("orl","a,b");
8418                         if (p_type == GPOINTER)
8419                                 pic14_emitcode("pop","b");
8420                 }
8421         }
8422         
8423         switch (p_type) {
8424         case POINTER:
8425                 pic14_emitcode("mov","@%s,a",rname);
8426                 break;
8427                 
8428         case FPOINTER:
8429                 pic14_emitcode("movx","@dptr,a");
8430                 break;
8431                 
8432         case GPOINTER:
8433                 DEBUGpic14_emitcode(";lcall","__gptrput");
8434                 break;
8435         }
8436         
8437         /* if we r done */
8438         if ( SPEC_BLEN(etype) <= 8 )
8439                 return ;
8440         
8441         pic14_emitcode("inc","%s",rname);
8442         rLen = SPEC_BLEN(etype) ;     
8443         
8444         /* now generate for lengths greater than one byte */
8445         while (1) {
8446                 
8447                 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8448                 
8449                 rLen -= 8 ;
8450                 if (rLen <= 0 )
8451                         break ;
8452                 
8453                 switch (p_type) {
8454                 case POINTER:
8455                         if (*l == '@') {
8456                                 MOVA(l);
8457                                 pic14_emitcode("mov","@%s,a",rname);
8458                         } else
8459                                 pic14_emitcode("mov","@%s,%s",rname,l);
8460                         break;
8461                         
8462                 case FPOINTER:
8463                         MOVA(l);
8464                         pic14_emitcode("movx","@dptr,a");
8465                         break;
8466                         
8467                 case GPOINTER:
8468                         MOVA(l);
8469                         DEBUGpic14_emitcode(";lcall","__gptrput");
8470                         break;  
8471                 }   
8472                 pic14_emitcode ("inc","%s",rname);
8473         }
8474         
8475         MOVA(l);
8476         
8477         /* last last was not complete */
8478         if (rLen)   {
8479                 /* save the byte & read byte */
8480                 switch (p_type) {
8481                 case POINTER:
8482                         pic14_emitcode ("mov","b,a");
8483                         pic14_emitcode("mov","a,@%s",rname);
8484                         break;
8485                         
8486                 case FPOINTER:
8487                         pic14_emitcode ("mov","b,a");
8488                         pic14_emitcode("movx","a,@dptr");
8489                         break;
8490                         
8491                 case GPOINTER:
8492                         pic14_emitcode ("push","b");
8493                         pic14_emitcode ("push","acc");
8494                         pic14_emitcode ("lcall","__gptrget");
8495                         pic14_emitcode ("pop","b");
8496                         break;
8497                 }
8498                 
8499                 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8500                 pic14_emitcode ("orl","a,b");
8501         }
8502         
8503         if (p_type == GPOINTER)
8504                 pic14_emitcode("pop","b");
8505         
8506         switch (p_type) {
8507                 
8508         case POINTER:
8509                 pic14_emitcode("mov","@%s,a",rname);
8510                 break;
8511                 
8512         case FPOINTER:
8513                 pic14_emitcode("movx","@dptr,a");
8514                 break;
8515                 
8516         case GPOINTER:
8517                 DEBUGpic14_emitcode(";lcall","__gptrput");
8518                 break;      
8519         }
8520 }
8521 /*-----------------------------------------------------------------*/
8522 /* genDataPointerSet - remat pointer to data space                 */
8523 /*-----------------------------------------------------------------*/
8524 static void genDataPointerSet(operand *right,
8525                                                           operand *result,
8526                                                           iCode *ic)
8527 {
8528         int size, offset = 0 ;
8529         char *l, buffer[256];
8530         
8531         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8532         aopOp(right,ic,FALSE);
8533         
8534         l = aopGet(AOP(result),0,FALSE,TRUE);
8535         size = AOP_SIZE(right);
8536         /*
8537         if ( AOP_TYPE(result) == AOP_PCODE) {
8538         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8539         AOP(result)->aopu.pcop->name,
8540         PCOI(AOP(result)->aopu.pcop)->offset);
8541         }
8542         */
8543         
8544         // tsd, was l+1 - the underline `_' prefix was being stripped
8545         while (size--) {
8546                 if (offset) {
8547                         sprintf(buffer,"(%s + %d)",l,offset);
8548                         fprintf(stderr,"oops  %s\n",buffer);
8549                 } else
8550                         sprintf(buffer,"%s",l);
8551                 
8552                 if (AOP_TYPE(right) == AOP_LIT) {
8553                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8554                         lit = lit >> (8*offset);
8555                         if(lit&0xff) {
8556                                 pic14_emitcode("movlw","%d",lit);
8557                                 pic14_emitcode("movwf","%s",buffer);
8558                                 
8559                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8560                                 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8561                                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8562                                 
8563                         } else {
8564                                 pic14_emitcode("clrf","%s",buffer);
8565                                 //emitpcode(POC_CLRF, popRegFromString(buffer));
8566                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
8567                         }
8568                 }else {
8569                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8570                         pic14_emitcode("movwf","%s",buffer);
8571                         
8572                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8573                         //emitpcode(POC_MOVWF, popRegFromString(buffer));
8574                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
8575                         
8576                 }
8577                 
8578                 offset++;
8579         }
8580         
8581         freeAsmop(right,NULL,ic,TRUE);
8582         freeAsmop(result,NULL,ic,TRUE);
8583 }
8584
8585 /*-----------------------------------------------------------------*/
8586 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8587 /*-----------------------------------------------------------------*/
8588 static void genNearPointerSet (operand *right,
8589                                                            operand *result, 
8590                                                            iCode *ic)
8591 {
8592         asmop *aop = NULL;
8593         char *l;
8594         sym_link *retype;
8595         sym_link *ptype = operandType(result);
8596         
8597         
8598         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8599         retype= getSpec(operandType(right));
8600         
8601         aopOp(result,ic,FALSE);
8602         
8603         
8604         /* if the result is rematerializable &
8605         in data space & not a bit variable */
8606         //if (AOP_TYPE(result) == AOP_IMMD &&
8607         if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8608                 DCL_TYPE(ptype) == POINTER   &&
8609                 !IS_BITFIELD(retype)) {
8610                 genDataPointerSet (right,result,ic);
8611                 freeAsmop(result,NULL,ic,TRUE);
8612                 return;
8613         }
8614         
8615         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8616         aopOp(right,ic,FALSE);
8617         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8618         
8619         /* if the value is already in a pointer register
8620         then don't need anything more */
8621         if (!AOP_INPREG(AOP(result))) {
8622                 /* otherwise get a free pointer register */
8623                 //aop = newAsmop(0);
8624                 //preg = getFreePtr(ic,&aop,FALSE);
8625                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8626                 //pic14_emitcode("mov","%s,%s",
8627                 //         preg->name,
8628                 //         aopGet(AOP(result),0,FALSE,TRUE));
8629                 //rname = preg->name ;
8630                 //pic14_emitcode("movwf","fsr");
8631                 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8632                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8633                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8634                 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8635                 goto release;
8636                 
8637         }// else
8638         //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8639         
8640         
8641         /* if bitfield then unpack the bits */
8642         if (IS_BITFIELD(retype)) {
8643                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8644                         "The programmer is obviously confused");
8645                 //genPackBits (retype,right,rname,POINTER);
8646                 exit(1);
8647         }
8648         else {
8649                 /* we have can just get the values */
8650                 int size = AOP_SIZE(right);
8651                 int offset = 0 ;    
8652                 
8653                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8654                 while (size--) {
8655                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8656                         if (*l == '@' ) {
8657                                 //MOVA(l);
8658                                 //pic14_emitcode("mov","@%s,a",rname);
8659                                 pic14_emitcode("movf","indf,w ;1");
8660                         } else {
8661                                 
8662                                 if (AOP_TYPE(right) == AOP_LIT) {
8663                                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8664                                         if(lit) {
8665                                                 pic14_emitcode("movlw","%s",l);
8666                                                 pic14_emitcode("movwf","indf ;2");
8667                                         } else 
8668                                                 pic14_emitcode("clrf","indf");
8669                                 }else {
8670                                         pic14_emitcode("movf","%s,w",l);
8671                                         pic14_emitcode("movwf","indf ;2");
8672                                 }
8673                                 //pic14_emitcode("mov","@%s,%s",rname,l);
8674                         }
8675                         if (size)
8676                                 pic14_emitcode("incf","fsr,f ;3");
8677                         //pic14_emitcode("inc","%s",rname);
8678                         offset++;
8679                 }
8680         }
8681         
8682         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8683         /* now some housekeeping stuff */
8684         if (aop) {
8685                 /* we had to allocate for this iCode */
8686                 freeAsmop(NULL,aop,ic,TRUE);
8687         } else { 
8688         /* we did not allocate which means left
8689         already in a pointer register, then
8690         if size > 0 && this could be used again
8691         we have to point it back to where it 
8692                 belongs */
8693                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8694                 if (AOP_SIZE(right) > 1 &&
8695                         !OP_SYMBOL(result)->remat &&
8696                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8697                         ic->depth )) {
8698                         int size = AOP_SIZE(right) - 1;
8699                         while (size--)
8700                                 pic14_emitcode("decf","fsr,f");
8701                         //pic14_emitcode("dec","%s",rname);
8702                 }
8703         }
8704         
8705         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8706         /* done */
8707 release:
8708         freeAsmop(right,NULL,ic,TRUE);
8709         freeAsmop(result,NULL,ic,TRUE);
8710 }
8711
8712 /*-----------------------------------------------------------------*/
8713 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8714 /*-----------------------------------------------------------------*/
8715 static void genPagedPointerSet (operand *right,
8716                                                                 operand *result, 
8717                                                                 iCode *ic)
8718 {
8719         asmop *aop = NULL;
8720         regs *preg = NULL ;
8721         char *rname , *l;
8722         sym_link *retype;
8723         
8724         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8725         
8726         retype= getSpec(operandType(right));
8727         
8728         aopOp(result,ic,FALSE);
8729         
8730         /* if the value is already in a pointer register
8731         then don't need anything more */
8732         if (!AOP_INPREG(AOP(result))) {
8733                 /* otherwise get a free pointer register */
8734                 aop = newAsmop(0);
8735                 preg = getFreePtr(ic,&aop,FALSE);
8736                 pic14_emitcode("mov","%s,%s",
8737                         preg->name,
8738                         aopGet(AOP(result),0,FALSE,TRUE));
8739                 rname = preg->name ;
8740         } else
8741                 rname = aopGet(AOP(result),0,FALSE,FALSE);
8742         
8743         freeAsmop(result,NULL,ic,TRUE);
8744         aopOp (right,ic,FALSE);
8745         
8746         /* if bitfield then unpack the bits */
8747         if (IS_BITFIELD(retype)) 
8748                 genPackBits (retype,right,rname,PPOINTER);
8749         else {
8750                 /* we have can just get the values */
8751                 int size = AOP_SIZE(right);
8752                 int offset = 0 ;  
8753                 
8754                 while (size--) {
8755                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8756                         
8757                         MOVA(l);
8758                         pic14_emitcode("movx","@%s,a",rname);
8759                         
8760                         if (size)
8761                                 pic14_emitcode("inc","%s",rname);
8762                         
8763                         offset++;
8764                 }
8765         }
8766         
8767         /* now some housekeeping stuff */
8768         if (aop) {
8769                 /* we had to allocate for this iCode */
8770                 freeAsmop(NULL,aop,ic,TRUE);
8771         } else { 
8772         /* we did not allocate which means left
8773         already in a pointer register, then
8774         if size > 0 && this could be used again
8775         we have to point it back to where it 
8776                 belongs */
8777                 if (AOP_SIZE(right) > 1 &&
8778                         !OP_SYMBOL(result)->remat &&
8779                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8780                         ic->depth )) {
8781                         int size = AOP_SIZE(right) - 1;
8782                         while (size--)
8783                                 pic14_emitcode("dec","%s",rname);
8784                 }
8785         }
8786         
8787         /* done */
8788         freeAsmop(right,NULL,ic,TRUE);
8789         
8790         
8791 }
8792
8793 /*-----------------------------------------------------------------*/
8794 /* genFarPointerSet - set value from far space                     */
8795 /*-----------------------------------------------------------------*/
8796 static void genFarPointerSet (operand *right,
8797                                                           operand *result, iCode *ic)
8798 {
8799         int size, offset ;
8800         sym_link *retype = getSpec(operandType(right));
8801         
8802         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8803         aopOp(result,ic,FALSE);
8804         
8805         /* if the operand is already in dptr 
8806         then we do nothing else we move the value to dptr */
8807         if (AOP_TYPE(result) != AOP_STR) {
8808                 /* if this is remateriazable */
8809                 if (AOP_TYPE(result) == AOP_IMMD)
8810                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8811                 else { /* we need to get it byte by byte */
8812                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8813                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8814                         if (options.model == MODEL_FLAT24)
8815                         {
8816                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8817                         }
8818                 }
8819         }
8820         /* so dptr know contains the address */
8821         freeAsmop(result,NULL,ic,TRUE);
8822         aopOp(right,ic,FALSE);
8823         
8824         /* if bit then unpack */
8825         if (IS_BITFIELD(retype)) 
8826                 genPackBits(retype,right,"dptr",FPOINTER);
8827         else {
8828                 size = AOP_SIZE(right);
8829                 offset = 0 ;
8830                 
8831                 while (size--) {
8832                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8833                         MOVA(l);
8834                         pic14_emitcode("movx","@dptr,a");
8835                         if (size)
8836                                 pic14_emitcode("inc","dptr");
8837                 }
8838         }
8839         
8840         freeAsmop(right,NULL,ic,TRUE);
8841 }
8842
8843 /*-----------------------------------------------------------------*/
8844 /* genGenPointerSet - set value from generic pointer space         */
8845 /*-----------------------------------------------------------------*/
8846 static void genGenPointerSet (operand *right,
8847                                                           operand *result, iCode *ic)
8848 {
8849         int size, offset ;
8850         sym_link *retype = getSpec(operandType(right));
8851         
8852         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8853         
8854         aopOp(result,ic,FALSE);
8855         aopOp(right,ic,FALSE);
8856         size = AOP_SIZE(right);
8857         
8858         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8859         
8860         /* if the operand is already in dptr 
8861         then we do nothing else we move the value to dptr */
8862         if (AOP_TYPE(result) != AOP_STR) {
8863                 /* if this is remateriazable */
8864                 if (AOP_TYPE(result) == AOP_IMMD) {
8865                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8866                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8867                 }
8868                 else { /* we need to get it byte by byte */
8869                         //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8870                         size = AOP_SIZE(right);
8871                         offset = 0 ;
8872                         
8873                         /* hack hack! see if this the FSR. If so don't load W */
8874                         if(AOP_TYPE(right) != AOP_ACC) {
8875                                 
8876                                 
8877                                 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8878                                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8879                                 
8880                                 if(AOP_SIZE(result) > 1) {
8881                                         emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8882                                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8883                                         emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8884                                         
8885                                 }
8886                                 
8887                                 //if(size==2)
8888                                 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8889                                 //if(size==4) {
8890                                 //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8891                                 //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8892                                 //}
8893                                 
8894                                 while(size--) {
8895                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8896                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8897                                         
8898                                         if(size)
8899                                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8900                                 }
8901                                 
8902                                 
8903                                 goto release;
8904                         } 
8905                         
8906                         if(aopIdx(AOP(result),0) != 4) {
8907                                 
8908                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8909                                 goto release;
8910                         }
8911                         
8912                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8913                         goto release;
8914                         
8915                 }
8916         }
8917         /* so dptr know contains the address */
8918         
8919         
8920         /* if bit then unpack */
8921         if (IS_BITFIELD(retype)) 
8922                 genPackBits(retype,right,"dptr",GPOINTER);
8923         else {
8924                 size = AOP_SIZE(right);
8925                 offset = 0 ;
8926                 
8927                 DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8928                 
8929                 while (size--) {
8930                         
8931                         emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8932                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8933                         
8934                         if (AOP_TYPE(right) == AOP_LIT) 
8935                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8936                         else
8937                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8938                         
8939                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8940                         
8941                         offset++;
8942                 }
8943         }
8944         
8945 release:
8946         freeAsmop(right,NULL,ic,TRUE);
8947         freeAsmop(result,NULL,ic,TRUE);
8948 }
8949
8950 /*-----------------------------------------------------------------*/
8951 /* genPointerSet - stores the value into a pointer location        */
8952 /*-----------------------------------------------------------------*/
8953 static void genPointerSet (iCode *ic)
8954 {    
8955         operand *right, *result ;
8956         sym_link *type, *etype;
8957         int p_type;
8958         
8959         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8960         
8961         right = IC_RIGHT(ic);
8962         result = IC_RESULT(ic) ;
8963         
8964         /* depending on the type of pointer we need to
8965         move it to the correct pointer register */
8966         type = operandType(result);
8967         etype = getSpec(type);
8968         /* if left is of type of pointer then it is simple */
8969         if (IS_PTR(type) && !IS_FUNC(type->next)) {
8970                 p_type = DCL_TYPE(type);
8971         }
8972         else {
8973                 /* we have to go by the storage class */
8974                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8975                 
8976                 /*  if (SPEC_OCLS(etype)->codesp ) { */
8977                 /*      p_type = CPOINTER ;  */
8978                 /*  } */
8979                 /*  else */
8980                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8981                 /*    p_type = FPOINTER ; */
8982                 /*      else */
8983                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8984                 /*        p_type = PPOINTER ; */
8985                 /*    else */
8986                 /*        if (SPEC_OCLS(etype) == idata ) */
8987                 /*      p_type = IPOINTER ; */
8988                 /*        else */
8989                 /*      p_type = POINTER ; */
8990         }
8991         
8992         /* now that we have the pointer type we assign
8993         the pointer values */
8994         switch (p_type) {
8995                 
8996         case POINTER:
8997         case IPOINTER:
8998                 genNearPointerSet (right,result,ic);
8999                 break;
9000                 
9001         case PPOINTER:
9002                 genPagedPointerSet (right,result,ic);
9003                 break;
9004                 
9005         case FPOINTER:
9006                 genFarPointerSet (right,result,ic);
9007                 break;
9008                 
9009         case GPOINTER:
9010                 genGenPointerSet (right,result,ic);
9011                 break;
9012                 
9013         default:
9014                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9015                         "genPointerSet: illegal pointer type");
9016         }
9017 }
9018
9019 /*-----------------------------------------------------------------*/
9020 /* genIfx - generate code for Ifx statement                        */
9021 /*-----------------------------------------------------------------*/
9022 static void genIfx (iCode *ic, iCode *popIc)
9023 {
9024         operand *cond = IC_COND(ic);
9025         int isbit =0;
9026         
9027         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9028         
9029         aopOp(cond,ic,FALSE);
9030         
9031         /* get the value into acc */
9032         if (AOP_TYPE(cond) != AOP_CRY)
9033                 pic14_toBoolean(cond);
9034         else
9035                 isbit = 1;
9036         /* the result is now in the accumulator */
9037         freeAsmop(cond,NULL,ic,TRUE);
9038         
9039         /* if there was something to be popped then do it */
9040         if (popIc)
9041                 genIpop(popIc);
9042         
9043         /* if the condition is  a bit variable */
9044         if (isbit && IS_ITEMP(cond) && 
9045                 SPIL_LOC(cond)) {
9046                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9047                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9048         }
9049         else {
9050                 if (isbit && !IS_ITEMP(cond))
9051                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9052                 else
9053                         genIfxJump(ic,"a");
9054         }
9055         ic->generated = 1;
9056         
9057 }
9058
9059 /*-----------------------------------------------------------------*/
9060 /* genAddrOf - generates code for address of                       */
9061 /*-----------------------------------------------------------------*/
9062 static void genAddrOf (iCode *ic)
9063 {
9064         operand *right, *result, *left;
9065         int size, offset ;
9066         
9067         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9068         
9069         
9070         //aopOp(IC_RESULT(ic),ic,FALSE);
9071         
9072         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9073         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9074         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9075         
9076         DEBUGpic14_AopType(__LINE__,left,right,result);
9077         
9078         size = AOP_SIZE(IC_RESULT(ic));
9079         offset = 0;
9080         
9081         while (size--) {
9082                 /* fixing bug #863624, reported from (errolv) */
9083                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9084                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9085                 
9086 #if 0
9087                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9088                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9089 #endif
9090                 offset++;
9091         }
9092         
9093         freeAsmop(left,NULL,ic,FALSE);
9094         freeAsmop(result,NULL,ic,TRUE);
9095         
9096 }
9097
9098 #if 0
9099 /*-----------------------------------------------------------------*/
9100 /* genFarFarAssign - assignment when both are in far space         */
9101 /*-----------------------------------------------------------------*/
9102 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9103 {
9104         int size = AOP_SIZE(right);
9105         int offset = 0;
9106         char *l ;
9107         /* first push the right side on to the stack */
9108         while (size--) {
9109                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9110                 MOVA(l);
9111                 pic14_emitcode ("push","acc");
9112         }
9113         
9114         freeAsmop(right,NULL,ic,FALSE);
9115         /* now assign DPTR to result */
9116         aopOp(result,ic,FALSE);
9117         size = AOP_SIZE(result);
9118         while (size--) {
9119                 pic14_emitcode ("pop","acc");
9120                 aopPut(AOP(result),"a",--offset);
9121         }
9122         freeAsmop(result,NULL,ic,FALSE);
9123         
9124 }
9125 #endif
9126
9127 /*-----------------------------------------------------------------*/
9128 /* genAssign - generate code for assignment                        */
9129 /*-----------------------------------------------------------------*/
9130 static void genAssign (iCode *ic)
9131 {
9132         operand *result, *right;
9133         int size, offset,know_W;
9134         unsigned long lit = 0L;
9135         
9136         result = IC_RESULT(ic);
9137         right  = IC_RIGHT(ic) ;
9138         
9139         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9140         
9141         /* if they are the same */
9142         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9143                 return ;
9144         
9145         aopOp(right,ic,FALSE);
9146         aopOp(result,ic,TRUE);
9147         
9148         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9149         
9150         /* if they are the same registers */
9151         if (pic14_sameRegs(AOP(right),AOP(result)))
9152                 goto release;
9153         
9154         /* if the result is a bit */
9155         if (AOP_TYPE(result) == AOP_CRY) {
9156                 
9157         /* if the right size is a literal then
9158                 we know what the value is */
9159                 if (AOP_TYPE(right) == AOP_LIT) {
9160                         
9161                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9162                                 popGet(AOP(result),0));
9163                         
9164                         if (((int) operandLitValue(right))) 
9165                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9166                                 AOP(result)->aopu.aop_dir,
9167                                 AOP(result)->aopu.aop_dir);
9168                         else
9169                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9170                                 AOP(result)->aopu.aop_dir,
9171                                 AOP(result)->aopu.aop_dir);
9172                         goto release;
9173                 }
9174                 
9175                 /* the right is also a bit variable */
9176                 if (AOP_TYPE(right) == AOP_CRY) {
9177                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9178                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9179                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9180                         
9181                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9182                                 AOP(result)->aopu.aop_dir,
9183                                 AOP(result)->aopu.aop_dir);
9184                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9185                                 AOP(right)->aopu.aop_dir,
9186                                 AOP(right)->aopu.aop_dir);
9187                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9188                                 AOP(result)->aopu.aop_dir,
9189                                 AOP(result)->aopu.aop_dir);
9190                         goto release ;
9191                 }
9192                 
9193                 /* we need to or */
9194                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9195                 pic14_toBoolean(right);
9196                 emitSKPZ;
9197                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9198                 //aopPut(AOP(result),"a",0);
9199                 goto release ;
9200         }
9201         
9202         /* bit variables done */
9203         /* general case */
9204         size = AOP_SIZE(result);
9205         offset = 0 ;
9206         if(AOP_TYPE(right) == AOP_LIT)
9207                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9208         
9209         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9210                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9211                 if(aopIdx(AOP(result),0) == 4) {
9212                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9213                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9214                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9215                         goto release;
9216                 } else
9217                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9218         }
9219         
9220         know_W=-1;
9221         while (size--) {
9222                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9223                 if(AOP_TYPE(right) == AOP_LIT) {
9224                         if(lit&0xff) {
9225                                 if(know_W != (int)(lit&0xff))
9226                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9227                                 know_W = lit&0xff;
9228                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9229                         } else
9230                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9231                         
9232                         lit >>= 8;
9233                         
9234                 } else if (AOP_TYPE(right) == AOP_CRY) {
9235                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9236                         if(offset == 0) {
9237                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9238                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9239                         }
9240                 } else {
9241                         mov2w (AOP(right), offset);
9242                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9243                 }
9244                 
9245                 offset++;
9246         }
9247         
9248         
9249 release:
9250         freeAsmop (right,NULL,ic,FALSE);
9251         freeAsmop (result,NULL,ic,TRUE);
9252 }   
9253
9254 /*-----------------------------------------------------------------*/
9255 /* genJumpTab - genrates code for jump table                       */
9256 /*-----------------------------------------------------------------*/
9257 static void genJumpTab (iCode *ic)
9258 {
9259         symbol *jtab;
9260         char *l;
9261         
9262         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9263         
9264         aopOp(IC_JTCOND(ic),ic,FALSE);
9265         /* get the condition into accumulator */
9266         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9267         MOVA(l);
9268         /* multiply by three */
9269         pic14_emitcode("add","a,acc");
9270         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9271         
9272         jtab = newiTempLabel(NULL);
9273         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9274         pic14_emitcode("jmp","@a+dptr");
9275         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9276         
9277         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9278         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9279         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9280         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9281         emitSKPNC;
9282         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9283         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9284         emitpLabel(jtab->key);
9285         
9286         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9287         
9288         /* now generate the jump labels */
9289         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9290         jtab = setNextItem(IC_JTLABELS(ic))) {
9291                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9292                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9293                 
9294         }
9295         
9296 }
9297
9298 /*-----------------------------------------------------------------*/
9299 /* genMixedOperation - gen code for operators between mixed types  */
9300 /*-----------------------------------------------------------------*/
9301 /*
9302 TSD - Written for the PIC port - but this unfortunately is buggy.
9303 This routine is good in that it is able to efficiently promote 
9304 types to different (larger) sizes. Unfortunately, the temporary
9305 variables that are optimized out by this routine are sometimes
9306 used in other places. So until I know how to really parse the 
9307 iCode tree, I'm going to not be using this routine :(.
9308 */
9309 static int genMixedOperation (iCode *ic)
9310 {
9311 #if 0
9312         operand *result = IC_RESULT(ic);
9313         sym_link *ctype = operandType(IC_LEFT(ic));
9314         operand *right = IC_RIGHT(ic);
9315         int ret = 0;
9316         int big,small;
9317         int offset;
9318         
9319         iCode *nextic;
9320         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9321         
9322         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9323         
9324         nextic = ic->next;
9325         if(!nextic)
9326                 return 0;
9327         
9328         nextright = IC_RIGHT(nextic);
9329         nextleft  = IC_LEFT(nextic);
9330         nextresult = IC_RESULT(nextic);
9331         
9332         aopOp(right,ic,FALSE);
9333         aopOp(result,ic,FALSE);
9334         aopOp(nextright,  nextic, FALSE);
9335         aopOp(nextleft,   nextic, FALSE);
9336         aopOp(nextresult, nextic, FALSE);
9337         
9338         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9339                 
9340                 operand *t = right;
9341                 right = nextright;
9342                 nextright = t; 
9343                 
9344                 pic14_emitcode(";remove right +","");
9345                 
9346         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9347         /*
9348         operand *t = right;
9349         right = nextleft;
9350         nextleft = t; 
9351                 */
9352                 pic14_emitcode(";remove left +","");
9353         } else
9354                 return 0;
9355         
9356         big = AOP_SIZE(nextleft);
9357         small = AOP_SIZE(nextright);
9358         
9359         switch(nextic->op) {
9360                 
9361         case '+':
9362                 pic14_emitcode(";optimize a +","");
9363                 /* if unsigned or not an integral type */
9364                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9365                         pic14_emitcode(";add a bit to something","");
9366                 } else {
9367                         
9368                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9369                         
9370                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9371                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9372                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9373                         } else
9374                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9375                         
9376                         offset = 0;
9377                         while(--big) {
9378                                 
9379                                 offset++;
9380                                 
9381                                 if(--small) {
9382                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9383                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9384                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9385                                         }
9386                                         
9387                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9388                                         emitSKPNC;
9389                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9390                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9391                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9392                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9393                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9394                                         
9395                                 } else {
9396                                         pic14_emitcode("rlf","known_zero,w");
9397                                         
9398                                         /*
9399                                         if right is signed
9400                                         btfsc  right,7
9401                                         addlw ff
9402                                         */
9403                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9404                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9405                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9406                                         } else {
9407                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9408                                         }
9409                                 }
9410                         }
9411                         ret = 1;
9412                 }
9413         }
9414         ret = 1;
9415         
9416 release:
9417         freeAsmop(right,NULL,ic,TRUE);
9418         freeAsmop(result,NULL,ic,TRUE);
9419         freeAsmop(nextright,NULL,ic,TRUE);
9420         freeAsmop(nextleft,NULL,ic,TRUE);
9421         if(ret)
9422                 nextic->generated = 1;
9423         
9424         return ret;
9425 #else
9426         return 0;
9427 #endif
9428 }
9429 /*-----------------------------------------------------------------*/
9430 /* genCast - gen code for casting                                  */
9431 /*-----------------------------------------------------------------*/
9432 static void genCast (iCode *ic)
9433 {
9434         operand *result = IC_RESULT(ic);
9435         sym_link *ctype = operandType(IC_LEFT(ic));
9436         sym_link *rtype = operandType(IC_RIGHT(ic));
9437         operand *right = IC_RIGHT(ic);
9438         int size, offset ;
9439         
9440         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9441         /* if they are equivalent then do nothing */
9442         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9443                 return ;
9444         
9445         aopOp(right,ic,FALSE) ;
9446         aopOp(result,ic,FALSE);
9447         
9448         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9449         
9450         /* if the result is a bit */
9451         if (AOP_TYPE(result) == AOP_CRY) {
9452         /* if the right size is a literal then
9453                 we know what the value is */
9454                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9455                 if (AOP_TYPE(right) == AOP_LIT) {
9456                         
9457                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9458                                 popGet(AOP(result),0));
9459                         
9460                         if (((int) operandLitValue(right))) 
9461                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9462                                 AOP(result)->aopu.aop_dir,
9463                                 AOP(result)->aopu.aop_dir);
9464                         else
9465                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9466                                 AOP(result)->aopu.aop_dir,
9467                                 AOP(result)->aopu.aop_dir);
9468                         
9469                         goto release;
9470                 }
9471                 
9472                 /* the right is also a bit variable */
9473                 if (AOP_TYPE(right) == AOP_CRY) {
9474                         
9475                         emitCLRC;
9476                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9477                         
9478                         pic14_emitcode("clrc","");
9479                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9480                                 AOP(right)->aopu.aop_dir,
9481                                 AOP(right)->aopu.aop_dir);
9482                         aopPut(AOP(result),"c",0);
9483                         goto release ;
9484                 }
9485                 
9486                 /* we need to or */
9487                 if (AOP_TYPE(right) == AOP_REG) {
9488                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9489                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9490                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9491                 }
9492                 pic14_toBoolean(right);
9493                 aopPut(AOP(result),"a",0);
9494                 goto release ;
9495         }
9496         
9497         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9498                 int offset = 1;
9499                 size = AOP_SIZE(result);
9500                 
9501                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9502                 
9503                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9504                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9505                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9506                 
9507                 while (size--)
9508                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9509                 
9510                 goto release;
9511         }
9512         
9513         /* if they are the same size : or less */
9514         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9515                 
9516                 /* if they are in the same place */
9517                 if (pic14_sameRegs(AOP(right),AOP(result)))
9518                         goto release;
9519                 
9520                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9521                 if (IS_PTR_CONST(rtype))
9522                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9523                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9524                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9525                 
9526                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9527                         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9528                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9529                         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9530                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9531                         if(AOP_SIZE(result) <2)
9532                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9533                         
9534                 } else {
9535                         
9536                         /* if they in different places then copy */
9537                         size = AOP_SIZE(result);
9538                         offset = 0 ;
9539                         while (size--) {
9540                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9541                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9542                                 
9543                                 //aopPut(AOP(result),
9544                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9545                                 // offset);
9546                                 
9547                                 offset++;
9548                         }
9549                 }
9550                 goto release;
9551         }
9552         
9553         
9554         /* if the result is of type pointer */
9555         if (IS_PTR(ctype)) {
9556                 
9557                 int p_type;
9558                 sym_link *type = operandType(right);
9559                 sym_link *etype = getSpec(type);
9560                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9561                 
9562                 /* pointer to generic pointer */
9563                 if (IS_GENPTR(ctype)) {
9564                         char *l = zero;
9565                         
9566                         if (IS_PTR(type)) 
9567                                 p_type = DCL_TYPE(type);
9568                         else {
9569                                 /* we have to go by the storage class */
9570                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9571                                 
9572                                 /*    if (SPEC_OCLS(etype)->codesp )  */
9573                                 /*        p_type = CPOINTER ;  */
9574                                 /*    else */
9575                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9576                                 /*      p_type = FPOINTER ; */
9577                                 /*        else */
9578                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9579                                 /*          p_type = PPOINTER; */
9580                                 /*      else */
9581                                 /*          if (SPEC_OCLS(etype) == idata ) */
9582                                 /*        p_type = IPOINTER ; */
9583                                 /*          else */
9584                                 /*        p_type = POINTER ; */
9585                         }
9586                         
9587                         /* the first two bytes are known */
9588                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9589                         size = GPTRSIZE - 1; 
9590                         offset = 0 ;
9591                         while (size--) {
9592                                 if(offset < AOP_SIZE(right)) {
9593                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9594                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9595                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9596                                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9597                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9598                                         } else { 
9599                                                 aopPut(AOP(result),
9600                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9601                                                         offset);
9602                                         }
9603                                 } else 
9604                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9605                                 offset++;
9606                         }
9607                         /* the last byte depending on type */
9608                         switch (p_type) {
9609                         case IPOINTER:
9610                         case POINTER:
9611                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9612                                 break;
9613                         case FPOINTER:
9614                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9615                                 l = one;
9616                                 break;
9617                         case CPOINTER:
9618                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9619                                 l = "#0x02";
9620                                 break;        
9621                         case PPOINTER:
9622                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9623                                 l = "#0x03";
9624                                 break;
9625                                 
9626                         default:
9627                                 /* this should never happen */
9628                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9629                                         "got unknown pointer type");
9630                                 exit(1);
9631                         }
9632                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9633                         goto release ;
9634                 }
9635                 
9636                 /* just copy the pointers */
9637                 size = AOP_SIZE(result);
9638                 offset = 0 ;
9639                 while (size--) {
9640                         aopPut(AOP(result),
9641                                 aopGet(AOP(right),offset,FALSE,FALSE),
9642                                 offset);
9643                         offset++;
9644                 }
9645                 goto release ;
9646         }
9647         
9648         
9649         
9650         /* so we now know that the size of destination is greater
9651         than the size of the source.
9652         Now, if the next iCode is an operator then we might be
9653         able to optimize the operation without performing a cast.
9654         */
9655         if(genMixedOperation(ic))
9656                 goto release;
9657         
9658         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9659         
9660         /* we move to result for the size of source */
9661         size = AOP_SIZE(right);
9662         offset = 0 ;
9663         while (size--) {
9664                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9665                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9666                 offset++;
9667         }
9668         
9669         /* now depending on the sign of the destination */
9670         size = AOP_SIZE(result) - AOP_SIZE(right);
9671         /* if unsigned or not an integral type */
9672         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9673                 while (size--)
9674                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9675         } else {
9676                 /* we need to extend the sign :{ */
9677                 
9678                 if(size == 1) {
9679                         /* Save one instruction of casting char to int */
9680                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9681                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9682                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9683                 } else {
9684                         emitpcodeNULLop(POC_CLRW);
9685                         
9686                         if(offset)
9687                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9688                         else
9689                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9690                         
9691                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9692                         
9693                         while (size--)
9694                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9695                 }
9696         }
9697         
9698 release:
9699         freeAsmop(right,NULL,ic,TRUE);
9700         freeAsmop(result,NULL,ic,TRUE);
9701         
9702 }
9703
9704 /*-----------------------------------------------------------------*/
9705 /* genDjnz - generate decrement & jump if not zero instrucion      */
9706 /*-----------------------------------------------------------------*/
9707 static int genDjnz (iCode *ic, iCode *ifx)
9708 {
9709         symbol *lbl, *lbl1;
9710         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9711         
9712         if (!ifx)
9713                 return 0;
9714         
9715                 /* if the if condition has a false label
9716         then we cannot save */
9717         if (IC_FALSE(ifx))
9718                 return 0;
9719         
9720                 /* if the minus is not of the form 
9721         a = a - 1 */
9722         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9723                 !IS_OP_LITERAL(IC_RIGHT(ic)))
9724                 return 0;
9725         
9726         if (operandLitValue(IC_RIGHT(ic)) != 1)
9727                 return 0;
9728         
9729                 /* if the size of this greater than one then no
9730         saving */
9731         if (getSize(operandType(IC_RESULT(ic))) > 1)
9732                 return 0;
9733         
9734         /* otherwise we can save BIG */
9735         lbl = newiTempLabel(NULL);
9736         lbl1= newiTempLabel(NULL);
9737         
9738         aopOp(IC_RESULT(ic),ic,FALSE);
9739         
9740         if (IS_AOP_PREG(IC_RESULT(ic))) {
9741                 pic14_emitcode("dec","%s",
9742                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9743                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9744                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9745         } else {  
9746                 
9747                 
9748                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9749                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9750                 
9751                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9752                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9753                 
9754         }
9755         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9756         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9757         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9758         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9759         
9760         
9761         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9762         ifx->generated = 1;
9763         return 1;
9764 }
9765
9766 /*-----------------------------------------------------------------*/
9767 /* genReceive - generate code for a receive iCode                  */
9768 /*-----------------------------------------------------------------*/
9769 static void genReceive (iCode *ic)
9770 {
9771         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9772         
9773         if (isOperandInFarSpace(IC_RESULT(ic)) &&
9774                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9775                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9776                 
9777                 int size = getSize(operandType(IC_RESULT(ic)));
9778                 int offset =  fReturnSizePic - size;
9779                 while (size--) {
9780                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9781                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
9782                         offset++;
9783                 }
9784                 aopOp(IC_RESULT(ic),ic,FALSE);
9785                 size = AOP_SIZE(IC_RESULT(ic));
9786                 offset = 0;
9787                 while (size--) {
9788                         pic14_emitcode ("pop","acc");
9789                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9790                 }
9791                 
9792         } else {
9793                 _G.accInUse++;
9794                 aopOp(IC_RESULT(ic),ic,FALSE);
9795                 _G.accInUse--;
9796                 assignResultValue(IC_RESULT(ic));
9797         }
9798         
9799         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9800 }
9801
9802 /*-----------------------------------------------------------------*/
9803 /* genDummyRead - generate code for dummy read of volatiles        */
9804 /*-----------------------------------------------------------------*/
9805 static void
9806 genDummyRead (iCode * ic)
9807 {
9808         pic14_emitcode ("; genDummyRead","");
9809         pic14_emitcode ("; not implemented","");
9810         
9811         ic = ic;
9812 }
9813
9814 /*-----------------------------------------------------------------*/
9815 /* genpic14Code - generate code for pic14 based controllers        */
9816 /*-----------------------------------------------------------------*/
9817 /*
9818 * At this point, ralloc.c has gone through the iCode and attempted
9819 * to optimize in a way suitable for a PIC. Now we've got to generate
9820 * PIC instructions that correspond to the iCode.
9821 *
9822 * Once the instructions are generated, we'll pass through both the
9823 * peep hole optimizer and the pCode optimizer.
9824 *-----------------------------------------------------------------*/
9825
9826 void genpic14Code (iCode *lic)
9827 {
9828         iCode *ic;
9829         int cln = 0;
9830         
9831         lineHead = lineCurr = NULL;
9832         
9833         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9834         addpBlock(pb);
9835         
9836         /* if debug information required */
9837         if (options.debug && currFunc) { 
9838                 if (currFunc) {
9839                         debugFile->writeFunction (currFunc, lic);
9840                 }
9841         }
9842         
9843         
9844         for (ic = lic ; ic ; ic = ic->next ) {
9845                 
9846                 DEBUGpic14_emitcode(";ic","");
9847                 if ( cln != ic->lineno ) {
9848                         if ( options.debug ) {
9849                                 debugFile->writeCLine (ic);
9850                         }
9851                         /*
9852                         pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9853                         pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9854                         printCLine(ic->filename, ic->lineno));
9855                         */
9856                         if (!options.noCcodeInAsm) {
9857                                 addpCode2pBlock(pb,
9858                                         newpCodeCSource(ic->lineno, 
9859                                         ic->filename, 
9860                                         printCLine(ic->filename, ic->lineno)));
9861                         }
9862                         
9863                         cln = ic->lineno ;
9864                 }
9865                 
9866                 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9867                 
9868                 /* if the result is marked as
9869                 spilt and rematerializable or code for
9870                 this has already been generated then
9871                 do nothing */
9872                 if (resultRemat(ic) || ic->generated ) 
9873                         continue ;
9874                 
9875                 /* depending on the operation */
9876                 switch (ic->op) {
9877                 case '!' :
9878                         genNot(ic);
9879                         break;
9880                         
9881                 case '~' :
9882                         genCpl(ic);
9883                         break;
9884                         
9885                 case UNARYMINUS:
9886                         genUminus (ic);
9887                         break;
9888                         
9889                 case IPUSH:
9890                         genIpush (ic);
9891                         break;
9892                         
9893                 case IPOP:
9894                 /* IPOP happens only when trying to restore a 
9895                 spilt live range, if there is an ifx statement
9896                 following this pop then the if statement might
9897                 be using some of the registers being popped which
9898                 would destory the contents of the register so
9899                 we need to check for this condition and handle it */
9900                         if (ic->next            && 
9901                                 ic->next->op == IFX &&
9902                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9903                                 genIfx (ic->next,ic);
9904                         else
9905                                 genIpop (ic);
9906                         break; 
9907                         
9908                 case CALL:
9909                         genCall (ic);
9910                         break;
9911                         
9912                 case PCALL:
9913                         genPcall (ic);
9914                         break;
9915                         
9916                 case FUNCTION:
9917                         genFunction (ic);
9918                         break;
9919                         
9920                 case ENDFUNCTION:
9921                         genEndFunction (ic);
9922                         break;
9923                         
9924                 case RETURN:
9925                         genRet (ic);
9926                         break;
9927                         
9928                 case LABEL:
9929                         genLabel (ic);
9930                         break;
9931                         
9932                 case GOTO:
9933                         genGoto (ic);
9934                         break;
9935                         
9936                 case '+' :
9937                         genPlus (ic) ;
9938                         break;
9939                         
9940                 case '-' :
9941                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9942                                 genMinus (ic);
9943                         break;
9944                         
9945                 case '*' :
9946                         genMult (ic);
9947                         break;
9948                         
9949                 case '/' :
9950                         genDiv (ic) ;
9951                         break;
9952                         
9953                 case '%' :
9954                         genMod (ic);
9955                         break;
9956                         
9957                 case '>' :
9958                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
9959                         break;
9960                         
9961                 case '<' :
9962                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9963                         break;
9964                         
9965                 case LE_OP:
9966                 case GE_OP:
9967                 case NE_OP:
9968                         
9969                 /* note these two are xlated by algebraic equivalence
9970                         during parsing SDCC.y */
9971                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9972                                 "got '>=' or '<=' shouldn't have come here");
9973                         break;  
9974                         
9975                 case EQ_OP:
9976                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9977                         break;      
9978                         
9979                 case AND_OP:
9980                         genAndOp (ic);
9981                         break;
9982                         
9983                 case OR_OP:
9984                         genOrOp (ic);
9985                         break;
9986                         
9987                 case '^' :
9988                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9989                         break;
9990                         
9991                 case '|' :
9992                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9993                         break;
9994                         
9995                 case BITWISEAND:
9996                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9997                         break;
9998                         
9999                 case INLINEASM:
10000                         genInline (ic);
10001                         break;
10002                         
10003                 case RRC:
10004                         genRRC (ic);
10005                         break;
10006                         
10007                 case RLC:
10008                         genRLC (ic);
10009                         break;
10010                         
10011                 case GETHBIT:
10012                         genGetHbit (ic);
10013                         break;
10014                         
10015                 case LEFT_OP:
10016                         genLeftShift (ic);
10017                         break;
10018                         
10019                 case RIGHT_OP:
10020                         genRightShift (ic);
10021                         break;
10022                         
10023                 case GET_VALUE_AT_ADDRESS:
10024                         genPointerGet(ic);
10025                         break;
10026                         
10027                 case '=' :
10028                         if (POINTER_SET(ic))
10029                                 genPointerSet(ic);
10030                         else
10031                                 genAssign(ic);
10032                         break;
10033                         
10034                 case IFX:
10035                         genIfx (ic,NULL);
10036                         break;
10037                         
10038                 case ADDRESS_OF:
10039                         genAddrOf (ic);
10040                         break;
10041                         
10042                 case JUMPTABLE:
10043                         genJumpTab (ic);
10044                         break;
10045                         
10046                 case CAST:
10047                         genCast (ic);
10048                         break;
10049                         
10050                 case RECEIVE:
10051                         genReceive(ic);
10052                         break;
10053                         
10054                 case SEND:
10055                         addSet(&_G.sendSet,ic);
10056                         break;
10057                         
10058                 case DUMMY_READ_VOLATILE:
10059                         genDummyRead (ic);
10060                         break;
10061                         
10062                 default :
10063                         ic = ic;
10064                 }
10065         }
10066
10067         
10068         /* now we are ready to call the
10069         peep hole optimizer */
10070         if (!options.nopeep) {
10071                 peepHole (&lineHead);
10072         }
10073         /* now do the actual printing */
10074         printLine (lineHead,codeOutFile);
10075         
10076 #ifdef PCODE_DEBUG
10077         DFPRINTF((stderr,"printing pBlock\n\n"));
10078         printpBlock(stdout,pb);
10079 #endif
10080         
10081         return;
10082 }