Fixed problem with fn returning a variable bigger than a char.
[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 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
83
84 static char *accUse[] = {"a","b"};
85
86 //static short rbank = -1;
87
88 static struct {
89         short r0Pushed;
90         short r1Pushed;
91         short accInUse;
92         short inLine;
93         short debugLine;
94         short nRegsSaved;
95         set *sendSet;
96 } _G;
97
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
100 */
101 typedef struct resolvedIfx {
102         symbol *lbl;       /* pointer to a label */
103         int condition;   /* true or false ifx */
104                                          int generated;   /* set true when the code associated with the ifx
105                                          * is generated */
106 } resolvedIfx;
107
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
112
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
115
116 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
120
121 static  pBlock *pb;
122
123 /*-----------------------------------------------------------------*/
124 /*      my_powof2(n) - If `n' is an integaer power of 2, then the          */
125 /*                                 exponent of 2 is returned, otherwise -1 is      */
126 /*                                 returned.                                                                       */
127 /* note that this is similar to the function `powof2' in SDCCsymt  */
128 /* if(n == 2^y)                                                                                                    */
129 /*       return y;                                                                                                         */
130 /* return -1;                                                                                                      */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
133 {
134         if(num) {
135                 if( (num & (num-1)) == 0) {
136                         int nshifts = -1;
137                         while(num) {
138                                 num>>=1;
139                                 nshifts++;
140                         }
141                         return nshifts;
142                 }
143         }
144         
145         return -1;
146 }
147
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
149 {
150         
151         DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
152                 line_no,
153                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154                 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
156                 ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
158                 ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159                 ((result) ? AOP_SIZE(result) : 0));
160         
161 }
162
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
164 {
165         
166         DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
167                 line_no,
168                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169                 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
171                 ((left)   ? (SPEC_USIGN(operandType(left))       ? 'u' : 's') : '-'),
172                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
173                 ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
174         
175 }
176
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
178 {
179         va_list ap;
180         char lb[INITIAL_INLINEASM];  
181         char *lbp = lb;
182         
183         if(!debug_verbose)
184                 return;
185         
186         va_start(ap,fmt);   
187         
188         if (inst && *inst) {
189                 if (fmt && *fmt)
190                         sprintf(lb,"%s\t",inst);
191                 else
192                         sprintf(lb,"%s",inst);
193                 vsprintf(lb+(strlen(lb)),fmt,ap);
194         }  else
195                 vsprintf(lb,fmt,ap);
196         
197         while (isspace(*lbp)) lbp++;
198         
199         if (lbp && *lbp) 
200                 lineCurr = (lineCurr ?
201                 connectLine(lineCurr,newLineNode(lb)) :
202         (lineHead = newLineNode(lb)));
203         lineCurr->isInline = _G.inLine;
204         lineCurr->isDebug  = _G.debugLine;
205         
206         addpCode2pBlock(pb,newpCodeCharP(lb));
207         
208         va_end(ap);
209 }
210
211
212 void emitpLabel(int key)
213 {
214         addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
215 }
216
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
218 {
219         if(pcop)
220                 addpCode2pBlock(pb,newpCode(poc,pcop));
221         else
222                 DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
223 }
224
225 void emitpcodeNULLop(PIC_OPCODE poc)
226 {
227         
228         addpCode2pBlock(pb,newpCode(poc,NULL));
229         
230 }
231
232
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple    */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
237 {
238         va_list ap;
239         char lb[INITIAL_INLINEASM];  
240         char *lbp = lb;
241         
242         va_start(ap,fmt);   
243         
244         if (inst && *inst) {
245                 if (fmt && *fmt)
246                         sprintf(lb,"%s\t",inst);
247                 else
248                         sprintf(lb,"%s",inst);
249                 vsprintf(lb+(strlen(lb)),fmt,ap);
250         }  else
251                 vsprintf(lb,fmt,ap);
252         
253         while (isspace(*lbp)) lbp++;
254         
255         if (lbp && *lbp) 
256                 lineCurr = (lineCurr ?
257                 connectLine(lineCurr,newLineNode(lb)) :
258         (lineHead = newLineNode(lb)));
259         lineCurr->isInline = _G.inLine;
260         lineCurr->isDebug  = _G.debugLine;
261         
262         if(debug_verbose)
263                 addpCode2pBlock(pb,newpCodeCharP(lb));
264         
265         va_end(ap);
266 }
267
268 /*-----------------------------------------------------------------*/
269 /* pic14_emitDebuggerSymbol - associate the current code location  */
270 /*       with a debugger symbol                                                                            */
271 /*-----------------------------------------------------------------*/
272 void
273 pic14_emitDebuggerSymbol (char * debugSym)
274 {
275         _G.debugLine = 1;
276         pic14_emitcode ("", ";%s ==.", debugSym);
277         _G.debugLine = 0;
278 }
279
280
281 /*-----------------------------------------------------------------*/
282 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
283 /*-----------------------------------------------------------------*/
284 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
285 {
286         bool r0iu = FALSE , r1iu = FALSE;
287         bool r0ou = FALSE , r1ou = FALSE;
288         
289         /* the logic: if r0 & r1 used in the instruction
290         then we are in trouble otherwise */
291         
292         /* first check if r0 & r1 are used by this
293         instruction, in which case we are in trouble */
294         if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
295                 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
296         {
297                 goto endOfWorld;          
298         }
299         
300         r0ou = bitVectBitValue(ic->rMask,R0_IDX);
301         r1ou = bitVectBitValue(ic->rMask,R1_IDX);
302         
303         /* if no usage of r0 then return it */
304         if (!r0iu && !r0ou) {
305                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
306                 (*aopp)->type = AOP_R0;
307                 
308                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
309         }
310         
311         /* if no usage of r1 then return it */
312         if (!r1iu && !r1ou) {
313                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
314                 (*aopp)->type = AOP_R1;
315                 
316                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
317         }    
318         
319         /* now we know they both have usage */
320         /* if r0 not used in this instruction */
321         if (!r0iu) {
322                 /* push it if not already pushed */
323                 if (!_G.r0Pushed) {
324                         //pic14_emitcode ("push","%s",
325                         //                pic14_regWithIdx(R0_IDX)->dname);
326                         _G.r0Pushed++ ;
327                 }
328                 
329                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
330                 (*aopp)->type = AOP_R0;
331                 
332                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
333         }
334         
335         /* if r1 not used then */
336         
337         if (!r1iu) {
338                 /* push it if not already pushed */
339                 if (!_G.r1Pushed) {
340                         //pic14_emitcode ("push","%s",
341                         //                pic14_regWithIdx(R1_IDX)->dname);
342                         _G.r1Pushed++ ;
343                 }
344                 
345                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
346                 (*aopp)->type = AOP_R1;
347                 return pic14_regWithIdx(R1_IDX);
348         }
349         
350 endOfWorld :
351         /* I said end of world but not quite end of world yet */
352         /* if this is a result then we can push it on the stack*/
353         if (result) {
354                 (*aopp)->type = AOP_STK;        
355                 return NULL;
356         }
357         
358         /* other wise this is true end of the world */
359         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
360                 "getFreePtr should never reach here");
361         exit(0);
362 }
363
364 /*-----------------------------------------------------------------*/
365 /* newAsmop - creates a new asmOp                                                                  */
366 /*-----------------------------------------------------------------*/
367 asmop *newAsmop (short type)
368 {
369         asmop *aop;
370         
371         aop = Safe_calloc(1,sizeof(asmop));
372         aop->type = type;
373         return aop;
374 }
375
376 static void genSetDPTR(int n)
377 {
378         if (!n)
379         {
380                 pic14_emitcode(";", "Select standard DPTR");
381                 pic14_emitcode("mov", "dps, #0x00");
382         }
383         else
384         {
385                 pic14_emitcode(";", "Select alternate DPTR");
386                 pic14_emitcode("mov", "dps, #0x01");
387         }
388 }
389
390 /*-----------------------------------------------------------------*/
391 /* resolveIfx - converts an iCode ifx into a form more useful for  */
392 /*                              generating code                                                                    */
393 /*-----------------------------------------------------------------*/
394 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
395 {
396         if(!resIfx) 
397                 return;
398         
399         //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
400         
401         resIfx->condition = 1;  /* assume that the ifx is true */
402         resIfx->generated = 0;  /* indicate that the ifx has not been used */
403         
404         if(!ifx) {
405                 resIfx->lbl = newiTempLabel(NULL);      /* oops, there is no ifx. so create a label */
406                                                                                         /*
407                                                                                         DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
408                                                                                         __FUNCTION__,__LINE__,resIfx->lbl->key);
409                 */
410         } else {
411                 if(IC_TRUE(ifx)) {
412                         resIfx->lbl = IC_TRUE(ifx);
413                 } else {
414                         resIfx->lbl = IC_FALSE(ifx);
415                         resIfx->condition = 0;
416                 }
417                 /*
418                 if(IC_TRUE(ifx)) 
419                 DEBUGpic14_emitcode("; ***","ifx true is non-null");
420                 if(IC_FALSE(ifx)) 
421                 DEBUGpic14_emitcode("; ***","ifx false is non-null");
422                 */
423         }
424         
425         //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
426         
427 }
428 /*-----------------------------------------------------------------*/
429 /* pointerCode - returns the code for a pointer type                       */
430 /*-----------------------------------------------------------------*/
431 static int pointerCode (sym_link *etype)
432 {
433         
434         return PTR_TYPE(SPEC_OCLS(etype));
435         
436 }
437
438 /*-----------------------------------------------------------------*/
439 /* aopForSym - for a true symbol                                                                   */
440 /*-----------------------------------------------------------------*/
441 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
442 {
443         asmop *aop;
444         memmap *space= SPEC_OCLS(sym->etype);
445         
446         DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
447         /* if already has one */
448         if (sym->aop)
449                 return sym->aop;
450         
451         /* assign depending on the storage class */
452         /* if it is on the stack or indirectly addressable */
453         /* space we need to assign either r0 or r1 to it         */    
454         if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
455                 sym->aop = aop = newAsmop(0);
456                 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
457                 aop->size = getSize(sym->type);
458                 
459                 /* now assign the address of the variable to 
460                 the pointer register */
461                 if (aop->type != AOP_STK) {
462                         
463                         if (sym->onStack) {
464                                 if ( _G.accInUse )
465                                         pic14_emitcode("push","acc");
466                                 
467                                 pic14_emitcode("mov","a,_bp");
468                                 pic14_emitcode("add","a,#0x%02x",
469                                         ((sym->stack < 0) ?
470                                         ((char)(sym->stack - _G.nRegsSaved )) :
471                                 ((char)sym->stack)) & 0xff);
472                                 pic14_emitcode("mov","%s,a",
473                                         aop->aopu.aop_ptr->name);
474                                 
475                                 if ( _G.accInUse )
476                                         pic14_emitcode("pop","acc");
477                         } else
478                                 pic14_emitcode("mov","%s,#%s",
479                                 aop->aopu.aop_ptr->name,
480                                 sym->rname);
481                         aop->paged = space->paged;
482                 } else
483                         aop->aopu.aop_stk = sym->stack;
484                 return aop;
485         }
486         
487         if (sym->onStack && options.stack10bit)
488         {
489         /* It's on the 10 bit stack, which is located in
490         * far data space.
491                 */
492                 
493                 //DEBUGpic14_emitcode(";","%d",__LINE__);
494                 
495                 if ( _G.accInUse )
496                         pic14_emitcode("push","acc");
497                 
498                 pic14_emitcode("mov","a,_bp");
499                 pic14_emitcode("add","a,#0x%02x",
500                         ((sym->stack < 0) ?
501                         ((char)(sym->stack - _G.nRegsSaved )) :
502                 ((char)sym->stack)) & 0xff);
503                 
504                 genSetDPTR(1);
505                 pic14_emitcode ("mov","dpx1,#0x40");
506                 pic14_emitcode ("mov","dph1,#0x00");
507                 pic14_emitcode ("mov","dpl1, a");
508                 genSetDPTR(0);
509                 
510                 if ( _G.accInUse )
511                         pic14_emitcode("pop","acc");
512                 
513                 sym->aop = aop = newAsmop(AOP_DPTR2);
514                 aop->size = getSize(sym->type); 
515                 return aop;
516         }
517         
518         //DEBUGpic14_emitcode(";","%d",__LINE__);
519         /* if in bit space */
520         if (IN_BITSPACE(space)) {
521                 sym->aop = aop = newAsmop (AOP_CRY);
522                 aop->aopu.aop_dir = sym->rname ;
523                 aop->size = getSize(sym->type);
524                 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
525                 return aop;
526         }
527         /* if it is in direct space */
528         if (IN_DIRSPACE(space)) {
529                 sym->aop = aop = newAsmop (AOP_DIR);
530                 aop->aopu.aop_dir = sym->rname ;
531                 aop->size = getSize(sym->type);
532                 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
533                 return aop;
534         }
535         
536         /* special case for a function */
537         if (IS_FUNC(sym->type)) {   
538                 
539                 sym->aop = aop = newAsmop(AOP_PCODE);
540                 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
541                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542                 PCOI(aop->aopu.pcop)->_function = 1;
543                 PCOI(aop->aopu.pcop)->index = 0;
544                 aop->size = FPTRSIZE; 
545                 /*
546                 sym->aop = aop = newAsmop(AOP_IMMD);    
547                 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548                 strcpy(aop->aopu.aop_immd,sym->rname);
549                 aop->size = FPTRSIZE; 
550                 */
551                 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552                 return aop;
553         }
554         
555         
556         /* only remaining is far space */
557         /* in which case DPTR gets the address */
558         sym->aop = aop = newAsmop(AOP_PCODE);
559         
560         aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
561         PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
562         PCOI(aop->aopu.pcop)->index = 0;
563         
564         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
565                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
566         
567         allocDirReg (IC_LEFT(ic));
568         
569         aop->size = FPTRSIZE; 
570         /*
571         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
572         sym->aop = aop = newAsmop(AOP_DPTR);
573         pic14_emitcode ("mov","dptr,#%s", sym->rname);
574         aop->size = getSize(sym->type);
575         
576           DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
577         */
578         
579         /* if it is in code space */
580         if (IN_CODESPACE(space))
581                 aop->code = 1;
582         
583         return aop;       
584 }
585
586 /*-----------------------------------------------------------------*/
587 /* aopForRemat - rematerialzes an object                                                   */
588 /*-----------------------------------------------------------------*/
589 static asmop *aopForRemat (operand *op) // x symbol *sym)
590 {
591         symbol *sym = OP_SYMBOL(op);
592         iCode *ic = NULL;
593         asmop *aop = newAsmop(AOP_PCODE);
594         int val = 0;
595         int offset = 0;
596         
597         ic = sym->rematiCode;
598         
599         DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
600         if(IS_OP_POINTER(op)) {
601                 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
602         }
603         for (;;) {
604                 if (ic->op == '+') {
605                         val += (int) operandLitValue(IC_RIGHT(ic));
606                 } else if (ic->op == '-') {
607                         val -= (int) operandLitValue(IC_RIGHT(ic));
608                 } else
609                         break;
610                 
611                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
612         }
613         
614         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
615         aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
616         PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
617         PCOI(aop->aopu.pcop)->index = val;
618         
619         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
620                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
621                 val, IS_PTR_CONST(operandType(op)));
622         
623         //      DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
624         
625         allocDirReg (IC_LEFT(ic));
626         
627         return aop;              
628 }
629
630 int aopIdx (asmop *aop, int offset)
631 {
632         if(!aop)
633                 return -1;
634         
635         if(aop->type !=  AOP_REG)
636                 return -2;
637         
638         return aop->aopu.aop_reg[offset]->rIdx;
639         
640 }
641 /*-----------------------------------------------------------------*/
642 /* regsInCommon - two operands have some registers in common       */
643 /*-----------------------------------------------------------------*/
644 static bool regsInCommon (operand *op1, operand *op2)
645 {
646         symbol *sym1, *sym2;
647         int i;
648         
649         /* if they have registers in common */
650         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
651                 return FALSE ;
652         
653         sym1 = OP_SYMBOL(op1);
654         sym2 = OP_SYMBOL(op2);
655         
656         if (sym1->nRegs == 0 || sym2->nRegs == 0)
657                 return FALSE ;
658         
659         for (i = 0 ; i < sym1->nRegs ; i++) {
660                 int j;
661                 if (!sym1->regs[i])
662                         continue ;
663                 
664                 for (j = 0 ; j < sym2->nRegs ;j++ ) {
665                         if (!sym2->regs[j])
666                                 continue ;
667                         
668                         if (sym2->regs[j] == sym1->regs[i])
669                                 return TRUE ;
670                 }
671         }
672         
673         return FALSE ;
674 }
675
676 /*-----------------------------------------------------------------*/
677 /* operandsEqu - equivalent                                                                        */
678 /*-----------------------------------------------------------------*/
679 static bool operandsEqu ( operand *op1, operand *op2)
680 {
681         symbol *sym1, *sym2;
682         
683         /* if they not symbols */
684         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
685                 return FALSE;
686         
687         sym1 = OP_SYMBOL(op1);
688         sym2 = OP_SYMBOL(op2);
689         
690         /* if both are itemps & one is spilt
691         and the other is not then false */
692         if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
693                 sym1->isspilt != sym2->isspilt )
694                 return FALSE ;
695         
696         /* if they are the same */
697         if (sym1 == sym2)
698                 return TRUE ;
699         
700         if (sym1->rname[0] && sym2->rname[0]
701                 && strcmp (sym1->rname, sym2->rname) == 0)
702                 return TRUE;
703         
704         
705         /* if left is a tmp & right is not */
706         if (IS_ITEMP(op1)  && 
707                 !IS_ITEMP(op2) &&
708                 sym1->isspilt  &&
709                 (sym1->usl.spillLoc == sym2))
710                 return TRUE;
711         
712         if (IS_ITEMP(op2)  && 
713                 !IS_ITEMP(op1) &&
714                 sym2->isspilt  &&
715                 sym1->level > 0 &&
716                 (sym2->usl.spillLoc == sym1))
717                 return TRUE ;
718         
719         return FALSE ;
720 }
721
722 /*-----------------------------------------------------------------*/
723 /* pic14_sameRegs - two asmops have the same registers                                   */
724 /*-----------------------------------------------------------------*/
725 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
726 {
727         int i;
728         
729         if (aop1 == aop2)
730                 return TRUE ;
731         
732         if (aop1->type != AOP_REG ||
733                 aop2->type != AOP_REG )
734                 return FALSE ;
735         
736         if (aop1->size != aop2->size )
737                 return FALSE ;
738         
739         for (i = 0 ; i < aop1->size ; i++ )
740                 if (aop1->aopu.aop_reg[i] !=
741                         aop2->aopu.aop_reg[i] )
742                         return FALSE ;
743                 
744                 return TRUE ;
745 }
746
747 /*-----------------------------------------------------------------*/
748 /* aopOp - allocates an asmop for an operand  :                                    */
749 /*-----------------------------------------------------------------*/
750 void aopOp (operand *op, iCode *ic, bool result)
751 {
752         asmop *aop;
753         symbol *sym;
754         int i;
755         
756         if (!op)
757                 return ;
758         
759         //      DEBUGpic14_emitcode(";","%d",__LINE__);
760         /* if this a literal */
761         if (IS_OP_LITERAL(op)) {
762                 op->aop = aop = newAsmop(AOP_LIT);
763                 aop->aopu.aop_lit = op->operand.valOperand;
764                 aop->size = getSize(operandType(op));
765                 return;
766         }
767         
768         {
769                 sym_link *type = operandType(op);
770                 if(IS_PTR_CONST(type))
771                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
772         }
773         
774         /* if already has a asmop then continue */
775         if (op->aop)
776                 return ;
777         
778         /* if the underlying symbol has a aop */
779         if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
780                 DEBUGpic14_emitcode(";","%d",__LINE__);
781                 op->aop = OP_SYMBOL(op)->aop;
782                 return;
783         }
784         
785         /* if this is a true symbol */
786         if (IS_TRUE_SYMOP(op)) {          
787                 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
788                 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
789                 return ;
790         }
791         
792         /* this is a temporary : this has
793         only four choices :
794         a) register
795         b) spillocation
796         c) rematerialize 
797         d) conditional   
798         e) can be a return use only */
799         
800         sym = OP_SYMBOL(op);
801         
802         
803         /* if the type is a conditional */
804         if (sym->regType == REG_CND) {
805                 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
806                 aop->size = 0;
807                 return;
808         }
809         
810         /* if it is spilt then two situations
811         a) is rematerialize 
812         b) has a spill location */
813         if (sym->isspilt || sym->nRegs == 0) {
814                 
815                 DEBUGpic14_emitcode(";","%d",__LINE__);
816                 /* rematerialize it NOW */
817                 if (sym->remat) {
818                         
819                         sym->aop = op->aop = aop = aopForRemat (op);
820                         aop->size = getSize(sym->type);
821                         //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
822                         return;
823                 }
824                 
825                 if (sym->accuse) {
826                         int i;
827                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
828                         aop->size = getSize(sym->type);
829                         for ( i = 0 ; i < 2 ; i++ )
830                                 aop->aopu.aop_str[i] = accUse[i];
831                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
832                         return;  
833                 }
834                 
835                 if (sym->ruonly ) {
836                         if(sym->isptr) {        // && sym->uptr 
837                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
838                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
839                                 
840                                 //PCOI(aop->aopu.pcop)->_const = 0;
841                                 //PCOI(aop->aopu.pcop)->index = 0;
842                                 /*
843                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
844                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
845                                 */
846                                 //allocDirReg (IC_LEFT(ic));
847                                 
848                                 aop->size = getSize(sym->type);
849                                 DEBUGpic14_emitcode(";","%d",__LINE__);
850                                 return;
851                                 
852                         } else {
853                                 
854                                 unsigned i;
855                                 
856                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
857                                 aop->size = getSize(sym->type);
858                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
859                                         aop->aopu.aop_str[i] = fReturn[i];
860                                 
861                                 DEBUGpic14_emitcode(";","%d",__LINE__);
862                                 return;
863                         }
864                 }
865                 
866                 /* else spill location  */
867                 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
868                         /* force a new aop if sizes differ */
869                         sym->usl.spillLoc->aop = NULL;
870                 }
871                 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
872                         __FUNCTION__,__LINE__,
873                         sym->usl.spillLoc->rname,
874                         sym->rname, sym->usl.spillLoc->offset);
875                 
876                 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
877                 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
878                 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
879                         getSize(sym->type), 
880                         sym->usl.spillLoc->offset);
881                 aop->size = getSize(sym->type);
882                 
883                 return;
884         }
885         
886         {
887                 sym_link *type = operandType(op);
888                 if(IS_PTR_CONST(type)) 
889                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
890         }
891         
892         /* must be in a register */
893         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
894         sym->aop = op->aop = aop = newAsmop(AOP_REG);
895         aop->size = sym->nRegs;
896         for ( i = 0 ; i < sym->nRegs ;i++)
897                 aop->aopu.aop_reg[i] = sym->regs[i];
898 }
899
900 /*-----------------------------------------------------------------*/
901 /* freeAsmop - free up the asmop given to an operand                       */
902 /*----------------------------------------------------------------*/
903 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
904 {       
905         asmop *aop ;
906         
907         if (!op)
908                 aop = aaop;
909         else 
910                 aop = op->aop;
911         
912         if (!aop)
913                 return ;
914         
915         if (aop->freed)
916                 goto dealloc; 
917         
918         aop->freed = 1;
919         
920         /* depending on the asmop type only three cases need work AOP_RO
921         , AOP_R1 && AOP_STK */
922 #if 0
923         switch (aop->type) {
924         case AOP_R0 :
925                 if (_G.r0Pushed ) {
926                         if (pop) {
927                                 pic14_emitcode ("pop","ar0");     
928                                 _G.r0Pushed--;
929                         }
930                 }
931                 bitVectUnSetBit(ic->rUsed,R0_IDX);
932                 break;
933                 
934         case AOP_R1 :
935                 if (_G.r1Pushed ) {
936                         if (pop) {
937                                 pic14_emitcode ("pop","ar1");
938                                 _G.r1Pushed--;
939                         }
940                 }
941                 bitVectUnSetBit(ic->rUsed,R1_IDX);                      
942                 break;
943                 
944         case AOP_STK :
945                 {
946                         int sz = aop->size;      
947                         int stk = aop->aopu.aop_stk + aop->size;
948                         bitVectUnSetBit(ic->rUsed,R0_IDX);
949                         bitVectUnSetBit(ic->rUsed,R1_IDX);                
950                         
951                         getFreePtr(ic,&aop,FALSE);
952                         
953                         if (options.stack10bit)
954                         {
955                                 /* I'm not sure what to do here yet... */
956                                 /* #STUB */
957                                 fprintf(stderr, 
958                                         "*** Warning: probably generating bad code for "
959                                         "10 bit stack mode.\n");
960                         }
961                         
962                         if (stk) {
963                                 pic14_emitcode ("mov","a,_bp");
964                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
965                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
966                         } else {
967                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
968                         }
969                         
970                         while (sz--) {
971                                 pic14_emitcode("pop","acc");
972                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
973                                 if (!sz) break;
974                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
975                         }
976                         op->aop = aop;
977                         freeAsmop(op,NULL,ic,TRUE);
978                         if (_G.r0Pushed) {
979                                 pic14_emitcode("pop","ar0");
980                                 _G.r0Pushed--;
981                         }
982                         
983                         if (_G.r1Pushed) {
984                                 pic14_emitcode("pop","ar1");
985                                 _G.r1Pushed--;
986                         }         
987                 }
988         }
989 #endif
990         
991 dealloc:
992         /* all other cases just dealloc */
993         if (op ) {
994                 op->aop = NULL;
995                 if (IS_SYMOP(op)) {
996                         OP_SYMBOL(op)->aop = NULL;      
997                         /* if the symbol has a spill */
998                         if (SPIL_LOC(op))
999                                 SPIL_LOC(op)->aop = NULL;
1000                 }
1001         }
1002 }
1003
1004 /*-----------------------------------------------------------------*/
1005 /* aopGet - for fetching value of the aop                                                  */
1006 /*-----------------------------------------------------------------*/
1007 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1008 {
1009         char *s = buffer ;
1010         char *rs;
1011         
1012         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1013         /* offset is greater than
1014         size then zero */
1015         if (offset > (aop->size - 1) &&
1016                 aop->type != AOP_LIT)
1017                 return zero;
1018         
1019         /* depending on type */
1020         switch (aop->type) {
1021                 
1022         case AOP_R0:
1023         case AOP_R1:
1024                 DEBUGpic14_emitcode(";","%d",__LINE__);
1025                 /* if we need to increment it */           
1026                 while (offset > aop->coff) {            
1027                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
1028                         aop->coff++;
1029                 }
1030                 
1031                 while (offset < aop->coff) {
1032                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1033                         aop->coff--;
1034                 }
1035                 
1036                 aop->coff = offset ;
1037                 if (aop->paged) {
1038                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1039                         return (dname ? "acc" : "a");
1040                 }               
1041                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1042                 rs = Safe_calloc(1,strlen(s)+1);
1043                 strcpy(rs,s);   
1044                 return rs;
1045                 
1046         case AOP_DPTR:
1047         case AOP_DPTR2:
1048                 DEBUGpic14_emitcode(";","%d",__LINE__);
1049                 if (aop->type == AOP_DPTR2)
1050                 {
1051                         genSetDPTR(1);
1052                 }
1053                 
1054                 while (offset > aop->coff) {
1055                         pic14_emitcode ("inc","dptr");
1056                         aop->coff++;
1057                 }
1058                 
1059                 while (offset < aop->coff) {            
1060                         pic14_emitcode("lcall","__decdptr");
1061                         aop->coff--;
1062                 }
1063                 
1064                 aop->coff = offset;
1065                 if (aop->code) {
1066                         pic14_emitcode("clr","a");
1067                         pic14_emitcode("movc","a,@a+dptr");
1068                 }
1069                 else {
1070                         pic14_emitcode("movx","a,@dptr");
1071                 }
1072                 
1073                 if (aop->type == AOP_DPTR2)
1074                 {
1075                         genSetDPTR(0);
1076                 }
1077                 
1078                 return (dname ? "acc" : "a");
1079                 
1080                 
1081         case AOP_IMMD:
1082                 if (bit16) 
1083                         sprintf (s,"%s",aop->aopu.aop_immd);
1084                 else
1085                         if (offset) 
1086                                 sprintf(s,"(%s >> %d)",
1087                                 aop->aopu.aop_immd,
1088                                 offset*8);
1089                         else
1090                                 sprintf(s,"%s",
1091                                 aop->aopu.aop_immd);
1092                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1093                         rs = Safe_calloc(1,strlen(s)+1);
1094                         strcpy(rs,s);   
1095                         return rs;
1096                         
1097         case AOP_DIR:
1098                 if (offset) {
1099                         sprintf(s,"(%s + %d)",
1100                                 aop->aopu.aop_dir,
1101                                 offset);
1102                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1103                 } else
1104                         sprintf(s,"%s",aop->aopu.aop_dir);
1105                 rs = Safe_calloc(1,strlen(s)+1);
1106                 strcpy(rs,s);   
1107                 return rs;
1108                 
1109         case AOP_REG:
1110                 //if (dname) 
1111                 //        return aop->aopu.aop_reg[offset]->dname;
1112                 //else
1113                 return aop->aopu.aop_reg[offset]->name;
1114                 
1115         case AOP_CRY:
1116                 //pic14_emitcode(";","%d",__LINE__);
1117                 return aop->aopu.aop_dir;
1118                 
1119         case AOP_ACC:
1120                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1121                 return "AOP_accumulator_bug";
1122                 
1123         case AOP_LIT:
1124                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1125                 rs = Safe_calloc(1,strlen(s)+1);
1126                 strcpy(rs,s);   
1127                 return rs;
1128                 
1129         case AOP_STR:
1130                 aop->coff = offset ;
1131                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1132                         dname)
1133                         return "acc";
1134                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1135                 
1136                 return aop->aopu.aop_str[offset];
1137                 
1138         case AOP_PCODE:
1139                 {
1140                         pCodeOp *pcop = aop->aopu.pcop;
1141                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1142                         if(pcop->name) {
1143                                 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1144                                 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1145                                 sprintf(s,"%s", pcop->name);
1146                         } else
1147                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1148                         
1149                 }
1150                 rs = Safe_calloc(1,strlen(s)+1);
1151                 strcpy(rs,s);   
1152                 return rs;
1153                 
1154   }
1155   
1156   werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1157           "aopget got unsupported aop->type");
1158   exit(0);
1159 }
1160
1161
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp                                  */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGetTempReg(void)
1166 {
1167         
1168         pCodeOp *pcop;
1169         
1170         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1171         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1172                 PCOR(pcop)->r->wasUsed=1;
1173                 PCOR(pcop)->r->isFree=0;
1174         }
1175         
1176         return pcop;
1177 }
1178
1179 /*-----------------------------------------------------------------*/
1180 /* popGetTempReg - create a new temporary pCodeOp                                  */
1181 /*-----------------------------------------------------------------*/
1182 void popReleaseTempReg(pCodeOp *pcop)
1183 {
1184         
1185         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1186                 PCOR(pcop)->r->isFree = 1;
1187         
1188 }
1189 /*-----------------------------------------------------------------*/
1190 /* popGetLabel - create a new pCodeOp of type PO_LABEL                     */
1191 /*-----------------------------------------------------------------*/
1192 pCodeOp *popGetLabel(unsigned int key)
1193 {
1194         
1195         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1196         
1197         if(key>(unsigned int)max_key)
1198                 max_key = key;
1199         
1200         return newpCodeOpLabel(NULL,key+100+labelOffset);
1201 }
1202
1203 /*-------------------------------------------------------------------*/
1204 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1205 /*-------------------------------------------------------------------*/
1206 pCodeOp *popGetHighLabel(unsigned int key)
1207 {
1208         pCodeOp *pcop;
1209         pcop = popGetLabel(key);
1210         PCOLAB(pcop)->offset = 1;
1211         return pcop;
1212 }
1213
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion                      */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1218 {
1219         
1220         return newpCodeOpLit(lit);
1221 }
1222
1223 /*-----------------------------------------------------------------*/
1224 /* popGetImmd - asm operator to pcode immediate conversion                 */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1227 {
1228         
1229         return newpCodeOpImmd(name, offset,index, 0, is_func);
1230 }
1231
1232
1233 /*-----------------------------------------------------------------*/
1234 /* popGet - asm operator to pcode operator conversion                      */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetWithString(char *str, int isExtern)
1237 {
1238         pCodeOp *pcop;
1239         
1240         
1241         if(!str) {
1242                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1243                 exit (1);
1244         }
1245         
1246         pcop = newpCodeOp(str,PO_STR);
1247         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1248         
1249         return pcop;
1250 }
1251
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString -                                                                                      */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1256 {
1257         
1258         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259         pcop->type = PO_DIR;
1260         
1261         DEBUGpic14_emitcode(";","%d",__LINE__);
1262         
1263         if(!str)
1264                 str = "BAD_STRING";
1265         
1266         pcop->name = Safe_calloc(1,strlen(str)+1);
1267         strcpy(pcop->name,str);
1268         
1269         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1270         
1271         PCOR(pcop)->r = dirregWithName(pcop->name);
1272         if(PCOR(pcop)->r == NULL) {
1273                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1276         } else {
1277                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1278         }
1279         PCOR(pcop)->instance = offset;
1280         
1281         return pcop;
1282 }
1283
1284 /*-----------------------------------------------------------------*/
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popRegFromIdx(int rIdx)
1287 {
1288         pCodeOp *pcop;
1289         
1290         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1291                 __FUNCTION__,__LINE__,rIdx);
1292         
1293         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1294         
1295         PCOR(pcop)->rIdx = rIdx;
1296         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1297         PCOR(pcop)->r->isFree = 0;
1298         PCOR(pcop)->r->wasUsed = 1;
1299         
1300         pcop->type = PCOR(pcop)->r->pc_type;
1301         
1302         
1303         return pcop;
1304 }
1305
1306 /*-----------------------------------------------------------------*/
1307 /* popGet - asm operator to pcode operator conversion                      */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1310 {
1311         //char *s = buffer ;
1312         //char *rs;
1313         
1314         pCodeOp *pcop;
1315         
1316         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1317         /* offset is greater than
1318         size then zero */
1319         
1320         if (offset > (aop->size - 1) &&
1321                 aop->type != AOP_LIT)
1322                 return NULL;  //zero;
1323         
1324         /* depending on type */
1325         switch (aop->type) {
1326                 
1327         case AOP_R0:
1328         case AOP_R1:
1329         case AOP_DPTR:
1330         case AOP_DPTR2:
1331         case AOP_ACC:
1332                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1333                 return NULL;
1334                 
1335         case AOP_IMMD:
1336                 DEBUGpic14_emitcode(";","%d",__LINE__);
1337                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1338                 
1339         case AOP_DIR:
1340                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1341 #if 0
1342                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1343                 pcop->type = PO_DIR;
1344                 
1345                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1346                 strcpy(pcop->name,aop->aopu.aop_dir);   
1347                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1348                 if(PCOR(pcop)->r == NULL) {
1349                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1350                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1351                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1352                 } else {
1353                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1354                 }
1355                 PCOR(pcop)->instance = offset;
1356                 
1357                 return pcop;
1358 #endif
1359                 
1360         case AOP_REG:
1361                 {
1362                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1363                         
1364                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365                         PCOR(pcop)->rIdx = rIdx;
1366                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1367                         PCOR(pcop)->r->wasUsed=1;
1368                         PCOR(pcop)->r->isFree=0;
1369                         
1370                         PCOR(pcop)->instance = offset;
1371                         pcop->type = PCOR(pcop)->r->pc_type;
1372                         //rs = aop->aopu.aop_reg[offset]->name;
1373                         DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1374                         return pcop;
1375                 }
1376                 
1377         case AOP_CRY:
1378                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1379                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1380                 //if(PCOR(pcop)->r == NULL)
1381                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1382                 return pcop;
1383                 
1384         case AOP_LIT:
1385                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1386                 
1387         case AOP_STR:
1388                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1389                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1390                 /*
1391                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1392                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1393                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1394                 pcop->type = PCOR(pcop)->r->pc_type;
1395                 pcop->name = PCOR(pcop)->r->name;
1396                 
1397                   return pcop;
1398                 */
1399                 
1400         case AOP_PCODE:
1401                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1402                         __LINE__, 
1403                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1404                 pcop = pCodeOpCopy(aop->aopu.pcop);
1405                 PCOI(pcop)->offset = offset;
1406                 return pcop;
1407         }
1408         
1409         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1410                 "popGet got unsupported aop->type");
1411         exit(0);
1412 }
1413 /*-----------------------------------------------------------------*/
1414 /* aopPut - puts a string for a aop                                                        */
1415 /*-----------------------------------------------------------------*/
1416 void aopPut (asmop *aop, char *s, int offset)
1417 {
1418         char *d = buffer ;
1419         symbol *lbl ;
1420         
1421         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1422         
1423         if (aop->size && offset > ( aop->size - 1)) {
1424                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1425                         "aopPut got offset > aop->size");
1426                 exit(0);
1427         }
1428         
1429         /* will assign value to value */
1430         /* depending on where it is ofcourse */
1431         switch (aop->type) {
1432         case AOP_DIR:
1433                 if (offset) {
1434                         sprintf(d,"(%s + %d)",
1435                                 aop->aopu.aop_dir,offset);
1436                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1437                         
1438                 } else
1439                         sprintf(d,"%s",aop->aopu.aop_dir);
1440                 
1441                 if (strcmp(d,s)) {
1442                         DEBUGpic14_emitcode(";","%d",__LINE__);
1443                         if(strcmp(s,"W"))
1444                                 pic14_emitcode("movf","%s,w",s);
1445                         pic14_emitcode("movwf","%s",d);
1446                         
1447                         if(strcmp(s,"W")) {
1448                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1449                                 if(offset >= aop->size) {
1450                                         emitpcode(POC_CLRF,popGet(aop,offset));
1451                                         break;
1452                                 } else
1453                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1454                         }
1455                         
1456                         emitpcode(POC_MOVWF,popGet(aop,offset));
1457                         
1458                         
1459                 }
1460                 break;
1461                 
1462         case AOP_REG:
1463                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1464                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1465                         /*
1466                         if (*s == '@'             ||
1467                         strcmp(s,"r0") == 0 ||
1468                         strcmp(s,"r1") == 0 ||
1469                         strcmp(s,"r2") == 0 ||
1470                         strcmp(s,"r3") == 0 ||
1471                         strcmp(s,"r4") == 0 ||
1472                         strcmp(s,"r5") == 0 ||
1473                         strcmp(s,"r6") == 0 || 
1474                         strcmp(s,"r7") == 0 )
1475                         pic14_emitcode("mov","%s,%s  ; %d",
1476                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1477                         else
1478                         */
1479                         
1480                         if(strcmp(s,"W")==0 )
1481                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1482                         
1483                         pic14_emitcode("movwf","%s",
1484                                 aop->aopu.aop_reg[offset]->name);
1485                         
1486                         if(strcmp(s,zero)==0) {
1487                                 emitpcode(POC_CLRF,popGet(aop,offset));
1488                                 
1489                         } else if(strcmp(s,"W")==0) {
1490                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1491                                 pcop->type = PO_GPR_REGISTER;
1492                                 
1493                                 PCOR(pcop)->rIdx = -1;
1494                                 PCOR(pcop)->r = NULL;
1495                                 
1496                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1497                                 pcop->name = Safe_strdup(s);
1498                                 emitpcode(POC_MOVFW,pcop);
1499                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1500                         } else if(strcmp(s,one)==0) {
1501                                 emitpcode(POC_CLRF,popGet(aop,offset));
1502                                 emitpcode(POC_INCF,popGet(aop,offset));
1503                         } else {
1504                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1505                         }
1506                 }
1507                 break;
1508                 
1509         case AOP_DPTR:
1510         case AOP_DPTR2:
1511                 
1512                 if (aop->type == AOP_DPTR2)
1513                 {
1514                         genSetDPTR(1);
1515                 }
1516                 
1517                 if (aop->code) {
1518                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1519                                 "aopPut writting to code space");
1520                         exit(0);
1521                 }
1522                 
1523                 while (offset > aop->coff) {
1524                         aop->coff++;
1525                         pic14_emitcode ("inc","dptr");
1526                 }
1527                 
1528                 while (offset < aop->coff) {
1529                         aop->coff-- ;
1530                         pic14_emitcode("lcall","__decdptr");
1531                 }
1532                 
1533                 aop->coff = offset;
1534                 
1535                 /* if not in accumulater */
1536                 MOVA(s);
1537                 
1538                 pic14_emitcode ("movx","@dptr,a");
1539                 
1540                 if (aop->type == AOP_DPTR2)
1541                 {
1542                         genSetDPTR(0);
1543                 }
1544                 break;
1545                 
1546         case AOP_R0:
1547         case AOP_R1:
1548                 while (offset > aop->coff) {
1549                         aop->coff++;
1550                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1551                 }
1552                 while (offset < aop->coff) {
1553                         aop->coff-- ;
1554                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1555                 }
1556                 aop->coff = offset;
1557                 
1558                 if (aop->paged) {
1559                         MOVA(s);                         
1560                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1561                         
1562                 } else
1563                         if (*s == '@') {
1564                                 MOVA(s);
1565                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1566                         } else
1567                                 if (strcmp(s,"r0") == 0 ||
1568                                         strcmp(s,"r1") == 0 ||
1569                                         strcmp(s,"r2") == 0 ||
1570                                         strcmp(s,"r3") == 0 ||
1571                                         strcmp(s,"r4") == 0 ||
1572                                         strcmp(s,"r5") == 0 ||
1573                                         strcmp(s,"r6") == 0 || 
1574                                         strcmp(s,"r7") == 0 ) {
1575                                         char buffer[10];
1576                                         sprintf(buffer,"a%s",s);
1577                                         pic14_emitcode("mov","@%s,%s",
1578                                                 aop->aopu.aop_ptr->name,buffer);
1579                                 } else
1580                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1581                                 
1582                                 break;
1583                                 
1584         case AOP_STK:
1585                 if (strcmp(s,"a") == 0)
1586                         pic14_emitcode("push","acc");
1587                 else
1588                         pic14_emitcode("push","%s",s);
1589                 
1590                 break;
1591                 
1592         case AOP_CRY:
1593                 /* if bit variable */
1594                 if (!aop->aopu.aop_dir) {
1595                         pic14_emitcode("clr","a");
1596                         pic14_emitcode("rlc","a");
1597                 } else {
1598                         if (s == zero) 
1599                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1600                         else
1601                                 if (s == one)
1602                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1603                                 else
1604                                         if (!strcmp(s,"c"))
1605                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1606                                         else {
1607                                                 lbl = newiTempLabel(NULL);
1608                                                 
1609                                                 if (strcmp(s,"a")) {
1610                                                         MOVA(s);
1611                                                 }
1612                                                 pic14_emitcode("clr","c");
1613                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1614                                                 pic14_emitcode("cpl","c");
1615                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1616                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1617                                         }
1618                 }
1619                 break;
1620                 
1621         case AOP_STR:
1622                 aop->coff = offset;
1623                 if (strcmp(aop->aopu.aop_str[offset],s))
1624                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1625                 break;
1626                 
1627         case AOP_ACC:
1628                 aop->coff = offset;
1629                 if (!offset && (strcmp(s,"acc") == 0))
1630                         break;
1631                 
1632                 if (strcmp(aop->aopu.aop_str[offset],s))
1633                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1634                 break;
1635                 
1636         default :
1637                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1638                         "aopPut got unsupported aop->type");
1639                 exit(0);
1640         }
1641         
1642 }
1643
1644 /*-----------------------------------------------------------------*/
1645 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1646 /*-----------------------------------------------------------------*/
1647 void mov2w (asmop *aop, int offset)
1648 {
1649         
1650         if(!aop)
1651                 return;
1652         
1653         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1654         
1655         if ( aop->type == AOP_PCODE ||
1656                 aop->type == AOP_LIT ||
1657                 aop->type == AOP_IMMD )
1658                 emitpcode(POC_MOVLW,popGet(aop,offset));
1659         else
1660                 emitpcode(POC_MOVFW,popGet(aop,offset));
1661         
1662 }
1663
1664 /*-----------------------------------------------------------------*/
1665 /* reAdjustPreg - points a register back to where it should        */
1666 /*-----------------------------------------------------------------*/
1667 static void reAdjustPreg (asmop *aop)
1668 {
1669         int size ;
1670         
1671         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1672         aop->coff = 0;
1673         if ((size = aop->size) <= 1)
1674                 return ;
1675         size-- ;
1676         switch (aop->type) {
1677         case AOP_R0 :
1678         case AOP_R1 :
1679                 while (size--)
1680                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1681                 break;                  
1682         case AOP_DPTR :
1683         case AOP_DPTR2:
1684                 if (aop->type == AOP_DPTR2)
1685                 {
1686                         genSetDPTR(1);
1687                 } 
1688                 while (size--)
1689                 {
1690                         pic14_emitcode("lcall","__decdptr");
1691                 }
1692                 
1693                 if (aop->type == AOP_DPTR2)
1694                 {
1695                         genSetDPTR(0);
1696                 }
1697                 break;
1698                 
1699         }
1700         
1701 }
1702
1703
1704 #if 0
1705 /*-----------------------------------------------------------------*/
1706 /* opIsGptr: returns non-zero if the passed operand is             */
1707 /* a generic pointer type.                                         */
1708 /*-----------------------------------------------------------------*/ 
1709 static int opIsGptr(operand *op)
1710 {
1711         sym_link *type = operandType(op);
1712         
1713         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1714         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1715         {
1716                 return 1;
1717         }
1718         return 0;          
1719 }
1720 #endif
1721
1722 /*-----------------------------------------------------------------*/
1723 /* pic14_getDataSize - get the operand data size                   */
1724 /*-----------------------------------------------------------------*/
1725 int pic14_getDataSize(operand *op)
1726 {
1727         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1728         
1729         
1730         return AOP_SIZE(op);
1731         
1732         // tsd- in the pic port, the genptr size is 1, so this code here
1733         // fails. ( in the 8051 port, the size was 4).
1734 #if 0
1735         int size;
1736         size = AOP_SIZE(op);
1737         if (size == GPTRSIZE)
1738         {
1739                 sym_link *type = operandType(op);
1740                 if (IS_GENPTR(type))
1741                 {
1742                 /* generic pointer; arithmetic operations
1743                 * should ignore the high byte (pointer type).
1744                         */
1745                         size--;
1746                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1747                 }
1748         }
1749         return size;
1750 #endif
1751 }
1752
1753 /*-----------------------------------------------------------------*/
1754 /* pic14_outAcc - output Acc                                       */
1755 /*-----------------------------------------------------------------*/
1756 void pic14_outAcc(operand *result)
1757 {
1758         int size,offset;
1759         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1760         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1761         
1762         
1763         size = pic14_getDataSize(result);
1764         if(size){
1765                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1766                 size--;
1767                 offset = 1;
1768                 /* unsigned or positive */
1769                 while(size--)
1770                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1771         }
1772         
1773 }
1774
1775 /*-----------------------------------------------------------------*/
1776 /* pic14_outBitC - output a bit C                                  */
1777 /*-----------------------------------------------------------------*/
1778 void pic14_outBitC(operand *result)
1779 {
1780         
1781         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1782         /* if the result is bit */
1783         if (AOP_TYPE(result) == AOP_CRY) 
1784                 aopPut(AOP(result),"c",0);
1785         else {
1786                 pic14_emitcode("clr","a  ; %d", __LINE__);
1787                 pic14_emitcode("rlc","a");
1788                 pic14_outAcc(result);
1789         }
1790 }
1791
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_toBoolean(operand *oper)
1796 {
1797         int size = AOP_SIZE(oper) - 1;
1798         int offset = 1;
1799         
1800         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1801         
1802         if ( AOP_TYPE(oper) != AOP_ACC) {
1803                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1804         }
1805         while (size--) {
1806                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1807         }
1808 }
1809
1810
1811 /*-----------------------------------------------------------------*/
1812 /* genNot - generate code for ! operation                          */
1813 /*-----------------------------------------------------------------*/
1814 static void genNot (iCode *ic)
1815 {
1816         symbol *tlbl;
1817         int size;
1818         
1819         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1820         /* assign asmOps to operand & result */
1821         aopOp (IC_LEFT(ic),ic,FALSE);
1822         aopOp (IC_RESULT(ic),ic,TRUE);
1823         
1824         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1825         /* if in bit space then a special case */
1826         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1827                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1828                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1829                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1830                 } else {
1831                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1832                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1833                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1834                 }
1835                 goto release;
1836         }
1837         
1838         size = AOP_SIZE(IC_LEFT(ic));
1839         if(size == 1) {
1840                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1841                 emitpcode(POC_ANDLW,popGetLit(1));
1842                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1843                 goto release;
1844         }
1845         pic14_toBoolean(IC_LEFT(ic));
1846         
1847         tlbl = newiTempLabel(NULL);
1848         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1849         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1850         pic14_outBitC(IC_RESULT(ic));
1851         
1852 release:        
1853         /* release the aops */
1854         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1855         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1856 }
1857
1858
1859 /*-----------------------------------------------------------------*/
1860 /* genCpl - generate code for complement                                                   */
1861 /*-----------------------------------------------------------------*/
1862 static void genCpl (iCode *ic)
1863 {
1864         operand *left, *result;
1865         int size, offset=0;  
1866         
1867         
1868         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1869         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1870         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1871         
1872         /* if both are in bit space then 
1873         a special case */
1874         if (AOP_TYPE(result) == AOP_CRY &&
1875                 AOP_TYPE(left) == AOP_CRY ) { 
1876                 
1877                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1878                 pic14_emitcode("cpl","c"); 
1879                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1880                 goto release; 
1881         } 
1882         
1883         size = AOP_SIZE(result);
1884         while (size--) {
1885                 
1886                 if(AOP_TYPE(left) == AOP_ACC) 
1887                         emitpcode(POC_XORLW, popGetLit(0xff));
1888                 else
1889                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1890                 
1891                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1892                 offset++;
1893         }
1894         
1895         
1896 release:
1897         /* release the aops */
1898         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899         freeAsmop(result,NULL,ic,TRUE);
1900 }
1901
1902 /*-----------------------------------------------------------------*/
1903 /* genUminusFloat - unary minus for floating points                        */
1904 /*-----------------------------------------------------------------*/
1905 static void genUminusFloat(operand *op,operand *result)
1906 {
1907         int size ,offset =0 ;
1908         char *l;
1909         
1910         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1911         /* for this we just need to flip the 
1912         first it then copy the rest in place */
1913         size = AOP_SIZE(op) - 1;
1914         l = aopGet(AOP(op),3,FALSE,FALSE);
1915         
1916         MOVA(l);          
1917         
1918         pic14_emitcode("cpl","acc.7");
1919         aopPut(AOP(result),"a",3);      
1920         
1921         while(size--) {
1922                 aopPut(AOP(result),
1923                         aopGet(AOP(op),offset,FALSE,FALSE),
1924                         offset);
1925                 offset++;
1926         }                
1927 }
1928
1929 /*-----------------------------------------------------------------*/
1930 /* genUminus - unary minus code generation                                                 */
1931 /*-----------------------------------------------------------------*/
1932 static void genUminus (iCode *ic)
1933 {
1934         int size, i;
1935         sym_link *optype, *rtype;
1936         
1937         
1938         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1939         /* assign asmops */
1940         aopOp(IC_LEFT(ic),ic,FALSE);
1941         aopOp(IC_RESULT(ic),ic,TRUE);
1942         
1943         /* if both in bit space then special
1944         case */
1945         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1946                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1947                 
1948                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
1949                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1950                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
1951                 
1952                 goto release; 
1953         } 
1954         
1955         optype = operandType(IC_LEFT(ic));
1956         rtype = operandType(IC_RESULT(ic));
1957         
1958         /* if float then do float stuff */
1959         if (IS_FLOAT(optype)) {
1960                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1961                 goto release;
1962         }
1963         
1964         /* otherwise subtract from zero by taking the 2's complement */
1965         size = AOP_SIZE(IC_LEFT(ic));
1966         
1967         for(i=0; i<size; i++) {
1968                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1969                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1970                 else {
1971                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1972                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1973                 }
1974         }
1975         
1976         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1977         for(i=1; i<size; i++) {
1978                 emitSKPNZ;
1979                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1980         }
1981         
1982 release:
1983         /* release the aops */
1984         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1985         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
1986 }
1987
1988 /*-----------------------------------------------------------------*/
1989 /* saveRegisters - will look for a call and save the registers     */
1990 /*-----------------------------------------------------------------*/
1991 static void saveRegisters(iCode *lic) 
1992 {
1993         int i;
1994         iCode *ic;
1995         bitVect *rsave;
1996         sym_link *dtype;
1997         
1998         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1999         /* look for call */
2000         for (ic = lic ; ic ; ic = ic->next) 
2001                 if (ic->op == CALL || ic->op == PCALL)
2002                         break;
2003                 
2004                 if (!ic) {
2005                         fprintf(stderr,"found parameter push with no function call\n");
2006                         return ;
2007                 }
2008                 
2009                 /* if the registers have been saved already then
2010                 do nothing */
2011                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2012                         return ;
2013                 
2014                         /* find the registers in use at this time 
2015                 and push them away to safety */
2016                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2017                         ic->rUsed);
2018                 
2019                 ic->regsSaved = 1;
2020                 if (options.useXstack) {
2021                         if (bitVectBitValue(rsave,R0_IDX))
2022                                 pic14_emitcode("mov","b,r0");
2023                         pic14_emitcode("mov","r0,%s",spname);
2024                         for (i = 0 ; i < pic14_nRegs ; i++) {
2025                                 if (bitVectBitValue(rsave,i)) {
2026                                         if (i == R0_IDX)
2027                                                 pic14_emitcode("mov","a,b");
2028                                         else
2029                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2030                                         pic14_emitcode("movx","@r0,a");
2031                                         pic14_emitcode("inc","r0");
2032                                 }
2033                         }
2034                         pic14_emitcode("mov","%s,r0",spname);
2035                         if (bitVectBitValue(rsave,R0_IDX))
2036                                 pic14_emitcode("mov","r0,b");     
2037                 }// else
2038                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2039                 //        if (bitVectBitValue(rsave,i))
2040                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2041                 //}
2042                 
2043                 dtype = operandType(IC_LEFT(ic));
2044                 if (currFunc && dtype && 
2045                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2046                         IFFUNC_ISISR(currFunc->type) &&
2047                         !ic->bankSaved) 
2048                         
2049                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2050                 
2051 }
2052 /*-----------------------------------------------------------------*/
2053 /* unsaveRegisters - pop the pushed registers                                      */
2054 /*-----------------------------------------------------------------*/
2055 static void unsaveRegisters (iCode *ic)
2056 {
2057         int i;
2058         bitVect *rsave;
2059         
2060         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2061         /* find the registers in use at this time 
2062         and push them away to safety */
2063         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2064                 ic->rUsed);
2065         
2066         if (options.useXstack) {
2067                 pic14_emitcode("mov","r0,%s",spname); 
2068                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2069                         if (bitVectBitValue(rsave,i)) {
2070                                 pic14_emitcode("dec","r0");
2071                                 pic14_emitcode("movx","a,@r0");
2072                                 if (i == R0_IDX)
2073                                         pic14_emitcode("mov","b,a");
2074                                 else
2075                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2076                         }       
2077                         
2078                 }
2079                 pic14_emitcode("mov","%s,r0",spname);
2080                 if (bitVectBitValue(rsave,R0_IDX))
2081                         pic14_emitcode("mov","r0,b");
2082         } //else
2083         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2084         //      if (bitVectBitValue(rsave,i))
2085         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2086         //}
2087         
2088 }  
2089
2090
2091 /*-----------------------------------------------------------------*/
2092 /* pushSide -                            */
2093 /*-----------------------------------------------------------------*/
2094 static void pushSide(operand * oper, int size)
2095 {
2096 #if 0
2097         int offset = 0;
2098         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2099         while (size--) {
2100                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2101                 if (AOP_TYPE(oper) != AOP_REG &&
2102                         AOP_TYPE(oper) != AOP_DIR &&
2103                         strcmp(l,"a") ) {
2104                         pic14_emitcode("mov","a,%s",l);
2105                         pic14_emitcode("push","acc");
2106                 } else
2107                         pic14_emitcode("push","%s",l);
2108         }
2109 #endif
2110 }
2111
2112 /*-----------------------------------------------------------------*/
2113 /* assignResultValue -                           */
2114 /*-----------------------------------------------------------------*/
2115 static void assignResultValue(operand * oper)
2116 {
2117         int size = AOP_SIZE(oper);
2118         
2119         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2120         
2121         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2122         
2123         while (size--) {
2124                 if (GpsuedoStkPtr++)
2125                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2126                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2127         }
2128 }
2129
2130
2131 /*-----------------------------------------------------------------*/
2132 /* genIpush - genrate code for pushing this gets a little complex  */
2133 /*-----------------------------------------------------------------*/
2134 static void genIpush (iCode *ic)
2135 {
2136         
2137         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 #if 0
2139         int size, offset = 0 ;
2140         char *l;
2141         
2142         
2143         /* if this is not a parm push : ie. it is spill push 
2144         and spill push is always done on the local stack */
2145         if (!ic->parmPush) {
2146                 
2147                 /* and the item is spilt then do nothing */
2148                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2149                         return ;
2150                 
2151                 aopOp(IC_LEFT(ic),ic,FALSE);
2152                 size = AOP_SIZE(IC_LEFT(ic));
2153                 /* push it on the stack */
2154                 while(size--) {
2155                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2156                         if (*l == '#') {
2157                                 MOVA(l);
2158                                 l = "acc";
2159                         }
2160                         pic14_emitcode("push","%s",l);
2161                 }
2162                 return ;                
2163         }
2164         
2165         /* this is a paramter push: in this case we call
2166         the routine to find the call and save those
2167         registers that need to be saved */   
2168         saveRegisters(ic);
2169         
2170         /* then do the push */
2171         aopOp(IC_LEFT(ic),ic,FALSE);
2172         
2173         
2174         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2175         size = AOP_SIZE(IC_LEFT(ic));
2176         
2177         while (size--) {
2178                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2179                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2180                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2181                         strcmp(l,"a") ) {
2182                         pic14_emitcode("mov","a,%s",l);
2183                         pic14_emitcode("push","acc");
2184                 } else
2185                         pic14_emitcode("push","%s",l);
2186         }         
2187         
2188         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2189 #endif
2190 }
2191
2192 /*-----------------------------------------------------------------*/
2193 /* genIpop - recover the registers: can happen only for spilling   */
2194 /*-----------------------------------------------------------------*/
2195 static void genIpop (iCode *ic)
2196 {
2197         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2198 #if 0
2199         int size,offset ;
2200         
2201         
2202         /* if the temp was not pushed then */
2203         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2204                 return ;
2205         
2206         aopOp(IC_LEFT(ic),ic,FALSE);
2207         size = AOP_SIZE(IC_LEFT(ic));
2208         offset = (size-1);
2209         while (size--) 
2210                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2211                 FALSE,TRUE));
2212         
2213         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2214 #endif
2215 }
2216
2217 /*-----------------------------------------------------------------*/
2218 /* unsaverbank - restores the resgister bank from stack                    */
2219 /*-----------------------------------------------------------------*/
2220 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2221 {
2222         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2223 #if 0
2224         int i;
2225         asmop *aop ;
2226         regs *r = NULL;
2227         
2228         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2229         if (popPsw) {
2230                 if (options.useXstack) {
2231                         aop = newAsmop(0);
2232                         r = getFreePtr(ic,&aop,FALSE);
2233                         
2234                         
2235                         pic14_emitcode("mov","%s,_spx",r->name);
2236                         pic14_emitcode("movx","a,@%s",r->name);
2237                         pic14_emitcode("mov","psw,a");
2238                         pic14_emitcode("dec","%s",r->name);
2239                         
2240                 }else
2241                         pic14_emitcode ("pop","psw");
2242         }
2243         
2244         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2245                 if (options.useXstack) {           
2246                         pic14_emitcode("movx","a,@%s",r->name);
2247                         //pic14_emitcode("mov","(%s+%d),a",
2248                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2249                         pic14_emitcode("dec","%s",r->name);
2250                         
2251                 } else 
2252                         pic14_emitcode("pop",""); //"(%s+%d)",
2253                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2254         }
2255         
2256         if (options.useXstack) {
2257                 
2258                 pic14_emitcode("mov","_spx,%s",r->name);
2259                 freeAsmop(NULL,aop,ic,TRUE);
2260                 
2261         }
2262 #endif 
2263 }
2264
2265 /*-----------------------------------------------------------------*/
2266 /* saverbank - saves an entire register bank on the stack                  */
2267 /*-----------------------------------------------------------------*/
2268 static void saverbank (int bank, iCode *ic, bool pushPsw)
2269 {
2270         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2271 #if 0
2272         int i;
2273         asmop *aop ;
2274         regs *r = NULL;
2275         
2276         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2277         if (options.useXstack) {
2278                 
2279                 aop = newAsmop(0);
2280                 r = getFreePtr(ic,&aop,FALSE);  
2281                 pic14_emitcode("mov","%s,_spx",r->name);
2282                 
2283         }
2284         
2285         for (i = 0 ; i < pic14_nRegs ;i++) {
2286                 if (options.useXstack) {
2287                         pic14_emitcode("inc","%s",r->name);
2288                         //pic14_emitcode("mov","a,(%s+%d)",
2289                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2290                         pic14_emitcode("movx","@%s,a",r->name);                 
2291                 } else 
2292                         pic14_emitcode("push","");// "(%s+%d)",
2293                 //regspic14[i].base,8*bank+regspic14[i].offset);
2294         }
2295         
2296         if (pushPsw) {
2297                 if (options.useXstack) {
2298                         pic14_emitcode("mov","a,psw");
2299                         pic14_emitcode("movx","@%s,a",r->name); 
2300                         pic14_emitcode("inc","%s",r->name);
2301                         pic14_emitcode("mov","_spx,%s",r->name);                 
2302                         freeAsmop (NULL,aop,ic,TRUE);
2303                         
2304                 } else
2305                         pic14_emitcode("push","psw");
2306                 
2307                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2308         }
2309         ic->bankSaved = 1;
2310 #endif
2311 }
2312
2313 /*-----------------------------------------------------------------*/
2314 /* genCall - generates a call statement                                                    */
2315 /*-----------------------------------------------------------------*/
2316 static void genCall (iCode *ic)
2317 {
2318         sym_link *dtype;         
2319         symbol *sym;
2320         unsigned char *name;
2321         int isExtern;
2322         
2323         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2324         
2325         /* if caller saves & we have not saved then */
2326         if (!ic->regsSaved)
2327                 saveRegisters(ic);
2328         
2329                 /* if we are calling a function that is not using
2330                 the same register bank then we need to save the
2331         destination registers on the stack */
2332         dtype = operandType(IC_LEFT(ic));
2333         if (currFunc && dtype && 
2334                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2335                 IFFUNC_ISISR(currFunc->type) &&
2336                 !ic->bankSaved) 
2337                 
2338                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2339         
2340         /* if send set is not empty the assign */
2341         if (_G.sendSet) {
2342                 iCode *sic;
2343                 /* For the Pic port, there is no data stack.
2344                 * So parameters passed to functions are stored
2345                 * in registers. (The pCode optimizer will get
2346                 * rid of most of these :).
2347                 */
2348                 int psuedoStkPtr=-1;
2349                 int firstTimeThruLoop = 1;
2350                 
2351                 _G.sendSet = reverseSet(_G.sendSet);
2352                 
2353                 /* First figure how many parameters are getting passed */
2354                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2355                 sic = setNextItem(_G.sendSet)) {
2356                         
2357                         aopOp(IC_LEFT(sic),sic,FALSE);
2358                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2359                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2360                 }
2361                 
2362                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2363                 sic = setNextItem(_G.sendSet)) {
2364                         int size, offset = 0;
2365                         
2366                         aopOp(IC_LEFT(sic),sic,FALSE);
2367                         size = AOP_SIZE(IC_LEFT(sic));
2368                         
2369                         while (size--) {
2370                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2371                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2372                                 
2373                                 if(!firstTimeThruLoop) {
2374                                 /* If this is not the first time we've been through the loop
2375                                 * then we need to save the parameter in a temporary
2376                                 * register. The last byte of the last parameter is
2377                                         * passed in W. */
2378                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2379                                         
2380                                 }
2381                                 firstTimeThruLoop=0;
2382                                 
2383                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2384                                 offset++;
2385                         }
2386                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2387                 }
2388                 _G.sendSet = NULL;
2389         }
2390         /* make the call */
2391         sym = OP_SYMBOL(IC_LEFT(ic));
2392         name = sym->rname[0] ? sym->rname : sym->name;
2393         isExtern = IS_EXTERN(sym->etype);
2394         if (isExtern) {
2395                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2396         }
2397         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2398         if (isExtern) {
2399                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2400         }
2401         GpsuedoStkPtr=0;
2402         /* if we need assign a result value */
2403         if ((IS_ITEMP(IC_RESULT(ic)) && 
2404                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2405                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2406                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2407                 
2408                 _G.accInUse++;
2409                 aopOp(IC_RESULT(ic),ic,FALSE);
2410                 _G.accInUse--;
2411                 
2412                 assignResultValue(IC_RESULT(ic));
2413                 
2414                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2415                         AopType(AOP_TYPE(IC_RESULT(ic))));
2416                 
2417                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2418         }
2419         
2420         /* adjust the stack for parameters if 
2421         required */
2422         if (ic->parmBytes) {
2423                 int i;
2424                 if (ic->parmBytes > 3) {
2425                         pic14_emitcode("mov","a,%s",spname);
2426                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2427                         pic14_emitcode("mov","%s,a",spname);
2428                 } else 
2429                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2430                                 pic14_emitcode("dec","%s",spname);
2431                         
2432         }
2433         
2434         /* if register bank was saved then pop them */
2435         if (ic->bankSaved)
2436                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2437         
2438         /* if we hade saved some registers then unsave them */
2439         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2440                 unsaveRegisters (ic);
2441         
2442         
2443 }
2444
2445 /*-----------------------------------------------------------------*/
2446 /* genPcall - generates a call by pointer statement                        */
2447 /*-----------------------------------------------------------------*/
2448 static void genPcall (iCode *ic)
2449 {
2450         sym_link *dtype;
2451         symbol *albl = newiTempLabel(NULL);
2452         symbol *blbl = newiTempLabel(NULL);
2453         PIC_OPCODE poc;
2454         pCodeOp *pcop;
2455         operand *left;
2456         
2457         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2458         /* if caller saves & we have not saved then */
2459         if (!ic->regsSaved)
2460                 saveRegisters(ic);
2461         
2462                 /* if we are calling a function that is not using
2463                 the same register bank then we need to save the
2464         destination registers on the stack */
2465         dtype = operandType(IC_LEFT(ic));
2466         if (currFunc && dtype && 
2467                 IFFUNC_ISISR(currFunc->type) &&
2468                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2469                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2470         
2471         left = IC_LEFT(ic);
2472         aopOp(left,ic,FALSE);
2473         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2474         
2475         pushSide(IC_LEFT(ic), FPTRSIZE);
2476         
2477         /* if send set is not empty, assign parameters */
2478         if (_G.sendSet) {
2479                 
2480                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2481                 /* no way to pass args - W always gets used to make the call */
2482         }
2483         /* first idea - factor out a common helper function and call it.
2484         But don't know how to get it generated only once in its own block
2485         
2486         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2487                 char *rname;
2488                 char *buffer;
2489                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2490                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2491                 buffer = Safe_calloc(1,strlen(rname)+16);
2492                 sprintf(buffer, "%s_goto_helper", rname);
2493                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2494                 free(buffer);
2495         }
2496         */
2497         emitpcode(POC_CALL,popGetLabel(albl->key));
2498         pcop = popGetLabel(blbl->key);
2499         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2500         emitpcode(POC_GOTO,pcop);
2501         emitpLabel(albl->key);
2502         
2503         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2504         
2505         emitpcode(poc,popGet(AOP(left),1));
2506         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2507         emitpcode(poc,popGet(AOP(left),0));
2508         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2509         
2510         emitpLabel(blbl->key);
2511         
2512         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2513         
2514         /* if we need to assign a result value */
2515         if ((IS_ITEMP(IC_RESULT(ic)) &&
2516                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2517                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2518                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2519                 
2520                 _G.accInUse++;
2521                 aopOp(IC_RESULT(ic),ic,FALSE);
2522                 _G.accInUse--;
2523                 
2524                 assignResultValue(IC_RESULT(ic));
2525                 
2526                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2527         }
2528         
2529         /* if register bank was saved then unsave them */
2530         if (currFunc && dtype && 
2531                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533         
2534                 /* if we hade saved some registers then
2535         unsave them */
2536         if (ic->regsSaved)
2537                 unsaveRegisters (ic);
2538         
2539 }
2540
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result  is rematerializable                                       */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2545 {
2546         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2547         if (SKIP_IC(ic) || ic->op == IFX)
2548                 return 0;
2549         
2550         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552                 if (sym->remat && !POINTER_SET(ic)) 
2553                         return 1;
2554         }
2555         
2556         return 0;
2557 }
2558
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2561 #else
2562 #define STRCASECMP strcasecmp
2563 #endif
2564
2565 #if 0
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2570 {
2571         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2572         int i =0;
2573         
2574         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2575         if (options.excludeRegs[i] &&
2576                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2577                 return FALSE ;
2578         
2579         for ( i = 0 ; options.excludeRegs[i]; i++) {
2580                 if (options.excludeRegs[i] &&
2581                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2582                         return TRUE;
2583         }
2584         return FALSE ;
2585 }
2586 #endif
2587
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry                                 */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2592 {
2593         symbol *sym;
2594         sym_link *ftype;
2595         
2596         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2597         
2598         labelOffset += (max_key+4);
2599         max_key=0;
2600         GpsuedoStkPtr=0;
2601         _G.nRegsSaved = 0;
2602         /* create the function header */
2603         pic14_emitcode(";","-----------------------------------------");
2604         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605         pic14_emitcode(";","-----------------------------------------");
2606         
2607         pic14_emitcode("","%s:",sym->rname);
2608         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2609         
2610         ftype = operandType(IC_LEFT(ic));
2611         
2612         /* if critical function then turn interrupts off */
2613         if (IFFUNC_ISCRITICAL(ftype))
2614                 pic14_emitcode("clr","ea");
2615         
2616                 /* here we need to generate the equates for the
2617         register bank if required */
2618 #if 0
2619         if (FUNC_REGBANK(ftype) != rbank) {
2620                 int i ;
2621                 
2622                 rbank = FUNC_REGBANK(ftype);
2623                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624                         if (strcmp(regspic14[i].base,"0") == 0)
2625                                 pic14_emitcode("","%s = 0x%02x",
2626                                 regspic14[i].dname,
2627                                 8*rbank+regspic14[i].offset);
2628                         else
2629                                 pic14_emitcode ("","%s = %s + 0x%02x",
2630                                 regspic14[i].dname,
2631                                 regspic14[i].base,
2632                                 8*rbank+regspic14[i].offset);
2633                 }
2634         }
2635 #endif
2636         
2637         /* if this is an interrupt service routine */
2638         if (IFFUNC_ISISR(sym->type)) {
2639         /*  already done in pic14createInterruptVect() - delete me
2640         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641         emitpcodeNULLop(POC_NOP);
2642         emitpcodeNULLop(POC_NOP);
2643         emitpcodeNULLop(POC_NOP);
2644                 */
2645                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2646                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2647                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2648                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2649                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2650                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2651                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2652                 
2653                 pBlockConvert2ISR(pb);
2654 #if 0  
2655                 if (!inExcludeList("acc"))              
2656                         pic14_emitcode ("push","acc");  
2657                 if (!inExcludeList("b"))
2658                         pic14_emitcode ("push","b");
2659                 if (!inExcludeList("dpl"))
2660                         pic14_emitcode ("push","dpl");
2661                 if (!inExcludeList("dph"))
2662                         pic14_emitcode ("push","dph");
2663                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2664                 {
2665                         pic14_emitcode ("push", "dpx");
2666                         /* Make sure we're using standard DPTR */
2667                         pic14_emitcode ("push", "dps");
2668                         pic14_emitcode ("mov", "dps, #0x00");
2669                         if (options.stack10bit)
2670                         { 
2671                                 /* This ISR could conceivably use DPTR2. Better save it. */
2672                                 pic14_emitcode ("push", "dpl1");
2673                                 pic14_emitcode ("push", "dph1");
2674                                 pic14_emitcode ("push", "dpx1");
2675                         }
2676                 }
2677                 /* if this isr has no bank i.e. is going to
2678                 run with bank 0 , then we need to save more
2679 registers :-) */
2680                 if (!FUNC_REGBANK(sym->type)) {
2681                         
2682                 /* if this function does not call any other
2683                 function then we can be economical and
2684                         save only those registers that are used */
2685                         if (! IFFUNC_HASFCALL(sym->type)) {
2686                                 int i;
2687                                 
2688                                 /* if any registers used */
2689                                 if (sym->regsUsed) {
2690                                         /* save the registers used */
2691                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2692                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2693                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2694                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2695                                         }
2696                                 }
2697                                 
2698                         } else {
2699                         /* this function has    a function call cannot
2700                         determines register usage so we will have the
2701                                 entire bank */
2702                                 saverbank(0,ic,FALSE);
2703                         }       
2704                 }
2705 #endif
2706         } else {
2707         /* if callee-save to be used for this function
2708                 then save the registers being used in this function */
2709                 if (IFFUNC_CALLEESAVES(sym->type)) {
2710                         int i;
2711                         
2712                         /* if any registers used */
2713                         if (sym->regsUsed) {
2714                                 /* save the registers used */
2715                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2716                                         if (bitVectBitValue(sym->regsUsed,i) ||
2717                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2718                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2719                                                 _G.nRegsSaved++;
2720                                         }
2721                                 }
2722                         }
2723                 }
2724         }
2725         
2726         /* set the register bank to the desired value */
2727         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2728                 pic14_emitcode("push","psw");
2729                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2730         }
2731         
2732         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2733                 
2734                 if (options.useXstack) {
2735                         pic14_emitcode("mov","r0,%s",spname);
2736                         pic14_emitcode("mov","a,_bp");
2737                         pic14_emitcode("movx","@r0,a");
2738                         pic14_emitcode("inc","%s",spname);
2739                 }
2740                 else
2741                 {
2742                         /* set up the stack */
2743                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2744                 }
2745                 pic14_emitcode ("mov","_bp,%s",spname);
2746         }
2747         
2748         /* adjust the stack for the function */
2749         if (sym->stack) {
2750                 
2751                 int i = sym->stack;
2752                 if (i > 256 ) 
2753                         werror(W_STACK_OVERFLOW,sym->name);
2754                 
2755                 if (i > 3 && sym->recvSize < 4) {                
2756                         
2757                         pic14_emitcode ("mov","a,sp");
2758                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2759                         pic14_emitcode ("mov","sp,a");
2760                         
2761                 }
2762                 else
2763                         while(i--)
2764                                 pic14_emitcode("inc","sp");
2765         }
2766         
2767         if (sym->xstack) {
2768                 
2769                 pic14_emitcode ("mov","a,_spx");
2770                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2771                 pic14_emitcode ("mov","_spx,a");
2772         }
2773         
2774 }
2775
2776 /*-----------------------------------------------------------------*/
2777 /* genEndFunction - generates epilogue for functions                       */
2778 /*-----------------------------------------------------------------*/
2779 static void genEndFunction (iCode *ic)
2780 {
2781         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2782         
2783         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2784         
2785         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2786         {
2787                 pic14_emitcode ("mov","%s,_bp",spname);
2788         }
2789         
2790         /* if use external stack but some variables were
2791         added to the local stack then decrement the
2792         local stack */
2793         if (options.useXstack && sym->stack) {    
2794                 pic14_emitcode("mov","a,sp");
2795                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2796                 pic14_emitcode("mov","sp,a");
2797         }
2798         
2799         
2800         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2801                 if (options.useXstack) {
2802                         pic14_emitcode("mov","r0,%s",spname);
2803                         pic14_emitcode("movx","a,@r0");
2804                         pic14_emitcode("mov","_bp,a");
2805                         pic14_emitcode("dec","%s",spname);
2806                 }
2807                 else
2808                 {
2809                         pic14_emitcode ("pop","_bp");
2810                 }
2811         }
2812         
2813         /* restore the register bank    */        
2814         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2815                 pic14_emitcode ("pop","psw");
2816         
2817         if (IFFUNC_ISISR(sym->type)) {
2818                 
2819                 /* now we need to restore the registers */
2820                 /* if this isr has no bank i.e. is going to
2821                 run with bank 0 , then we need to save more
2822 registers :-) */
2823                 if (!FUNC_REGBANK(sym->type)) {
2824                         
2825                 /* if this function does not call any other
2826                 function then we can be economical and
2827                         save only those registers that are used */
2828                         if (! IFFUNC_HASFCALL(sym->type)) {
2829                                 int i;
2830                                 
2831                                 /* if any registers used */
2832                                 if (sym->regsUsed) {
2833                                         /* save the registers used */
2834                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2835                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2836                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2837                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2838                                         }
2839                                 }
2840                                 
2841                         } else {
2842                         /* this function has    a function call cannot
2843                         determines register usage so we will have the
2844                                 entire bank */
2845                                 unsaverbank(0,ic,FALSE);
2846                         }       
2847                 }
2848 #if 0
2849                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2850                 {
2851                         if (options.stack10bit)
2852                         {
2853                                 pic14_emitcode ("pop", "dpx1");
2854                                 pic14_emitcode ("pop", "dph1");
2855                                 pic14_emitcode ("pop", "dpl1");
2856                         } 
2857                         pic14_emitcode ("pop", "dps");
2858                         pic14_emitcode ("pop", "dpx");
2859                 }
2860                 if (!inExcludeList("dph"))
2861                         pic14_emitcode ("pop","dph");
2862                 if (!inExcludeList("dpl"))
2863                         pic14_emitcode ("pop","dpl");
2864                 if (!inExcludeList("b"))
2865                         pic14_emitcode ("pop","b");
2866                 if (!inExcludeList("acc"))
2867                         pic14_emitcode ("pop","acc");
2868                 
2869                 if (IFFUNC_ISCRITICAL(sym->type))
2870                         pic14_emitcode("setb","ea");
2871 #endif
2872                 
2873                 /* if debug then send end of function */
2874                 /*      if (options.debug && currFunc) { */
2875                 if (currFunc) {
2876                         debugFile->writeEndFunction (currFunc, ic, 1);
2877                 }
2878                 
2879                 pic14_emitcode ("reti","");
2880                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2881                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2882                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2883                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2884                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2885                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2886                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2887                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2888                 emitpcodeNULLop(POC_RETFIE);
2889         }
2890         else {
2891                 if (IFFUNC_ISCRITICAL(sym->type))
2892                         pic14_emitcode("setb","ea");
2893                 
2894                 if (IFFUNC_CALLEESAVES(sym->type)) {
2895                         int i;
2896                         
2897                         /* if any registers used */
2898                         if (sym->regsUsed) {
2899                                 /* save the registers used */
2900                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2901                                         if (bitVectBitValue(sym->regsUsed,i) ||
2902                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2903                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2904                                 }
2905                         }
2906                         
2907                 }
2908                 
2909                 /* if debug then send end of function */
2910                 if (currFunc) {
2911                         debugFile->writeEndFunction (currFunc, ic, 1);
2912                 }
2913                 
2914                 pic14_emitcode ("return","");
2915                 emitpcodeNULLop(POC_RETURN);
2916                 
2917                 /* Mark the end of a function */
2918                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2919         }
2920         
2921 }
2922
2923 /*-----------------------------------------------------------------*/
2924 /* genRet - generate code for return statement                                     */
2925 /*-----------------------------------------------------------------*/
2926 static void genRet (iCode *ic)
2927 {
2928         int size, pushed = 0;
2929         
2930         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2931         /* if we have no return value then
2932         just generate the "ret" */
2933         if (!IC_LEFT(ic)) 
2934                 goto jumpret;           
2935         
2936         /* we have something to return then
2937         move the return value into place */
2938         aopOp(IC_LEFT(ic),ic,FALSE);
2939         size = AOP_SIZE(IC_LEFT(ic));
2940         
2941         while (size--) {
2942                 char *l ;
2943                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2944                         /* #NOCHANGE */
2945                         l = aopGet(AOP(IC_LEFT(ic)),size,FALSE,TRUE);
2946                         pic14_emitcode("push","%s",l);
2947                         pushed++;
2948                 } else {
2949                         l = aopGet(AOP(IC_LEFT(ic)),size,FALSE,FALSE);
2950                         if (strcmp(fReturn[size],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)),size));
2956                                 }else {
2957                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),size));
2958                                 }
2959                                 if(size) {
2960                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2961                                 }
2962                         }
2963                 }
2964         }
2965         
2966         if (pushed) {
2967                 while(pushed) {
2968                         pushed--;
2969                         if (strcmp(fReturn[pushed],"a"))
2970                                 pic14_emitcode("pop",fReturn[pushed]);
2971                         else
2972                                 pic14_emitcode("pop","acc");
2973                 }
2974         }
2975         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2976         
2977 jumpret:
2978         /* generate a jump to the return label
2979         if the next is not the return statement */
2980         if (!(ic->next && ic->next->op == LABEL &&
2981                 IC_LABEL(ic->next) == returnLabel)) {
2982                 
2983                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2984                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2985         }
2986         
2987 }
2988
2989 /*-----------------------------------------------------------------*/
2990 /* genLabel - generates a label                                                                    */
2991 /*-----------------------------------------------------------------*/
2992 static void genLabel (iCode *ic)
2993 {
2994         /* special case never generate */
2995         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2996         if (IC_LABEL(ic) == entryLabel)
2997                 return ;
2998         
2999         emitpLabel(IC_LABEL(ic)->key);
3000         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3001 }
3002
3003 /*-----------------------------------------------------------------*/
3004 /* genGoto - generates a goto                                                                      */
3005 /*-----------------------------------------------------------------*/
3006 //tsd
3007 static void genGoto (iCode *ic)
3008 {
3009         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3010         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3011 }
3012
3013
3014 /*-----------------------------------------------------------------*/
3015 /* genMultbits :- multiplication of bits                                                   */
3016 /*-----------------------------------------------------------------*/
3017 static void genMultbits (operand *left, 
3018                                                  operand *right, 
3019                                                  operand *result)
3020 {
3021         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3022         
3023         if(!pic14_sameRegs(AOP(result),AOP(right)))
3024                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3025         
3026         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3027         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3028         emitpcode(POC_BCF,  popGet(AOP(result),0));
3029         
3030 }
3031
3032
3033 /*-----------------------------------------------------------------*/
3034 /* genMultOneByte : 8 bit multiplication & division                        */
3035 /*-----------------------------------------------------------------*/
3036 static void genMultOneByte (operand *left,
3037                                                         operand *right,
3038                                                         operand *result)
3039 {
3040         sym_link *opetype = operandType(result);
3041         
3042         // symbol *lbl ;
3043         int size,offset;
3044         
3045         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3046         DEBUGpic14_AopType(__LINE__,left,right,result);
3047         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3048         
3049         /* (if two literals, the value is computed before) */
3050         /* if one literal, literal on the right */
3051         if (AOP_TYPE(left) == AOP_LIT){
3052                 operand *t = right;
3053                 right = left;
3054                 left = t;
3055         }
3056         
3057         size = AOP_SIZE(result);
3058         if(size == 1) {
3059                 
3060                 if (AOP_TYPE(right) == AOP_LIT){
3061                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3062                                 aopGet(AOP(right),0,FALSE,FALSE), 
3063                                 aopGet(AOP(left),0,FALSE,FALSE), 
3064                                 aopGet(AOP(result),0,FALSE,FALSE));
3065                         pic14_emitcode("call","genMultLit");
3066                 } else {
3067                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3068                                 aopGet(AOP(right),0,FALSE,FALSE), 
3069                                 aopGet(AOP(left),0,FALSE,FALSE), 
3070                                 aopGet(AOP(result),0,FALSE,FALSE));
3071                         pic14_emitcode("call","genMult8X8_8");
3072                         
3073                 }
3074                 genMult8X8_8 (left, right,result);
3075                 
3076                 
3077                 /* signed or unsigned */
3078                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3079                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3080                 //MOVA(l);               
3081                 //pic14_emitcode("mul","ab");
3082                 /* if result size = 1, mul signed = mul unsigned */
3083                 //aopPut(AOP(result),"a",0);
3084                 
3085         } else {        // (size > 1)
3086                 
3087                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3088                         aopGet(AOP(right),0,FALSE,FALSE), 
3089                         aopGet(AOP(left),0,FALSE,FALSE), 
3090                         aopGet(AOP(result),0,FALSE,FALSE));
3091                 
3092                 if (SPEC_USIGN(opetype)){
3093                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3094                         genUMult8X8_16 (left, right, result, NULL);
3095                         
3096                         if (size > 2) {
3097                                 /* for filling the MSBs */
3098                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3099                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3100                         }
3101                 }
3102                 else{
3103                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3104                         
3105                         pic14_emitcode("mov","a,b");
3106                         
3107                         /* adjust the MSB if left or right neg */
3108                         
3109                         /* if one literal */
3110                         if (AOP_TYPE(right) == AOP_LIT){
3111                                 pic14_emitcode("multiply ","right is a lit");
3112                                 /* AND literal negative */
3113                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3114                                         /* adjust MSB (c==0 after mul) */
3115                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3116                                 }
3117                         }
3118                         else{
3119                                 genSMult8X8_16 (left, right, result, NULL);
3120                         }
3121                         
3122                         if(size > 2){
3123                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3124                                 /* get the sign */
3125                                 pic14_emitcode("rlc","a");
3126                                 pic14_emitcode("subb","a,acc");
3127                         }
3128                 }
3129                 
3130                 size -= 2;
3131                 offset = 2;
3132                 if (size > 0)
3133                         while (size--)
3134                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3135                         //aopPut(AOP(result),"a",offset++);
3136         }
3137 }
3138
3139 /*-----------------------------------------------------------------*/
3140 /* genMult - generates code for multiplication                                     */
3141 /*-----------------------------------------------------------------*/
3142 static void genMult (iCode *ic)
3143 {
3144         operand *left = IC_LEFT(ic);
3145         operand *right = IC_RIGHT(ic);
3146         operand *result= IC_RESULT(ic); 
3147         
3148         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3149         /* assign the amsops */
3150         aopOp (left,ic,FALSE);
3151         aopOp (right,ic,FALSE);
3152         aopOp (result,ic,TRUE);
3153         
3154         DEBUGpic14_AopType(__LINE__,left,right,result);
3155         
3156         /* special cases first */
3157         /* both are bits */
3158         if (AOP_TYPE(left) == AOP_CRY &&
3159                 AOP_TYPE(right)== AOP_CRY) {
3160                 genMultbits(left,right,result);
3161                 goto release ;
3162         }
3163         
3164         /* if both are of size == 1 */
3165         if (AOP_SIZE(left) == 1 &&
3166                 AOP_SIZE(right) == 1 ) {
3167                 genMultOneByte(left,right,result);
3168                 goto release ;
3169         }
3170         
3171         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3172         
3173         /* should have been converted to function call */
3174         //assert(0) ;
3175         
3176 release :
3177         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3178         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3179         freeAsmop(result,NULL,ic,TRUE); 
3180 }
3181
3182 /*-----------------------------------------------------------------*/
3183 /* genDivbits :- division of bits                                                                  */
3184 /*-----------------------------------------------------------------*/
3185 static void genDivbits (operand *left, 
3186                                                 operand *right, 
3187                                                 operand *result)
3188 {
3189         
3190         char *l;
3191         
3192         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3193         /* the result must be bit */      
3194         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3195         l = aopGet(AOP(left),0,FALSE,FALSE);
3196         
3197         MOVA(l);          
3198         
3199         pic14_emitcode("div","ab");
3200         pic14_emitcode("rrc","a");
3201         aopPut(AOP(result),"c",0);
3202 }
3203
3204 /*-----------------------------------------------------------------*/
3205 /* genDivOneByte : 8 bit division                                                                  */
3206 /*-----------------------------------------------------------------*/
3207 static void genDivOneByte (operand *left,
3208                                                    operand *right,
3209                                                    operand *result)
3210 {
3211         sym_link *opetype = operandType(result);
3212         char *l ;
3213         symbol *lbl ;
3214         int size,offset;
3215         
3216         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3217         size = AOP_SIZE(result) - 1;
3218         offset = 1;
3219         /* signed or unsigned */
3220         if (SPEC_USIGN(opetype)) {
3221                 /* unsigned is easy */
3222                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3223                 l = aopGet(AOP(left),0,FALSE,FALSE);
3224                 MOVA(l);                
3225                 pic14_emitcode("div","ab");
3226                 aopPut(AOP(result),"a",0);
3227                 while (size--)
3228                         aopPut(AOP(result),zero,offset++);
3229                 return ;
3230         }
3231         
3232         /* signed is a little bit more difficult */
3233         
3234         /* save the signs of the operands */
3235         l = aopGet(AOP(left),0,FALSE,FALSE);      
3236         MOVA(l);          
3237         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3238         pic14_emitcode("push","acc"); /* save it on the stack */
3239         
3240         /* now sign adjust for both left & right */
3241         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3242         MOVA(l);                 
3243         lbl = newiTempLabel(NULL);
3244         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3245         pic14_emitcode("cpl","a");   
3246         pic14_emitcode("inc","a");
3247         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3248         pic14_emitcode("mov","b,a");
3249         
3250         /* sign adjust left side */
3251         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3252         MOVA(l);
3253         
3254         lbl = newiTempLabel(NULL);
3255         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3256         pic14_emitcode("cpl","a");
3257         pic14_emitcode("inc","a");
3258         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3259         
3260         /* now the division */
3261         pic14_emitcode("div","ab");
3262         /* we are interested in the lower order
3263         only */
3264         pic14_emitcode("mov","b,a");
3265         lbl = newiTempLabel(NULL);
3266         pic14_emitcode("pop","acc");     
3267         /* if there was an over flow we don't 
3268         adjust the sign of the result */
3269         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3270         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3271         CLRC;
3272         pic14_emitcode("clr","a");
3273         pic14_emitcode("subb","a,b");
3274         pic14_emitcode("mov","b,a");
3275         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3276         
3277         /* now we are done */
3278         aopPut(AOP(result),"b",0);
3279         if(size > 0){
3280                 pic14_emitcode("mov","c,b.7");
3281                 pic14_emitcode("subb","a,acc");   
3282         }
3283         while (size--)
3284                 aopPut(AOP(result),"a",offset++);
3285         
3286 }
3287
3288 /*-----------------------------------------------------------------*/
3289 /* genDiv - generates code for division                                                    */
3290 /*-----------------------------------------------------------------*/
3291 static void genDiv (iCode *ic)
3292 {
3293         operand *left = IC_LEFT(ic);
3294         operand *right = IC_RIGHT(ic);
3295         operand *result= IC_RESULT(ic); 
3296         
3297         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3298         /* assign the amsops */
3299         aopOp (left,ic,FALSE);
3300         aopOp (right,ic,FALSE);
3301         aopOp (result,ic,TRUE);
3302         
3303         /* special cases first */
3304         /* both are bits */
3305         if (AOP_TYPE(left) == AOP_CRY &&
3306                 AOP_TYPE(right)== AOP_CRY) {
3307                 genDivbits(left,right,result);
3308                 goto release ;
3309         }
3310         
3311         /* if both are of size == 1 */
3312         if (AOP_SIZE(left) == 1 &&
3313                 AOP_SIZE(right) == 1 ) {
3314                 genDivOneByte(left,right,result);
3315                 goto release ;
3316         }
3317         
3318         /* should have been converted to function call */
3319         assert(0);
3320 release :
3321         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3322         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3323         freeAsmop(result,NULL,ic,TRUE); 
3324 }
3325
3326 /*-----------------------------------------------------------------*/
3327 /* genModbits :- modulus of bits                                                                   */
3328 /*-----------------------------------------------------------------*/
3329 static void genModbits (operand *left, 
3330                                                 operand *right, 
3331                                                 operand *result)
3332 {
3333         
3334         char *l;
3335         
3336         /* the result must be bit */      
3337         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3338         l = aopGet(AOP(left),0,FALSE,FALSE);
3339         
3340         MOVA(l);
3341         
3342         pic14_emitcode("div","ab");
3343         pic14_emitcode("mov","a,b");
3344         pic14_emitcode("rrc","a");
3345         aopPut(AOP(result),"c",0);
3346 }
3347
3348 /*-----------------------------------------------------------------*/
3349 /* genModOneByte : 8 bit modulus                                                                   */
3350 /*-----------------------------------------------------------------*/
3351 static void genModOneByte (operand *left,
3352                                                    operand *right,
3353                                                    operand *result)
3354 {
3355         sym_link *opetype = operandType(result);
3356         char *l ;
3357         symbol *lbl ;
3358         
3359         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3360         /* signed or unsigned */
3361         if (SPEC_USIGN(opetype)) {
3362                 /* unsigned is easy */
3363                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3364                 l = aopGet(AOP(left),0,FALSE,FALSE);
3365                 MOVA(l);        
3366                 pic14_emitcode("div","ab");
3367                 aopPut(AOP(result),"b",0);
3368                 return ;
3369         }
3370         
3371         /* signed is a little bit more difficult */
3372         
3373         /* save the signs of the operands */
3374         l = aopGet(AOP(left),0,FALSE,FALSE);      
3375         MOVA(l);
3376         
3377         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3378         pic14_emitcode("push","acc"); /* save it on the stack */
3379         
3380         /* now sign adjust for both left & right */
3381         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3382         MOVA(l);
3383         
3384         lbl = newiTempLabel(NULL);
3385         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3386         pic14_emitcode("cpl","a");   
3387         pic14_emitcode("inc","a");
3388         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3389         pic14_emitcode("mov","b,a"); 
3390         
3391         /* sign adjust left side */
3392         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3393         MOVA(l);
3394         
3395         lbl = newiTempLabel(NULL);
3396         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3397         pic14_emitcode("cpl","a");   
3398         pic14_emitcode("inc","a");
3399         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3400         
3401         /* now the multiplication */
3402         pic14_emitcode("div","ab");
3403         /* we are interested in the lower order
3404         only */
3405         lbl = newiTempLabel(NULL);
3406         pic14_emitcode("pop","acc");     
3407         /* if there was an over flow we don't 
3408         adjust the sign of the result */
3409         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3410         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3411         CLRC ;
3412         pic14_emitcode("clr","a");
3413         pic14_emitcode("subb","a,b");
3414         pic14_emitcode("mov","b,a");
3415         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3416         
3417         /* now we are done */
3418         aopPut(AOP(result),"b",0);
3419         
3420 }
3421
3422 /*-----------------------------------------------------------------*/
3423 /* genMod - generates code for division                                                    */
3424 /*-----------------------------------------------------------------*/
3425 static void genMod (iCode *ic)
3426 {
3427         operand *left = IC_LEFT(ic);
3428         operand *right = IC_RIGHT(ic);
3429         operand *result= IC_RESULT(ic);  
3430         
3431         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3432         /* assign the amsops */
3433         aopOp (left,ic,FALSE);
3434         aopOp (right,ic,FALSE);
3435         aopOp (result,ic,TRUE);
3436         
3437         /* special cases first */
3438         /* both are bits */
3439         if (AOP_TYPE(left) == AOP_CRY &&
3440                 AOP_TYPE(right)== AOP_CRY) {
3441                 genModbits(left,right,result);
3442                 goto release ;
3443         }
3444         
3445         /* if both are of size == 1 */
3446         if (AOP_SIZE(left) == 1 &&
3447                 AOP_SIZE(right) == 1 ) {
3448                 genModOneByte(left,right,result);
3449                 goto release ;
3450         }
3451         
3452         /* should have been converted to function call */
3453         assert(0);
3454         
3455 release :
3456         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3457         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3458         freeAsmop(result,NULL,ic,TRUE); 
3459 }
3460
3461 /*-----------------------------------------------------------------*/
3462 /* genIfxJump :- will create a jump depending on the ifx                   */
3463 /*-----------------------------------------------------------------*/
3464 /*
3465 note: May need to add parameter to indicate when a variable is in bit space.
3466 */
3467 static void genIfxJump (iCode *ic, char *jval)
3468 {
3469         
3470         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3471         /* if true label then we jump if condition
3472         supplied is true */
3473         if ( IC_TRUE(ic) ) {
3474                 
3475                 if(strcmp(jval,"a") == 0)
3476                         emitSKPZ;
3477                 else if (strcmp(jval,"c") == 0)
3478                         emitSKPC;
3479                 else {
3480                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3481                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3482                 }
3483                 
3484                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3485                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3486                 
3487         }
3488         else {
3489                 /* false label is present */
3490                 if(strcmp(jval,"a") == 0)
3491                         emitSKPNZ;
3492                 else if (strcmp(jval,"c") == 0)
3493                         emitSKPNC;
3494                 else {
3495                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3496                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3497                 }
3498                 
3499                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3500                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3501                 
3502         }
3503         
3504         
3505         /* mark the icode as generated */
3506         ic->generated = 1;
3507 }
3508
3509 /*-----------------------------------------------------------------*/
3510 /* genSkip                                                                                                                 */
3511 /*-----------------------------------------------------------------*/
3512 static void genSkip(iCode *ifx,int status_bit)
3513 {
3514         if(!ifx)
3515                 return;
3516         
3517         if ( IC_TRUE(ifx) ) {
3518                 switch(status_bit) {
3519                 case 'z':
3520                         emitSKPNZ;
3521                         break;
3522                         
3523                 case 'c':
3524                         emitSKPNC;
3525                         break;
3526                         
3527                 case 'd':
3528                         emitSKPDC;
3529                         break;
3530                         
3531                 }
3532                 
3533                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3534                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3535                 
3536         } else {
3537                 
3538                 switch(status_bit) {
3539                         
3540                 case 'z':
3541                         emitSKPZ;
3542                         break;
3543                         
3544                 case 'c':
3545                         emitSKPC;
3546                         break;
3547                         
3548                 case 'd':
3549                         emitSKPDC;
3550                         break;
3551                 }
3552                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3553                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3554                 
3555         }
3556         
3557 }
3558
3559 /*-----------------------------------------------------------------*/
3560 /* genSkipc                                                                                                        */
3561 /*-----------------------------------------------------------------*/
3562 static void genSkipc(resolvedIfx *rifx)
3563 {
3564         if(!rifx)
3565                 return;
3566         
3567         if(rifx->condition)
3568                 emitSKPC;
3569         else
3570                 emitSKPNC;
3571         
3572         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3573         rifx->generated = 1;
3574 }
3575
3576 /*-----------------------------------------------------------------*/
3577 /* genSkipz2                                                                                                       */
3578 /*-----------------------------------------------------------------*/
3579 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3580 {
3581         if(!rifx)
3582                 return;
3583         
3584         if( (rifx->condition ^ invert_condition) & 1)
3585                 emitSKPZ;
3586         else
3587                 emitSKPNZ;
3588         
3589         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3590         rifx->generated = 1;
3591 }
3592
3593 /*-----------------------------------------------------------------*/
3594 /* genSkipz                                                        */
3595 /*-----------------------------------------------------------------*/
3596 static void genSkipz(iCode *ifx, int condition)
3597 {
3598         if(!ifx)
3599                 return;
3600         
3601         if(condition)
3602                 emitSKPNZ;
3603         else
3604                 emitSKPZ;
3605         
3606         if ( IC_TRUE(ifx) )
3607                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3608         else
3609                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3610         
3611         if ( IC_TRUE(ifx) )
3612                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3613         else
3614                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3615         
3616 }
3617 /*-----------------------------------------------------------------*/
3618 /* genSkipCond                                                     */
3619 /*-----------------------------------------------------------------*/
3620 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3621 {
3622         if(!rifx)
3623                 return;
3624         
3625         if(rifx->condition)
3626                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3627         else
3628                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3629         
3630         
3631         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3632         rifx->generated = 1;
3633 }
3634
3635 #if 0
3636 /*-----------------------------------------------------------------*/
3637 /* genChkZeroes :- greater or less than comparison                 */
3638 /*     For each byte in a literal that is zero, inclusive or the   */
3639 /*     the corresponding byte in the operand with W                */
3640 /*     returns true if any of the bytes are zero                   */
3641 /*-----------------------------------------------------------------*/
3642 static int genChkZeroes(operand *op, int lit,  int size)
3643 {
3644         
3645         int i;
3646         int flag =1;
3647         
3648         while(size--) {
3649                 i = (lit >> (size*8)) & 0xff;
3650                 
3651                 if(i==0) {
3652                         if(flag) 
3653                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3654                         else
3655                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3656                         flag = 0;
3657                 }
3658         }
3659         
3660         return (flag==0);
3661 }
3662 #endif
3663
3664 /*-----------------------------------------------------------------*/
3665 /* genCmp :- greater or less than comparison                       */
3666 /*-----------------------------------------------------------------*/
3667 static void genCmp (operand *left,operand *right,
3668                                         operand *result, iCode *ifx, int sign)
3669 {
3670         int size; //, offset = 0 ;
3671         unsigned long lit = 0L,i = 0;
3672         resolvedIfx rFalseIfx;
3673         //  resolvedIfx rTrueIfx;
3674         symbol *truelbl;
3675         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3676         /*
3677         if(ifx) {
3678         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3679         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3680         }
3681         */
3682         
3683         resolveIfx(&rFalseIfx,ifx);
3684         truelbl  = newiTempLabel(NULL);
3685         size = max(AOP_SIZE(left),AOP_SIZE(right));
3686         
3687         DEBUGpic14_AopType(__LINE__,left,right,result);
3688         
3689 #define _swapp
3690         
3691         /* if literal is on the right then swap with left */
3692         if ((AOP_TYPE(right) == AOP_LIT)) {
3693                 operand *tmp = right ;
3694                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3695                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3696 #ifdef _swapp
3697                 
3698                 lit = (lit - 1) & mask;
3699                 right = left;
3700                 left = tmp;
3701                 rFalseIfx.condition ^= 1;
3702 #endif
3703                 
3704         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3705                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3706         }
3707         
3708         
3709         //if(IC_TRUE(ifx) == NULL)
3710         /* if left & right are bit variables */
3711         if (AOP_TYPE(left) == AOP_CRY &&
3712                 AOP_TYPE(right) == AOP_CRY ) {
3713                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3714                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3715         } else {
3716         /* subtract right from left if at the
3717         end the carry flag is set then we know that
3718                 left is greater than right */
3719                 
3720                 symbol *lbl  = newiTempLabel(NULL);
3721                 
3722 #ifndef _swapp
3723                 if(AOP_TYPE(right) == AOP_LIT) {
3724                         
3725                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3726                         
3727                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3728                         
3729                         /* special cases */
3730                         
3731                         if(lit == 0) {
3732                                 
3733                                 if(sign != 0) 
3734                                         genSkipCond(&rFalseIfx,left,size-1,7);
3735                                 else 
3736                                         /* no need to compare to 0...*/
3737                                         /* NOTE: this is a de-generate compare that most certainly 
3738                                         *       creates some dead code. */
3739                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3740                                 
3741                                 if(ifx) ifx->generated = 1;
3742                                 return;
3743                                 
3744                         }
3745                         size--;
3746                         
3747                         if(size == 0) {
3748                                 //i = (lit >> (size*8)) & 0xff;
3749                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3750                                 
3751                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3752                                 
3753                                 i = ((0-lit) & 0xff);
3754                                 if(sign) {
3755                                         if( i == 0x81) { 
3756                                         /* lit is 0x7f, all signed chars are less than
3757                                                 * this except for 0x7f itself */
3758                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3759                                                 genSkipz2(&rFalseIfx,0);
3760                                         } else {
3761                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3762                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3763                                                 genSkipc(&rFalseIfx);
3764                                         }
3765                                         
3766                                 } else {
3767                                         if(lit == 1) {
3768                                                 genSkipz2(&rFalseIfx,1);
3769                                         } else {
3770                                                 emitpcode(POC_ADDLW, popGetLit(i));
3771                                                 genSkipc(&rFalseIfx);
3772                                         }
3773                                 }
3774                                 
3775                                 if(ifx) ifx->generated = 1;
3776                                 return;
3777                         }
3778                         
3779                         /* chars are out of the way. now do ints and longs */
3780                         
3781                         
3782                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3783                         
3784                         /* special cases */
3785                         
3786                         if(sign) {
3787                                 
3788                                 if(lit == 0) {
3789                                         genSkipCond(&rFalseIfx,left,size,7);
3790                                         if(ifx) ifx->generated = 1;
3791                                         return;
3792                                 }
3793                                 
3794                                 if(lit <0x100) {
3795                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3796                                         
3797                                         //rFalseIfx.condition ^= 1;
3798                                         //genSkipCond(&rFalseIfx,left,size,7);
3799                                         //rFalseIfx.condition ^= 1;
3800                                         
3801                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3802                                         if(rFalseIfx.condition)
3803                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3804                                         else
3805                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3806                                         
3807                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3808                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3809                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3810                                         
3811                                         while(size > 1)
3812                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3813                                         
3814                                         if(rFalseIfx.condition) {
3815                                                 emitSKPZ;
3816                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3817                                                 
3818                                         } else {
3819                                                 emitSKPNZ;
3820                                         }
3821                                         
3822                                         genSkipc(&rFalseIfx);
3823                                         emitpLabel(truelbl->key);
3824                                         if(ifx) ifx->generated = 1;
3825                                         return;
3826                                         
3827                                 }
3828                                 
3829                                 if(size == 1) {
3830                                         
3831                                         if( (lit & 0xff) == 0) {
3832                                                 /* lower byte is zero */
3833                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3834                                                 i = ((lit >> 8) & 0xff) ^0x80;
3835                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3836                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3837                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3838                                                 genSkipc(&rFalseIfx);
3839                                                 
3840                                                 
3841                                                 if(ifx) ifx->generated = 1;
3842                                                 return;
3843                                                 
3844                                         }
3845                                 } else {
3846                                         /* Special cases for signed longs */
3847                                         if( (lit & 0xffffff) == 0) {
3848                                                 /* lower byte is zero */
3849                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3850                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3851                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3852                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3853                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3854                                                 genSkipc(&rFalseIfx);
3855                                                 
3856                                                 
3857                                                 if(ifx) ifx->generated = 1;
3858                                                 return;
3859                                                 
3860                                         }
3861                                         
3862                                 }
3863                                 
3864                                 
3865                                 if(lit & (0x80 << (size*8))) {
3866                                         /* lit is negative */
3867                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3868                                         
3869                                         //genSkipCond(&rFalseIfx,left,size,7);
3870                                         
3871                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3872                                         
3873                                         if(rFalseIfx.condition)
3874                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3875                                         else
3876                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3877                                         
3878                                         
3879                                 } else {
3880                                         /* lit is positive */
3881                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3882                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3883                                         if(rFalseIfx.condition)
3884                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3885                                         else
3886                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3887                                         
3888                                 }
3889                                 
3890                                 /* There are no more special cases, so perform a general compare */
3891                                 
3892                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3893                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3894                                 
3895                                 while(size--) {
3896                                         
3897                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3898                                         emitSKPNZ;
3899                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3900                                 }
3901                                 //rFalseIfx.condition ^= 1;
3902                                 genSkipc(&rFalseIfx);
3903                                 
3904                                 emitpLabel(truelbl->key);
3905                                 
3906                                 if(ifx) ifx->generated = 1;
3907                                 return;
3908                                 
3909                                 
3910                         }
3911
3912
3913                         /* sign is out of the way. So now do an unsigned compare */
3914                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3915
3916
3917                         /* General case - compare to an unsigned literal on the right.*/
3918
3919                         i = (lit >> (size*8)) & 0xff;
3920                         emitpcode(POC_MOVLW, popGetLit(i));
3921                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3922                         while(size--) {
3923                                 i = (lit >> (size*8)) & 0xff;
3924                                 
3925                                 if(i) {
3926                                         emitpcode(POC_MOVLW, popGetLit(i));
3927                                         emitSKPNZ;
3928                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3929                                 } else {
3930                                 /* this byte of the lit is zero, 
3931                                         *if it's not the last then OR in the variable */
3932                                         if(size)
3933                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
3934                                 }
3935                         }
3936
3937
3938                 emitpLabel(lbl->key);
3939                 //if(emitFinalCheck)
3940                 genSkipc(&rFalseIfx);
3941                 if(sign)
3942                         emitpLabel(truelbl->key);
3943
3944                 if(ifx) ifx->generated = 1;
3945                 return;
3946
3947
3948                 }
3949 #endif  // _swapp
3950
3951                 if(AOP_TYPE(left) == AOP_LIT) {
3952                         //symbol *lbl = newiTempLabel(NULL);
3953                         
3954                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3955                         
3956                         
3957                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3958                         
3959                         /* Special cases */
3960                         if((lit == 0) && (sign == 0)){
3961                                 
3962                                 size--;
3963                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3964                                 while(size) 
3965                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
3966                                 
3967                                 genSkipz2(&rFalseIfx,0);
3968                                 if(ifx) ifx->generated = 1;
3969                                 return;
3970                         }
3971                         
3972                         if(size==1) {
3973                                 /* Special cases */
3974                                 lit &= 0xff;
3975                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3976                                         /* degenerate compare can never be true */
3977                                         if(rFalseIfx.condition == 0)
3978                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3979                                         
3980                                         if(ifx) ifx->generated = 1;
3981                                         return;
3982                                 }
3983                                 
3984                                 if(sign) {
3985                                         /* signed comparisons to a literal byte */
3986                                         
3987                                         int lp1 = (lit+1) & 0xff;
3988                                         
3989                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3990                                         switch (lp1) {
3991                                         case 0:
3992                                                 rFalseIfx.condition ^= 1;
3993                                                 genSkipCond(&rFalseIfx,right,0,7);
3994                                                 break;
3995                                         case 0x7f:
3996                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
3997                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3998                                                 genSkipz2(&rFalseIfx,1);
3999                                                 break;
4000                                         default:
4001                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4002                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4003                                                 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4004                                                 rFalseIfx.condition ^= 1;
4005                                                 genSkipc(&rFalseIfx);
4006                                                 break;
4007                                         }
4008                                         if(ifx) ifx->generated = 1;
4009                                 } else {
4010                                         /* unsigned comparisons to a literal byte */
4011                                         
4012                                         switch(lit & 0xff ) {
4013                                         case 0:
4014                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4015                                                 genSkipz2(&rFalseIfx,0);
4016                                                 if(ifx) ifx->generated = 1;
4017                                                 break;
4018                                         case 0x7f:
4019                                                 genSkipCond(&rFalseIfx,right,0,7);
4020                                                 if(ifx) ifx->generated = 1;
4021                                                 break;
4022                                                 
4023                                         default:
4024                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4025                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4026                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4027                                                 rFalseIfx.condition ^= 1;
4028                                                 if (AOP_TYPE(result) == AOP_CRY) {
4029                                                         genSkipc(&rFalseIfx);
4030                                                         if(ifx) ifx->generated = 1;
4031                                                 } else {
4032                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4033                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4034                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4035                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4036                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4037                                                 }       
4038                                                 break;
4039                                         }
4040                                 }
4041                                 
4042                                 //goto check_carry;
4043                                 return;
4044                                 
4045                         } else {
4046                                 
4047                                 /* Size is greater than 1 */
4048                                 
4049                                 if(sign) {
4050                                         int lp1 = lit+1;
4051                                         
4052                                         size--;
4053                                         
4054                                         if(lp1 == 0) {
4055                                                 /* this means lit = 0xffffffff, or -1 */
4056                                                 
4057                                                 
4058                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4059                                                 rFalseIfx.condition ^= 1;
4060                                                 genSkipCond(&rFalseIfx,right,size,7);
4061                                                 if(ifx) ifx->generated = 1;
4062                                                 return;
4063                                         }
4064                                         
4065                                         if(lit == 0) {
4066                                                 int s = size;
4067                                                 
4068                                                 if(rFalseIfx.condition) {
4069                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4070                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4071                                                 }
4072                                                 
4073                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4074                                                 while(size--)
4075                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4076                                                 
4077                                                 
4078                                                 emitSKPZ;
4079                                                 if(rFalseIfx.condition) {
4080                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4081                                                         emitpLabel(truelbl->key);
4082                                                 }else {
4083                                                         rFalseIfx.condition ^= 1;
4084                                                         genSkipCond(&rFalseIfx,right,s,7);
4085                                                 }
4086                                                 
4087                                                 if(ifx) ifx->generated = 1;
4088                                                 return;
4089                                         }
4090                                         
4091                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4092                                                 /* lower byte of signed word is zero */
4093                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4094                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4095                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4096                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4097                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4098                                                 rFalseIfx.condition ^= 1;
4099                                                 genSkipc(&rFalseIfx);
4100                                                 
4101                                                 
4102                                                 if(ifx) ifx->generated = 1;
4103                                                 return;
4104                                         }
4105                                         
4106                                         if(lit & (0x80 << (size*8))) {
4107                                                 /* Lit is less than zero */
4108                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4109                                                 //rFalseIfx.condition ^= 1;
4110                                                 //genSkipCond(&rFalseIfx,left,size,7);
4111                                                 //rFalseIfx.condition ^= 1;
4112                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4113                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4114                                                 
4115                                                 if(rFalseIfx.condition)
4116                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4117                                                 else
4118                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4119                                                 
4120                                                 
4121                                         } else {
4122                                                 /* Lit is greater than or equal to zero */
4123                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4124                                                 //rFalseIfx.condition ^= 1;
4125                                                 //genSkipCond(&rFalseIfx,right,size,7);
4126                                                 //rFalseIfx.condition ^= 1;
4127                                                 
4128                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4129                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4130                                                 
4131                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132                                                 if(rFalseIfx.condition)
4133                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4134                                                 else
4135                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4136                                                 
4137                                         }
4138                                         
4139                                         
4140                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4141                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4142                                         
4143                                         while(size--) {
4144                                                 
4145                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4146                                                 emitSKPNZ;
4147                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4148                                         }
4149                                         rFalseIfx.condition ^= 1;
4150                                         //rFalseIfx.condition = 1;
4151                                         genSkipc(&rFalseIfx);
4152                                         
4153                                         emitpLabel(truelbl->key);
4154                                         
4155                                         if(ifx) ifx->generated = 1;
4156                                         return;
4157                                         // end of if (sign)
4158                                 } else {
4159                                         
4160                                         /* compare word or long to an unsigned literal on the right.*/
4161                                         
4162                                         
4163                                         size--;
4164                                         if(lit < 0xff) {
4165                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4166                                                 switch (lit) {
4167                                                 case 0:
4168                                                         break; /* handled above */
4169                                                 /*
4170                                                 case 0xff:
4171                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4172                                                         while(size--)
4173                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4174                                                         genSkipz2(&rFalseIfx,0);
4175                                                         break;
4176                                                 */
4177                                                 default:
4178                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4179                                                         while(--size)
4180                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4181                                                         
4182                                                         emitSKPZ;
4183                                                         if(rFalseIfx.condition)
4184                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4185                                                         else
4186                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4187                                                         
4188                                                         
4189                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4190                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4191                                                         
4192                                                         rFalseIfx.condition ^= 1;
4193                                                         genSkipc(&rFalseIfx);
4194                                                 }
4195                                                 
4196                                                 emitpLabel(truelbl->key);
4197                                                 
4198                                                 if(ifx) ifx->generated = 1;
4199                                                 return;
4200                                         }
4201                                         
4202                                         
4203                                         lit++;
4204                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4205                                         i = (lit >> (size*8)) & 0xff;
4206                                         
4207                                         emitpcode(POC_MOVLW, popGetLit(i));
4208                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4209                                         
4210                                         while(size--) {
4211                                                 i = (lit >> (size*8)) & 0xff;
4212                                                 
4213                                                 if(i) {
4214                                                         emitpcode(POC_MOVLW, popGetLit(i));
4215                                                         emitSKPNZ;
4216                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4217                                                 } else {
4218                                                 /* this byte of the lit is zero, 
4219                                                         *if it's not the last then OR in the variable */
4220                                                         if(size)
4221                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4222                                                 }
4223                                         }
4224                                         
4225                                         
4226                                         emitpLabel(lbl->key);
4227                                         
4228                                         rFalseIfx.condition ^= 1;
4229                                         genSkipc(&rFalseIfx);
4230                                 }
4231                                 
4232                                 if(sign)
4233                                         emitpLabel(truelbl->key);
4234                                 if(ifx) ifx->generated = 1;
4235                                 return;
4236                         }
4237                 }
4238                 /* Compare two variables */
4239                 
4240                 DEBUGpic14_emitcode(";sign","%d",sign);
4241                 
4242                 size--;
4243                 if(sign) {
4244                         /* Sigh. thus sucks... */
4245                         if(size) {
4246                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4247                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4248                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4249                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4250                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4251                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4252                         } else {
4253                                 /* Signed char comparison */
4254                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4255                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4256                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4257                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4258                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4259                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4260                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4261                                 
4262                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4263                                 genSkipc(&rFalseIfx);
4264                                 
4265                                 if(ifx) ifx->generated = 1;
4266                                 return;
4267                         }
4268                         
4269                 } else {
4270                         
4271                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4272                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4273                 }
4274                 
4275                 
4276                 /* The rest of the bytes of a multi-byte compare */
4277                 while (size) {
4278                         
4279                         emitSKPZ;
4280                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4281                         size--;
4282                         
4283                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4284                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4285                         
4286                         
4287                 }
4288                 
4289                 emitpLabel(lbl->key);
4290                 
4291                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4292                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4293                         (AOP_TYPE(result) == AOP_REG)) {
4294                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4295                         emitpcode(POC_RLF, popGet(AOP(result),0));
4296                 } else {
4297                         genSkipc(&rFalseIfx);
4298                 }       
4299                 //genSkipc(&rFalseIfx);
4300                 if(ifx) ifx->generated = 1;
4301                 
4302                 return;
4303                 
4304         }
4305         
4306         // check_carry:
4307         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4308                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4309                 pic14_outBitC(result);
4310         } else {
4311                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4312                 /* if the result is used in the next
4313                 ifx conditional branch then generate
4314                 code a little differently */
4315                 if (ifx )
4316                         genIfxJump (ifx,"c");
4317                 else
4318                         pic14_outBitC(result);
4319                 /* leave the result in acc */
4320         }
4321         
4322 }
4323
4324 /*-----------------------------------------------------------------*/
4325 /* genCmpGt :- greater than comparison                             */
4326 /*-----------------------------------------------------------------*/
4327 static void genCmpGt (iCode *ic, iCode *ifx)
4328 {
4329         operand *left, *right, *result;
4330         sym_link *letype , *retype;
4331         int sign ;
4332         
4333         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4334         left = IC_LEFT(ic);
4335         right= IC_RIGHT(ic);
4336         result = IC_RESULT(ic);
4337         
4338         letype = getSpec(operandType(left));
4339         retype =getSpec(operandType(right));
4340         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4341         /* assign the amsops */
4342         aopOp (left,ic,FALSE);
4343         aopOp (right,ic,FALSE);
4344         aopOp (result,ic,TRUE);
4345         
4346         genCmp(right, left, result, ifx, sign);
4347         
4348         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4349         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4350         freeAsmop(result,NULL,ic,TRUE); 
4351 }
4352
4353 /*-----------------------------------------------------------------*/
4354 /* genCmpLt - less than comparisons                                */
4355 /*-----------------------------------------------------------------*/
4356 static void genCmpLt (iCode *ic, iCode *ifx)
4357 {
4358         operand *left, *right, *result;
4359         sym_link *letype , *retype;
4360         int sign ;
4361         
4362         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4363         left = IC_LEFT(ic);
4364         right= IC_RIGHT(ic);
4365         result = IC_RESULT(ic);
4366         
4367         letype = getSpec(operandType(left));
4368         retype =getSpec(operandType(right));
4369         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4370         
4371         /* assign the amsops */
4372         aopOp (left,ic,FALSE);
4373         aopOp (right,ic,FALSE);
4374         aopOp (result,ic,TRUE);
4375         
4376         genCmp(left, right, result, ifx, sign);
4377         
4378         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4379         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380         freeAsmop(result,NULL,ic,TRUE); 
4381 }
4382
4383 /*-----------------------------------------------------------------*/
4384 /* genc16bit2lit - compare a 16 bit value to a literal             */
4385 /*-----------------------------------------------------------------*/
4386 static void genc16bit2lit(operand *op, int lit, int offset)
4387 {
4388         int i;
4389         
4390         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4391         if( (lit&0xff) == 0) 
4392                 i=1;
4393         else
4394                 i=0;
4395         
4396         switch( BYTEofLONG(lit,i)) { 
4397         case 0:
4398                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4399                 break;
4400         case 1:
4401                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4402                 break;
4403         case 0xff:
4404                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4405                 break;
4406         default:
4407                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4408                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4409         }
4410         
4411         i ^= 1;
4412         
4413         switch( BYTEofLONG(lit,i)) { 
4414         case 0:
4415                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4416                 break;
4417         case 1:
4418                 emitSKPNZ;
4419                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4420                 break;
4421         case 0xff:
4422                 emitSKPNZ;
4423                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4424                 break;
4425         default:
4426                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4427                 emitSKPNZ;
4428                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4429                 
4430         }
4431         
4432 }
4433
4434 /*-----------------------------------------------------------------*/
4435 /* gencjneshort - compare and jump if not equal                    */
4436 /*-----------------------------------------------------------------*/
4437 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4438 {
4439         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4440         int offset = 0;
4441         int res_offset = 0;  /* the result may be a different size then left or right */
4442         int res_size = AOP_SIZE(result);
4443         resolvedIfx rIfx;
4444         symbol *lbl;
4445         
4446         unsigned long lit = 0L;
4447         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4448         DEBUGpic14_AopType(__LINE__,left,right,result);
4449         if(result)
4450                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4451         resolveIfx(&rIfx,ifx);
4452         lbl =  newiTempLabel(NULL);
4453         
4454         
4455         /* if the left side is a literal or 
4456         if the right is in a pointer register and left 
4457         is not */
4458         if ((AOP_TYPE(left) == AOP_LIT) || 
4459                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4460                 operand *t = right;
4461                 right = left;
4462                 left = t;
4463         }
4464         if(AOP_TYPE(right) == AOP_LIT)
4465                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4466         
4467         /* if the right side is a literal then anything goes */
4468         if (AOP_TYPE(right) == AOP_LIT &&
4469                 AOP_TYPE(left) != AOP_DIR ) {
4470                 switch(size) {
4471                 case 2:
4472                         genc16bit2lit(left, lit, 0);
4473                         emitSKPNZ;
4474                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4475                         break;
4476                 default:
4477                         while (size--) {
4478                                 if(lit & 0xff) {
4479                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4480                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4481                                 } else {
4482                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4483                                 }
4484                                 
4485                                 emitSKPNZ;
4486                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4487                                 offset++;
4488                                 if(res_offset < res_size-1)
4489                                         res_offset++;
4490                                 lit >>= 8;
4491                         }
4492                         break;
4493                 }
4494         }
4495         
4496         /* if the right side is in a register or in direct space or
4497         if the left is a pointer register & right is not */    
4498         else if (AOP_TYPE(right) == AOP_REG ||
4499                 AOP_TYPE(right) == AOP_DIR || 
4500                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4501                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4502                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4503                 int lbl_key = lbl->key;
4504                 
4505                 if(result) {
4506                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4507                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4508                 }else {
4509                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4510                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4511                                 __FUNCTION__,__LINE__);
4512                         return;
4513                 }
4514                 
4515                 /*     switch(size) { */
4516                 /*     case 2: */
4517                 /*       genc16bit2lit(left, lit, 0); */
4518                 /*       emitSKPNZ; */
4519                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4520                 /*       break; */
4521                 /*     default: */
4522                 while (size--) {
4523                         int emit_skip=1;
4524                         if((AOP_TYPE(left) == AOP_DIR) && 
4525                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4526                                 
4527                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4528                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4529                                 
4530                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4531                                 
4532                                 switch (lit & 0xff) {
4533                                 case 0:
4534                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4535                                         break;
4536                                 case 1:
4537                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4538                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4539                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4540                                         emit_skip=0;
4541                                         break;
4542                                 case 0xff:
4543                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4544                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4545                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4546                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4547                                         emit_skip=0;
4548                                         break;
4549                                 default:
4550                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4551                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4552                                 }
4553                                 lit >>= 8;
4554                                 
4555                         } else {
4556                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4557                         }
4558                         if(emit_skip) {
4559                                 if(AOP_TYPE(result) == AOP_CRY) {
4560                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4561                                         if(rIfx.condition)
4562                                                 emitSKPNZ;
4563                                         else
4564                                                 emitSKPZ;
4565                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4566                                 } else {
4567                                         /* fix me. probably need to check result size too */
4568                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4569                                         if(rIfx.condition)
4570                                                 emitSKPZ;
4571                                         else
4572                                                 emitSKPNZ;
4573                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4574                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4575                                 }
4576                                 if(ifx)
4577                                         ifx->generated=1;
4578                         }
4579                         emit_skip++;
4580                         offset++;
4581                         if(res_offset < res_size-1)
4582                                 res_offset++;
4583                 }
4584                 /*       break; */
4585                 /*     } */
4586         } else if(AOP_TYPE(right) == AOP_REG &&
4587                 AOP_TYPE(left) != AOP_DIR){
4588                 
4589                 while(size--) {
4590                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4591                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4592                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4593                         if(rIfx.condition)
4594                                 emitSKPNZ;
4595                         else
4596                                 emitSKPZ;
4597                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4598                         offset++;
4599                         if(res_offset < res_size-1)
4600                                 res_offset++;
4601                 }
4602                 
4603         }else{
4604                 /* right is a pointer reg need both a & b */
4605                 while(size--) {
4606                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4607                         if(strcmp(l,"b"))
4608                                 pic14_emitcode("mov","b,%s",l);
4609                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4610                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4611                         offset++;
4612                 }
4613         }
4614         
4615         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4616         if(!rIfx.condition)
4617                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4618         
4619         emitpLabel(lbl->key);
4620         
4621         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4622         
4623         if(ifx)
4624                 ifx->generated = 1;
4625 }
4626
4627 #if 0
4628 /*-----------------------------------------------------------------*/
4629 /* gencjne - compare and jump if not equal                         */
4630 /*-----------------------------------------------------------------*/
4631 static void gencjne(operand *left, operand *right, iCode *ifx)
4632 {
4633         symbol *tlbl  = newiTempLabel(NULL);
4634         
4635         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4636         gencjneshort(left, right, lbl);
4637         
4638         pic14_emitcode("mov","a,%s",one);
4639         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4640         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4641         pic14_emitcode("clr","a");
4642         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4643         
4644         emitpLabel(lbl->key);
4645         emitpLabel(tlbl->key);
4646         
4647 }
4648 #endif
4649
4650 /*-----------------------------------------------------------------*/
4651 /* genCmpEq - generates code for equal to                          */
4652 /*-----------------------------------------------------------------*/
4653 static void genCmpEq (iCode *ic, iCode *ifx)
4654 {
4655         operand *left, *right, *result;
4656         unsigned long lit = 0L;
4657         int size,offset=0;
4658         
4659         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4660         
4661         if(ifx)
4662                 DEBUGpic14_emitcode ("; ifx is non-null","");
4663         else
4664                 DEBUGpic14_emitcode ("; ifx is null","");
4665         
4666         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4667         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4668         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4669         
4670         size = max(AOP_SIZE(left),AOP_SIZE(right));
4671         
4672         DEBUGpic14_AopType(__LINE__,left,right,result);
4673         
4674         /* if literal, literal on the right or 
4675         if the right is in a pointer register and left 
4676         is not */
4677         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4678                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4679                 operand *tmp = right ;
4680                 right = left;
4681                 left = tmp;
4682         }
4683         
4684         
4685         if(ifx && !AOP_SIZE(result)){
4686                 symbol *tlbl;
4687                 /* if they are both bit variables */
4688                 if (AOP_TYPE(left) == AOP_CRY &&
4689                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4690                         if(AOP_TYPE(right) == AOP_LIT){
4691                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4692                                 if(lit == 0L){
4693                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4694                                         pic14_emitcode("cpl","c");
4695                                 } else if(lit == 1L) {
4696                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4697                                 } else {
4698                                         pic14_emitcode("clr","c");
4699                                 }
4700                                 /* AOP_TYPE(right) == AOP_CRY */
4701                         } else {
4702                                 symbol *lbl = newiTempLabel(NULL);
4703                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4704                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4705                                 pic14_emitcode("cpl","c");
4706                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4707                         }
4708                         /* if true label then we jump if condition
4709                         supplied is true */
4710                         tlbl = newiTempLabel(NULL);
4711                         if ( IC_TRUE(ifx) ) {
4712                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4713                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4714                         } else {
4715                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4716                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4717                         }
4718                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4719                         
4720                         {
4721                                 /* left and right are both bit variables, result is carry */
4722                                 resolvedIfx rIfx;
4723                                 
4724                                 resolveIfx(&rIfx,ifx);
4725                                 
4726                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4727                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4728                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4729                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4730                                 genSkipz2(&rIfx,0);
4731                         }
4732                 } else {
4733                         
4734                         /* They're not both bit variables. Is the right a literal? */
4735                         if(AOP_TYPE(right) == AOP_LIT) {
4736                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4737                                 
4738                                 switch(size) {
4739                                         
4740                                 case 1:
4741                                         switch(lit & 0xff) {
4742                                         case 1:
4743                                                 if ( IC_TRUE(ifx) ) {
4744                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4745                                                         emitSKPNZ;
4746                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4747                                                 } else {
4748                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4749                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4750                                                 }
4751                                                 break;
4752                                         case 0xff:
4753                                                 if ( IC_TRUE(ifx) ) {
4754                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4755                                                         emitSKPNZ;
4756                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4757                                                 } else {
4758                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4759                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4760                                                 }
4761                                                 break;
4762                                         default:
4763                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4764                                                 if(lit)
4765                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4766                                                 genSkip(ifx,'z');
4767                                         }
4768                                         
4769                                         
4770                                         /* end of size == 1 */
4771                                         break;
4772                                         
4773                                         case 2:
4774                                                 genc16bit2lit(left,lit,offset);
4775                                                 genSkip(ifx,'z');
4776                                                 break;
4777                                                 /* end of size == 2 */
4778                                                 
4779                                         default:
4780                                                 /* size is 4 */
4781                                                 if(lit==0) {
4782                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4783                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4784                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4785                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4786                                                         
4787                                                 } else {
4788                                                         
4789                                                         /* search for patterns that can be optimized */
4790                                                         
4791                                                         genc16bit2lit(left,lit,0);
4792                                                         lit >>= 16;
4793                                                         if(lit) {
4794                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4795                                                                 //genSkip(ifx,'z');
4796                                                                 genc16bit2lit(left,lit,2);
4797                                                         } else {
4798                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4799                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4800                                                                 
4801                                                         }
4802                                                         
4803                                                 }
4804                                                 
4805                                                 genSkip(ifx,'z');
4806                                 }
4807                                 
4808                                 ifx->generated = 1;
4809                                 goto release ;
4810                                 
4811                                 
4812                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4813                                 /* we know the left is not a bit, but that the right is */
4814                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4815                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4816                                         popGet(AOP(right),offset));
4817                                 emitpcode(POC_XORLW,popGetLit(1));
4818                                 
4819                                 /* if the two are equal, then W will be 0 and the Z bit is set
4820                                 * we could test Z now, or go ahead and check the high order bytes if
4821                                 * the variable we're comparing is larger than a byte. */
4822                                 
4823                                 while(--size)
4824                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4825                                 
4826                                 if ( IC_TRUE(ifx) ) {
4827                                         emitSKPNZ;
4828                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4829                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4830                                 } else {
4831                                         emitSKPZ;
4832                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4833                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4834                                 }
4835                                 
4836                         } else {
4837                                 /* They're both variables that are larger than bits */
4838                                 int s = size;
4839                                 
4840                                 tlbl = newiTempLabel(NULL);
4841                                 
4842                                 while(size--) {
4843                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4844                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4845                                         
4846                                         if ( IC_TRUE(ifx) ) {
4847                                                 if(size) {
4848                                                         emitSKPZ;
4849                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4850                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4851                                                 } else {
4852                                                         emitSKPNZ;
4853                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4854                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4855                                                 }
4856                                         } else {
4857                                                 emitSKPZ;
4858                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4859                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4860                                         }
4861                                         offset++;
4862                                 }
4863                                 if(s>1 && IC_TRUE(ifx)) {
4864                                         emitpLabel(tlbl->key);
4865                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4866                                 }
4867                         }
4868                 }
4869                 /* mark the icode as generated */
4870                 ifx->generated = 1;
4871                 goto release ;
4872         }
4873   
4874   /* if they are both bit variables */
4875   if (AOP_TYPE(left) == AOP_CRY &&
4876           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4877           if(AOP_TYPE(right) == AOP_LIT){
4878                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4879                   if(lit == 0L){
4880                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4881                           pic14_emitcode("cpl","c");
4882                   } else if(lit == 1L) {
4883                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4884                   } else {
4885                           pic14_emitcode("clr","c");
4886                   }
4887                   /* AOP_TYPE(right) == AOP_CRY */
4888           } else {
4889                   symbol *lbl = newiTempLabel(NULL);
4890                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4891                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4892                   pic14_emitcode("cpl","c");
4893                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4894           }
4895           /* c = 1 if egal */
4896           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4897                   pic14_outBitC(result);
4898                   goto release ;
4899           }
4900           if (ifx) {
4901                   genIfxJump (ifx,"c");
4902                   goto release ;
4903           }
4904           /* if the result is used in an arithmetic operation
4905           then put the result in place */
4906           pic14_outBitC(result);
4907   } else {
4908           
4909           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4910           gencjne(left,right,result,ifx);
4911           /*
4912           if(ifx) 
4913           gencjne(left,right,newiTempLabel(NULL));
4914           else {
4915           if(IC_TRUE(ifx)->key)
4916           gencjne(left,right,IC_TRUE(ifx)->key);
4917           else
4918           gencjne(left,right,IC_FALSE(ifx)->key);
4919           ifx->generated = 1;
4920           goto release ;
4921           }
4922           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4923           aopPut(AOP(result),"a",0);
4924           goto release ;
4925           }
4926           
4927                 if (ifx) {
4928                 genIfxJump (ifx,"a");
4929                 goto release ;
4930                 }
4931           */
4932           /* if the result is used in an arithmetic operation
4933           then put the result in place */
4934           /*
4935           if (AOP_TYPE(result) != AOP_CRY) 
4936           pic14_outAcc(result);
4937           */
4938           /* leave the result in acc */
4939   }
4940   
4941 release:
4942   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4943   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4944   freeAsmop(result,NULL,ic,TRUE);
4945 }
4946
4947 /*-----------------------------------------------------------------*/
4948 /* ifxForOp - returns the icode containing the ifx for operand     */
4949 /*-----------------------------------------------------------------*/
4950 static iCode *ifxForOp ( operand *op, iCode *ic )
4951 {
4952         /* if true symbol then needs to be assigned */
4953         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4954         if (IS_TRUE_SYMOP(op))
4955                 return NULL ;
4956         
4957                 /* if this has register type condition and
4958                 the next instruction is ifx with the same operand
4959         and live to of the operand is upto the ifx only then */
4960         if (ic->next &&
4961                 ic->next->op == IFX &&
4962                 IC_COND(ic->next)->key == op->key &&
4963                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4964                 return ic->next;
4965         
4966         if (ic->next &&
4967                 ic->next->op == IFX &&
4968                 IC_COND(ic->next)->key == op->key) {
4969                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4970                 return ic->next;
4971         }
4972         
4973         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4974         if (ic->next &&
4975                 ic->next->op == IFX)
4976                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4977         
4978         if (ic->next &&
4979                 ic->next->op == IFX &&
4980                 IC_COND(ic->next)->key == op->key) {
4981                 DEBUGpic14_emitcode ("; "," key is okay");
4982                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4983                         OP_SYMBOL(op)->liveTo,
4984                         ic->next->seq);
4985         }
4986         
4987         
4988         return NULL;
4989 }
4990 /*-----------------------------------------------------------------*/
4991 /* genAndOp - for && operation                                     */
4992 /*-----------------------------------------------------------------*/
4993 static void genAndOp (iCode *ic)
4994 {
4995         operand *left,*right, *result;
4996         /*     symbol *tlbl; */
4997         
4998         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4999         /* note here that && operations that are in an
5000         if statement are taken away by backPatchLabels
5001         only those used in arthmetic operations remain */
5002         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5003         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5004         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5005         
5006         DEBUGpic14_AopType(__LINE__,left,right,result);
5007         
5008         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5009         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5010         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5011         
5012         /* if both are bit variables */
5013         /*     if (AOP_TYPE(left) == AOP_CRY && */
5014         /*         AOP_TYPE(right) == AOP_CRY ) { */
5015         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5016         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5017         /*         pic14_outBitC(result); */
5018         /*     } else { */
5019         /*         tlbl = newiTempLabel(NULL); */
5020         /*         pic14_toBoolean(left);     */
5021         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5022         /*         pic14_toBoolean(right); */
5023         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5024         /*         pic14_outBitAcc(result); */
5025         /*     } */
5026         
5027         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5028         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5029         freeAsmop(result,NULL,ic,TRUE);
5030 }
5031
5032
5033 /*-----------------------------------------------------------------*/
5034 /* genOrOp - for || operation                                      */
5035 /*-----------------------------------------------------------------*/
5036 /*
5037 tsd pic port -
5038 modified this code, but it doesn't appear to ever get called
5039 */
5040
5041 static void genOrOp (iCode *ic)
5042 {
5043         operand *left,*right, *result;
5044         symbol *tlbl;
5045         
5046         /* note here that || operations that are in an
5047         if statement are taken away by backPatchLabels
5048         only those used in arthmetic operations remain */
5049         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5050         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5051         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5052         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5053         
5054         DEBUGpic14_AopType(__LINE__,left,right,result);
5055         
5056         /* if both are bit variables */
5057         if (AOP_TYPE(left) == AOP_CRY &&
5058                 AOP_TYPE(right) == AOP_CRY ) {
5059                 pic14_emitcode("clrc","");
5060                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5061                         AOP(left)->aopu.aop_dir,
5062                         AOP(left)->aopu.aop_dir);
5063                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5064                         AOP(right)->aopu.aop_dir,
5065                         AOP(right)->aopu.aop_dir);
5066                 pic14_emitcode("setc","");
5067                 
5068         } else {
5069                 tlbl = newiTempLabel(NULL);
5070                 pic14_toBoolean(left);
5071                 emitSKPZ;
5072                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5073                 pic14_toBoolean(right);
5074                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5075                 
5076                 pic14_outBitAcc(result);
5077         }
5078         
5079         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5080         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5081         freeAsmop(result,NULL,ic,TRUE);            
5082 }
5083
5084 /*-----------------------------------------------------------------*/
5085 /* isLiteralBit - test if lit == 2^n                               */
5086 /*-----------------------------------------------------------------*/
5087 static int isLiteralBit(unsigned long lit)
5088 {
5089         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5090                 0x100L,0x200L,0x400L,0x800L,
5091                 0x1000L,0x2000L,0x4000L,0x8000L,
5092                 0x10000L,0x20000L,0x40000L,0x80000L,
5093                 0x100000L,0x200000L,0x400000L,0x800000L,
5094                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5095                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5096         int idx;
5097         
5098         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5099         for(idx = 0; idx < 32; idx++)
5100                 if(lit == pw[idx])
5101                         return idx+1;
5102                 return 0;
5103 }
5104
5105 /*-----------------------------------------------------------------*/
5106 /* continueIfTrue -                                                */
5107 /*-----------------------------------------------------------------*/
5108 static void continueIfTrue (iCode *ic)
5109 {
5110         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5111         if(IC_TRUE(ic))
5112                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5113         ic->generated = 1;
5114 }
5115
5116 /*-----------------------------------------------------------------*/
5117 /* jmpIfTrue -                                                     */
5118 /*-----------------------------------------------------------------*/
5119 static void jumpIfTrue (iCode *ic)
5120 {
5121         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5122         if(!IC_TRUE(ic))
5123                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5124         ic->generated = 1;
5125 }
5126
5127 /*-----------------------------------------------------------------*/
5128 /* jmpTrueOrFalse -                                                */
5129 /*-----------------------------------------------------------------*/
5130 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5131 {
5132         // ugly but optimized by peephole
5133         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5134         if(IC_TRUE(ic)){
5135                 symbol *nlbl = newiTempLabel(NULL);
5136                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5137                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5138                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5139                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5140         }
5141         else{
5142                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5143                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5144         }
5145         ic->generated = 1;
5146 }
5147
5148 /*-----------------------------------------------------------------*/
5149 /* genAnd  - code for and                                          */
5150 /*-----------------------------------------------------------------*/
5151 static void genAnd (iCode *ic, iCode *ifx)
5152 {
5153         operand *left, *right, *result;
5154         int size, offset=0;  
5155         unsigned long lit = 0L;
5156         int bytelit = 0;
5157         resolvedIfx rIfx;
5158         
5159         
5160         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5161         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5162         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5163         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5164         
5165         resolveIfx(&rIfx,ifx);
5166         
5167         /* if left is a literal & right is not then exchange them */
5168         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5169                 AOP_NEEDSACC(left)) {
5170                 operand *tmp = right ;
5171                 right = left;
5172                 left = tmp;
5173         }
5174         
5175         /* if result = right then exchange them */
5176         if(pic14_sameRegs(AOP(result),AOP(right))){
5177                 operand *tmp = right ;
5178                 right = left;
5179                 left = tmp;
5180         }
5181         
5182         /* if right is bit then exchange them */
5183         if (AOP_TYPE(right) == AOP_CRY &&
5184                 AOP_TYPE(left) != AOP_CRY){
5185                 operand *tmp = right ;
5186                 right = left;
5187                 left = tmp;
5188         }
5189         if(AOP_TYPE(right) == AOP_LIT)
5190                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5191         
5192         size = AOP_SIZE(result);
5193         
5194         DEBUGpic14_AopType(__LINE__,left,right,result);
5195         
5196         // if(bit & yy)
5197         // result = bit & yy;
5198         if (AOP_TYPE(left) == AOP_CRY){
5199                 // c = bit & literal;
5200                 if(AOP_TYPE(right) == AOP_LIT){
5201                         if(lit & 1) {
5202                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5203                                         // no change
5204                                         goto release;
5205                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5206                         } else {
5207                                 // bit(result) = 0;
5208                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5209                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5210                                         goto release;
5211                                 }
5212                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5213                                         jumpIfTrue(ifx);
5214                                         goto release;
5215                                 }
5216                                 pic14_emitcode("clr","c");
5217                         }
5218                 } else {
5219                         if (AOP_TYPE(right) == AOP_CRY){
5220                                 // c = bit & bit;
5221                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5222                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5223                         } else {
5224                                 // c = bit & val;
5225                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5226                                 // c = lsb
5227                                 pic14_emitcode("rrc","a");
5228                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5229                         }
5230                 }
5231                 // bit = c
5232                 // val = c
5233                 if(size)
5234                         pic14_outBitC(result);
5235                 // if(bit & ...)
5236                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5237                         genIfxJump(ifx, "c");           
5238                 goto release ;
5239         }
5240         
5241         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5242         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5243         if((AOP_TYPE(right) == AOP_LIT) &&
5244                 (AOP_TYPE(result) == AOP_CRY) &&
5245                 (AOP_TYPE(left) != AOP_CRY)){
5246                 int posbit = isLiteralBit(lit);
5247                 /* left &  2^n */
5248                 if(posbit){
5249                         posbit--;
5250                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5251                         // bit = left & 2^n
5252                         if(size)
5253                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5254                         // if(left &  2^n)
5255                         else{
5256                                 if(ifx){
5257                                         int offset = 0;
5258                                         while (posbit > 7) {
5259                                                 posbit -= 8;
5260                                                 offset++;
5261                                         }
5262                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5263                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5264                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5265                                         
5266                                         ifx->generated = 1;
5267                                 }
5268                                 goto release;
5269                         }
5270                 } else {
5271                         symbol *tlbl = newiTempLabel(NULL);
5272                         int sizel = AOP_SIZE(left);
5273                         if(size)
5274                                 pic14_emitcode("setb","c");
5275                         while(sizel--){
5276                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5277                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5278                                         // byte ==  2^n ?
5279                                         if((posbit = isLiteralBit(bytelit)) != 0)
5280                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5281                                         else{
5282                                                 if(bytelit != 0x0FFL)
5283                                                         pic14_emitcode("anl","a,%s",
5284                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5285                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5286                                         }
5287                                 }
5288                                 offset++;
5289                         }
5290                         // bit = left & literal
5291                         if(size){
5292                                 pic14_emitcode("clr","c");
5293                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5294                         }
5295                         // if(left & literal)
5296                         else{
5297                                 if(ifx)
5298                                         jmpTrueOrFalse(ifx, tlbl);
5299                                 goto release ;
5300                         }
5301                 }
5302                 pic14_outBitC(result);
5303                 goto release ;
5304         }
5305         
5306         /* if left is same as result */
5307         if(pic14_sameRegs(AOP(result),AOP(left))){
5308                 int know_W = -1;
5309                 for(;size--; offset++,lit>>=8) {
5310                         if(AOP_TYPE(right) == AOP_LIT){
5311                                 switch(lit & 0xff) {
5312                                 case 0x00:
5313                                         /*  and'ing with 0 has clears the result */
5314                                         pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
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                                                         pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5327                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5328                                                         
5329                                                 } else {
5330                                                         pic14_emitcode("movlw","0x%x", (lit & 0xff));
5331                                                         pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5332                                                         if(know_W != (int)(lit&0xff))
5333                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5334                                                         know_W = lit &0xff;
5335                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5336                                                 }
5337                                         }    
5338                                 }
5339                         } else {
5340                                 if (AOP_TYPE(left) == AOP_ACC) {
5341                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5342                                 } else {        
5343                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5344                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5345                                         
5346                                 }
5347                         }
5348                 }
5349                 
5350         } else {
5351                 // left & result in different registers
5352                 if(AOP_TYPE(result) == AOP_CRY){
5353                         // result = bit
5354                         // if(size), result in bit
5355                         // if(!size && ifx), conditional oper: if(left & right)
5356                         symbol *tlbl = newiTempLabel(NULL);
5357                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5358                         if(size)
5359                                 pic14_emitcode("setb","c");
5360                         while(sizer--){
5361                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5362                                 pic14_emitcode("anl","a,%s",
5363                                         aopGet(AOP(left),offset,FALSE,FALSE));
5364                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5365                                 offset++;
5366                         }
5367                         if(size){
5368                                 CLRC;
5369                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5370                                 pic14_outBitC(result);
5371                         } else if(ifx)
5372                                 jmpTrueOrFalse(ifx, tlbl);
5373                 } else {
5374                         for(;(size--);offset++) {
5375                                 // normal case
5376                                 // result = left & right
5377                                 if(AOP_TYPE(right) == AOP_LIT){
5378                                         int t = (lit >> (offset*8)) & 0x0FFL;
5379                                         switch(t) { 
5380                                         case 0x00:
5381                                                 pic14_emitcode("clrf","%s",
5382                                                         aopGet(AOP(result),offset,FALSE,FALSE));
5383                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5384                                                 break;
5385                                         case 0xff:
5386                                                 if(AOP_TYPE(left) != AOP_ACC) {
5387                                                         pic14_emitcode("movf","%s,w",
5388                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5389                                                         pic14_emitcode("movwf","%s",
5390                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5391                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5392                                                 }
5393                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5394                                                 break;
5395                                         default:
5396                                                 if(AOP_TYPE(left) == AOP_ACC) {
5397                                                         emitpcode(POC_ANDLW, popGetLit(t));
5398                                                 } else {
5399                                                         pic14_emitcode("movlw","0x%x",t);
5400                                                         pic14_emitcode("andwf","%s,w",
5401                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5402                                                         pic14_emitcode("movwf","%s",
5403                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5404                                                         
5405                                                         emitpcode(POC_MOVLW, popGetLit(t));
5406                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5407                                                 }
5408                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5409                                         }
5410                                         continue;
5411                                 }
5412                                 
5413                                 if (AOP_TYPE(left) == AOP_ACC) {
5414                                         pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5415                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5416                                 } else {
5417                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5418                                         pic14_emitcode("andwf","%s,w",
5419                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5420                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5421                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5422                                 }
5423                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5424                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5425                         }
5426                 }
5427         }
5428         
5429 release :
5430         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5431         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5432         freeAsmop(result,NULL,ic,TRUE);     
5433 }
5434
5435 /*-----------------------------------------------------------------*/
5436 /* genOr  - code for or                                            */
5437 /*-----------------------------------------------------------------*/
5438 static void genOr (iCode *ic, iCode *ifx)
5439 {
5440         operand *left, *right, *result;
5441         int size, offset=0;
5442         unsigned long lit = 0L;
5443         
5444         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5445         
5446         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5447         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5448         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5449         
5450         DEBUGpic14_AopType(__LINE__,left,right,result);
5451         
5452         /* if left is a literal & right is not then exchange them */
5453         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5454                 AOP_NEEDSACC(left)) {
5455                 operand *tmp = right ;
5456                 right = left;
5457                 left = tmp;
5458         }
5459         
5460         /* if result = right then exchange them */
5461         if(pic14_sameRegs(AOP(result),AOP(right))){
5462                 operand *tmp = right ;
5463                 right = left;
5464                 left = tmp;
5465         }
5466         
5467         /* if right is bit then exchange them */
5468         if (AOP_TYPE(right) == AOP_CRY &&
5469                 AOP_TYPE(left) != AOP_CRY){
5470                 operand *tmp = right ;
5471                 right = left;
5472                 left = tmp;
5473         }
5474         
5475         DEBUGpic14_AopType(__LINE__,left,right,result);
5476         
5477         if(AOP_TYPE(right) == AOP_LIT)
5478                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5479         
5480         size = AOP_SIZE(result);
5481         
5482         // if(bit | yy)
5483         // xx = bit | yy;
5484         if (AOP_TYPE(left) == AOP_CRY){
5485                 if(AOP_TYPE(right) == AOP_LIT){
5486                         // c = bit & literal;
5487                         if(lit){
5488                                 // lit != 0 => result = 1
5489                                 if(AOP_TYPE(result) == AOP_CRY){
5490                                         if(size)
5491                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5492                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5493                                         //   AOP(result)->aopu.aop_dir,
5494                                         //   AOP(result)->aopu.aop_dir);
5495                                         else if(ifx)
5496                                                 continueIfTrue(ifx);
5497                                         goto release;
5498                                 }
5499                         } else {
5500                                 // lit == 0 => result = left
5501                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5502                                         goto release;
5503                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5504                         }
5505                 } else {
5506                         if (AOP_TYPE(right) == AOP_CRY){
5507                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5508                                         // c = bit | bit;
5509                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5510                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5511                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5512                                         
5513                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5514                                                 AOP(result)->aopu.aop_dir,
5515                                                 AOP(result)->aopu.aop_dir);
5516                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5517                                                 AOP(right)->aopu.aop_dir,
5518                                                 AOP(right)->aopu.aop_dir);
5519                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5520                                                 AOP(result)->aopu.aop_dir,
5521                                                 AOP(result)->aopu.aop_dir);
5522                                 } else {
5523                                         if( AOP_TYPE(result) == AOP_ACC) {
5524                                                 emitpcode(POC_MOVLW, popGetLit(0));
5525                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5526                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5527                                                 emitpcode(POC_MOVLW, popGetLit(1));
5528                                                 
5529                                         } else {
5530                                                 
5531                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5532                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5533                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5534                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5535                                                 
5536                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5537                                                         AOP(result)->aopu.aop_dir,
5538                                                         AOP(result)->aopu.aop_dir);
5539                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5540                                                         AOP(right)->aopu.aop_dir,
5541                                                         AOP(right)->aopu.aop_dir);
5542                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5543                                                         AOP(left)->aopu.aop_dir,
5544                                                         AOP(left)->aopu.aop_dir);
5545                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5546                                                         AOP(result)->aopu.aop_dir,
5547                                                         AOP(result)->aopu.aop_dir);
5548                                         }
5549                                 }
5550                         } else {
5551                                 // c = bit | val;
5552                                 symbol *tlbl = newiTempLabel(NULL);
5553                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5554                                 
5555                                 
5556                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5557                                 if( AOP_TYPE(right) == AOP_ACC) {
5558                                         emitpcode(POC_IORLW, popGetLit(0));
5559                                         emitSKPNZ;
5560                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5561                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5562                                 }
5563                                 
5564                                 
5565                                 
5566                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5567                                         pic14_emitcode(";XXX setb","c");
5568                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5569                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5570                                 pic14_toBoolean(right);
5571                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5572                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5573                                         jmpTrueOrFalse(ifx, tlbl);
5574                                         goto release;
5575                                 } else {
5576                                         CLRC;
5577                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5578                                 }
5579                         }
5580                 }
5581                 // bit = c
5582                 // val = c
5583                 if(size)
5584                         pic14_outBitC(result);
5585                 // if(bit | ...)
5586                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5587                         genIfxJump(ifx, "c");           
5588                 goto release ;
5589   }
5590   
5591   // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5592   // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5593   if((AOP_TYPE(right) == AOP_LIT) &&
5594           (AOP_TYPE(result) == AOP_CRY) &&
5595           (AOP_TYPE(left) != AOP_CRY)){
5596           if(lit){
5597                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5598                   // result = 1
5599                   if(size)
5600                           pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5601                   else 
5602                           continueIfTrue(ifx);
5603                   goto release;
5604           } else {
5605                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5606                   // lit = 0, result = boolean(left)
5607                   if(size)
5608                           pic14_emitcode(";XXX setb","c");
5609                   pic14_toBoolean(right);
5610                   if(size){
5611                           symbol *tlbl = newiTempLabel(NULL);
5612                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5613                           CLRC;
5614                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5615                   } else {
5616                           genIfxJump (ifx,"a");
5617                           goto release;
5618                   }
5619           }
5620           pic14_outBitC(result);
5621           goto release ;
5622   }
5623   
5624   /* if left is same as result */
5625   if(pic14_sameRegs(AOP(result),AOP(left))){
5626           int know_W = -1;
5627           for(;size--; offset++,lit>>=8) {
5628                   if(AOP_TYPE(right) == AOP_LIT){
5629                           if((lit & 0xff) == 0)
5630                                   /*  or'ing with 0 has no effect */
5631                                   continue;
5632                           else {
5633                                   int p = my_powof2(lit & 0xff);
5634                                   if(p>=0) {
5635                                           /* only one bit is set in the literal, so use a bsf instruction */
5636                                           emitpcode(POC_BSF,
5637                                                   newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5638                                   } else {
5639                                           if(know_W != (int)(lit & 0xff))
5640                                                   emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5641                                           know_W = lit & 0xff;
5642                                           emitpcode(POC_IORWF, popGet(AOP(left),offset));
5643                                   }
5644                                   
5645                           }
5646                   } else {
5647                           if (AOP_TYPE(left) == AOP_ACC) {
5648                                   emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5649                                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5650                           } else {        
5651                                   emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5652                                   emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5653                                   
5654                                   pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5655                                   pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5656                                   
5657                           }
5658                   }
5659           }
5660   } else {
5661           // left & result in different registers
5662           if(AOP_TYPE(result) == AOP_CRY){
5663                   // result = bit
5664                   // if(size), result in bit
5665                   // if(!size && ifx), conditional oper: if(left | right)
5666                   symbol *tlbl = newiTempLabel(NULL);
5667                   int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5668                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5669                   
5670                   
5671                   if(size)
5672                           pic14_emitcode(";XXX setb","c");
5673                   while(sizer--){
5674                           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5675                           pic14_emitcode(";XXX orl","a,%s",
5676                                   aopGet(AOP(left),offset,FALSE,FALSE));
5677                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5678                           offset++;
5679                   }
5680                   if(size){
5681                           CLRC;
5682                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5683                           pic14_outBitC(result);
5684                   } else if(ifx)
5685                           jmpTrueOrFalse(ifx, tlbl);
5686           } else for(;(size--);offset++){
5687                   // normal case
5688                   // result = left & right
5689                   if(AOP_TYPE(right) == AOP_LIT){
5690                           int t = (lit >> (offset*8)) & 0x0FFL;
5691                           switch(t) { 
5692                           case 0x00:
5693                                   if (AOP_TYPE(left) != AOP_ACC) {
5694                                           emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5695                                   }
5696                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5697                                   
5698                                   break;
5699                           default:
5700                                   if (AOP_TYPE(left) == AOP_ACC) {
5701                                           emitpcode(POC_IORLW,  popGetLit(t));
5702                                   } else {
5703                                           emitpcode(POC_MOVLW,  popGetLit(t));
5704                                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5705                                   }
5706                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5707                           }
5708                           continue;
5709                   }
5710                   
5711                   // faster than result <- left, anl result,right
5712                   // and better if result is SFR
5713                   if (AOP_TYPE(left) == AOP_ACC) {
5714                           emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5715                           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5716                   } else {
5717                           emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5718                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5719                           
5720                           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5721                           pic14_emitcode("iorwf","%s,w",
5722                                   aopGet(AOP(left),offset,FALSE,FALSE));
5723                   }
5724                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5725                   pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5726           }
5727   }
5728   
5729 release :
5730   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5731   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5732   freeAsmop(result,NULL,ic,TRUE);     
5733 }
5734
5735 /*-----------------------------------------------------------------*/
5736 /* genXor - code for xclusive or                                   */
5737 /*-----------------------------------------------------------------*/
5738 static void genXor (iCode *ic, iCode *ifx)
5739 {
5740         operand *left, *right, *result;
5741         int size, offset=0;
5742         unsigned long lit = 0L;
5743         
5744         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5745         
5746         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5747         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5748         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5749         
5750         /* if left is a literal & right is not ||
5751         if left needs acc & right does not */
5752         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5753                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5754                 operand *tmp = right ;
5755                 right = left;
5756                 left = tmp;
5757         }
5758         
5759         /* if result = right then exchange them */
5760         if(pic14_sameRegs(AOP(result),AOP(right))){
5761                 operand *tmp = right ;
5762                 right = left;
5763                 left = tmp;
5764         }
5765         
5766         /* if right is bit then exchange them */
5767         if (AOP_TYPE(right) == AOP_CRY &&
5768                 AOP_TYPE(left) != AOP_CRY){
5769                 operand *tmp = right ;
5770                 right = left;
5771                 left = tmp;
5772         }
5773         if(AOP_TYPE(right) == AOP_LIT)
5774                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5775         
5776         size = AOP_SIZE(result);
5777         
5778         // if(bit ^ yy)
5779         // xx = bit ^ yy;
5780         if (AOP_TYPE(left) == AOP_CRY){
5781                 if(AOP_TYPE(right) == AOP_LIT){
5782                         // c = bit & literal;
5783                         if(lit>>1){
5784                                 // lit>>1  != 0 => result = 1
5785                                 if(AOP_TYPE(result) == AOP_CRY){
5786                                         if(size)
5787                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5788                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5789                                         else if(ifx)
5790                                                 continueIfTrue(ifx);
5791                                         goto release;
5792                                 }
5793                                 pic14_emitcode("setb","c");
5794                         } else{
5795                                 // lit == (0 or 1)
5796                                 if(lit == 0){
5797                                         // lit == 0, result = left
5798                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5799                                                 goto release;
5800                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5801                                 } else{
5802                                         // lit == 1, result = not(left)
5803                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5804                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5805                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5806                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5807                                                 goto release;
5808                                         } else {
5809                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5810                                                 pic14_emitcode("cpl","c");
5811                                         }
5812                                 }
5813                         }
5814                         
5815                 } else {
5816                         // right != literal
5817                         symbol *tlbl = newiTempLabel(NULL);
5818                         if (AOP_TYPE(right) == AOP_CRY){
5819                                 // c = bit ^ bit;
5820                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5821                         }
5822                         else{
5823                                 int sizer = AOP_SIZE(right);
5824                                 // c = bit ^ val
5825                                 // if val>>1 != 0, result = 1
5826                                 pic14_emitcode("setb","c");
5827                                 while(sizer){
5828                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5829                                         if(sizer == 1)
5830                                                 // test the msb of the lsb
5831                                                 pic14_emitcode("anl","a,#0xfe");
5832                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5833                                         sizer--;
5834                                 }
5835                                 // val = (0,1)
5836                                 pic14_emitcode("rrc","a");
5837                         }
5838                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5839                         pic14_emitcode("cpl","c");
5840                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5841                 }
5842                 // bit = c
5843                 // val = c
5844                 if(size)
5845                         pic14_outBitC(result);
5846                 // if(bit | ...)
5847                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5848                         genIfxJump(ifx, "c");           
5849                 goto release ;
5850         }
5851         
5852         if(pic14_sameRegs(AOP(result),AOP(left))){
5853                 /* if left is same as result */
5854                 for(;size--; offset++) {
5855                         if(AOP_TYPE(right) == AOP_LIT){
5856                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5857                                 if(t == 0x00L)
5858                                         continue;
5859                                 else
5860                                         if (IS_AOP_PREG(left)) {
5861                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5862                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5863                                                 aopPut(AOP(result),"a",offset);
5864                                         } else {
5865                                                 emitpcode(POC_MOVLW, popGetLit(t));
5866                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5867                                                 pic14_emitcode("xrl","%s,%s",
5868                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5869                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5870                                         }
5871                         } else {
5872                                 if (AOP_TYPE(left) == AOP_ACC)
5873                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5874                                 else {
5875                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5876                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5877                                         /*
5878                                         if (IS_AOP_PREG(left)) {
5879                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5880                                         aopPut(AOP(result),"a",offset);
5881                                         } else
5882                                         pic14_emitcode("xrl","%s,a",
5883                                         aopGet(AOP(left),offset,FALSE,TRUE));
5884                                         */
5885                                 }
5886                         }
5887                 }
5888         } else {
5889                 // left & result in different registers
5890                 if(AOP_TYPE(result) == AOP_CRY){
5891                         // result = bit
5892                         // if(size), result in bit
5893                         // if(!size && ifx), conditional oper: if(left ^ right)
5894                         symbol *tlbl = newiTempLabel(NULL);
5895                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5896                         if(size)
5897                                 pic14_emitcode("setb","c");
5898                         while(sizer--){
5899                                 if((AOP_TYPE(right) == AOP_LIT) &&
5900                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5901                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5902                                 } else {
5903                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5904                                         pic14_emitcode("xrl","a,%s",
5905                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5906                                 }
5907                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5908                                 offset++;
5909                         }
5910                         if(size){
5911                                 CLRC;
5912                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5913                                 pic14_outBitC(result);
5914                         } else if(ifx)
5915                                 jmpTrueOrFalse(ifx, tlbl);
5916                 } else for(;(size--);offset++){
5917                         // normal case
5918                         // result = left & right
5919                         if(AOP_TYPE(right) == AOP_LIT){
5920                                 int t = (lit >> (offset*8)) & 0x0FFL;
5921                                 switch(t) { 
5922                                 case 0x00:
5923                                         if (AOP_TYPE(left) != AOP_ACC) {
5924                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5925                                         }
5926                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5927                                         pic14_emitcode("movf","%s,w",
5928                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5929                                         pic14_emitcode("movwf","%s",
5930                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5931                                         break;
5932                                 case 0xff:
5933                                         if (AOP_TYPE(left) == AOP_ACC) {
5934                                                 emitpcode(POC_XORLW, popGetLit(t));
5935                                         } else {
5936                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5937                                         }
5938                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5939                                         break;
5940                                 default:
5941                                         if (AOP_TYPE(left) == AOP_ACC) {
5942                                                 emitpcode(POC_XORLW, popGetLit(t));
5943                                         } else {
5944                                                 emitpcode(POC_MOVLW, popGetLit(t));
5945                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5946                                         }
5947                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5948                                         pic14_emitcode("movlw","0x%x",t);
5949                                         pic14_emitcode("xorwf","%s,w",
5950                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5951                                         pic14_emitcode("movwf","%s",
5952                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5953                                         
5954                                 }
5955                                 continue;
5956                         }
5957                         
5958                         // faster than result <- left, anl result,right
5959                         // and better if result is SFR
5960                         if (AOP_TYPE(left) == AOP_ACC) {
5961                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5962                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5963                         } else {
5964                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5965                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5966                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5967                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5968                         }
5969                         if ( AOP_TYPE(result) != AOP_ACC){
5970                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5971                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5972                         }
5973                 }
5974         }
5975         
5976 release :
5977         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5978         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5979         freeAsmop(result,NULL,ic,TRUE);     
5980 }
5981
5982 /*-----------------------------------------------------------------*/
5983 /* genInline - write the inline code out                           */
5984 /*-----------------------------------------------------------------*/
5985 static void genInline (iCode *ic)
5986 {
5987         char *buffer, *bp, *bp1;
5988         
5989         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5990         
5991         _G.inLine += (!options.asmpeep);
5992         
5993         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5994         strcpy(buffer,IC_INLINE(ic));
5995         
5996         /* emit each line as a code */
5997         while (*bp) {
5998                 if (*bp == '\n') {
5999                         *bp++ = '\0';
6000                         
6001                         if(*bp1)
6002                                 addpCode2pBlock(pb,AssembleLine(bp1));
6003                         bp1 = bp;
6004                 } else {
6005                         if (*bp == ':') {
6006                                 bp++;
6007                                 *bp = '\0';
6008                                 bp++;
6009                                 pic14_emitcode(bp1,"");
6010                                 bp1 = bp;
6011                         } else
6012                                 bp++;
6013                 }
6014         }
6015         if ((bp1 != bp) && *bp1)
6016                 addpCode2pBlock(pb,AssembleLine(bp1));
6017         
6018         Safe_free(buffer);
6019         
6020         _G.inLine -= (!options.asmpeep);
6021 }
6022
6023 /*-----------------------------------------------------------------*/
6024 /* genRRC - rotate right with carry                                */
6025 /*-----------------------------------------------------------------*/
6026 static void genRRC (iCode *ic)
6027 {
6028         operand *left , *result ;
6029         int size, offset = 0, same;
6030         
6031         /* rotate right with carry */
6032         left = IC_LEFT(ic);
6033         result=IC_RESULT(ic);
6034         aopOp (left,ic,FALSE);
6035         aopOp (result,ic,FALSE);
6036         
6037         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6038         
6039         same = pic14_sameRegs(AOP(result),AOP(left));
6040         
6041         size = AOP_SIZE(result);    
6042         
6043         /* get the lsb and put it into the carry */
6044         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6045         
6046         offset = 0 ;
6047         
6048         while(size--) {
6049                 
6050                 if(same) {
6051                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6052                 } else {
6053                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6054                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6055                 }
6056                 
6057                 offset++;
6058         }
6059         
6060         freeAsmop(left,NULL,ic,TRUE);
6061         freeAsmop(result,NULL,ic,TRUE);
6062 }
6063
6064 /*-----------------------------------------------------------------*/
6065 /* genRLC - generate code for rotate left with carry               */
6066 /*-----------------------------------------------------------------*/
6067 static void genRLC (iCode *ic)
6068 {    
6069         operand *left , *result ;
6070         int size, offset = 0;
6071         int same;
6072         
6073         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6074         /* rotate right with carry */
6075         left = IC_LEFT(ic);
6076         result=IC_RESULT(ic);
6077         aopOp (left,ic,FALSE);
6078         aopOp (result,ic,FALSE);
6079         
6080         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6081         
6082         same = pic14_sameRegs(AOP(result),AOP(left));
6083         
6084         /* move it to the result */
6085         size = AOP_SIZE(result);    
6086         
6087         /* get the msb and put it into the carry */
6088         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6089         
6090         offset = 0 ;
6091         
6092         while(size--) {
6093                 
6094                 if(same) {
6095                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6096                 } else {
6097                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6098                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6099                 }
6100                 
6101                 offset++;
6102         }
6103         
6104         
6105         freeAsmop(left,NULL,ic,TRUE);
6106         freeAsmop(result,NULL,ic,TRUE);
6107 }
6108
6109 /*-----------------------------------------------------------------*/
6110 /* genGetHbit - generates code get highest order bit               */
6111 /*-----------------------------------------------------------------*/
6112 static void genGetHbit (iCode *ic)
6113 {
6114         operand *left, *result;
6115         left = IC_LEFT(ic);
6116         result=IC_RESULT(ic);
6117         aopOp (left,ic,FALSE);
6118         aopOp (result,ic,FALSE);
6119         
6120         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6121         /* get the highest order byte into a */
6122         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6123         if(AOP_TYPE(result) == AOP_CRY){
6124                 pic14_emitcode("rlc","a");
6125                 pic14_outBitC(result);
6126         }
6127         else{
6128                 pic14_emitcode("rl","a");
6129                 pic14_emitcode("anl","a,#0x01");
6130                 pic14_outAcc(result);
6131         }
6132         
6133         
6134         freeAsmop(left,NULL,ic,TRUE);
6135         freeAsmop(result,NULL,ic,TRUE);
6136 }
6137
6138 /*-----------------------------------------------------------------*/
6139 /* AccRol - rotate left accumulator by known count                 */
6140 /*-----------------------------------------------------------------*/
6141 static void AccRol (int shCount)
6142 {
6143         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6144         shCount &= 0x0007;              // shCount : 0..7
6145         switch(shCount){
6146         case 0 :
6147                 break;
6148         case 1 :
6149                 pic14_emitcode("rl","a");
6150                 break;
6151         case 2 :
6152                 pic14_emitcode("rl","a");
6153                 pic14_emitcode("rl","a");
6154                 break;
6155         case 3 :
6156                 pic14_emitcode("swap","a");
6157                 pic14_emitcode("rr","a");
6158                 break;
6159         case 4 :
6160                 pic14_emitcode("swap","a");
6161                 break;
6162         case 5 :
6163                 pic14_emitcode("swap","a");
6164                 pic14_emitcode("rl","a");
6165                 break;
6166         case 6 :
6167                 pic14_emitcode("rr","a");
6168                 pic14_emitcode("rr","a");
6169                 break;
6170         case 7 :
6171                 pic14_emitcode("rr","a");
6172                 break;
6173         }
6174 }
6175
6176 /*-----------------------------------------------------------------*/
6177 /* AccLsh - left shift accumulator by known count                  */
6178 /*-----------------------------------------------------------------*/
6179 static void AccLsh (int shCount)
6180 {
6181         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6182         if(shCount != 0){
6183                 if(shCount == 1)
6184                         pic14_emitcode("add","a,acc");
6185                 else 
6186                         if(shCount == 2) {
6187                                 pic14_emitcode("add","a,acc");
6188                                 pic14_emitcode("add","a,acc");
6189                         } else {
6190                                 /* rotate left accumulator */
6191                                 AccRol(shCount);
6192                                 /* and kill the lower order bits */
6193                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6194                         }
6195         }
6196 }
6197
6198 /*-----------------------------------------------------------------*/
6199 /* AccRsh - right shift accumulator by known count                 */
6200 /*-----------------------------------------------------------------*/
6201 static void AccRsh (int shCount)
6202 {
6203         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6204         if(shCount != 0){
6205                 if(shCount == 1){
6206                         CLRC;
6207                         pic14_emitcode("rrc","a");
6208                 } else {
6209                         /* rotate right accumulator */
6210                         AccRol(8 - shCount);
6211                         /* and kill the higher order bits */
6212                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6213                 }
6214         }
6215 }
6216
6217 #if 0
6218 /*-----------------------------------------------------------------*/
6219 /* AccSRsh - signed right shift accumulator by known count                 */
6220 /*-----------------------------------------------------------------*/
6221 static void AccSRsh (int shCount)
6222 {
6223         symbol *tlbl ;
6224         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6225         if(shCount != 0){
6226                 if(shCount == 1){
6227                         pic14_emitcode("mov","c,acc.7");
6228                         pic14_emitcode("rrc","a");
6229                 } else if(shCount == 2){
6230                         pic14_emitcode("mov","c,acc.7");
6231                         pic14_emitcode("rrc","a");
6232                         pic14_emitcode("mov","c,acc.7");
6233                         pic14_emitcode("rrc","a");
6234                 } else {
6235                         tlbl = newiTempLabel(NULL);
6236                         /* rotate right accumulator */
6237                         AccRol(8 - shCount);
6238                         /* and kill the higher order bits */
6239                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6240                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6241                         pic14_emitcode("orl","a,#0x%02x",
6242                                 (unsigned char)~SRMask[shCount]);
6243                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6244                 }
6245         }
6246 }
6247 #endif
6248 /*-----------------------------------------------------------------*/
6249 /* shiftR1Left2Result - shift right one byte from left to result   */
6250 /*-----------------------------------------------------------------*/
6251 static void shiftR1Left2ResultSigned (operand *left, int offl,
6252                                                                           operand *result, int offr,
6253                                                                           int shCount)
6254 {
6255         int same;
6256         
6257         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6258         
6259         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6260         
6261         switch(shCount) {
6262         case 1:
6263                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6264                 if(same) 
6265                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6266                 else {
6267                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6268                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6269                 }
6270                 
6271                 break;
6272         case 2:
6273                 
6274                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6275                 if(same) 
6276                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6277                 else {
6278                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6279                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6280                 }
6281                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6282                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6283                 
6284                 break;
6285                 
6286         case 3:
6287                 if(same)
6288                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6289                 else {
6290                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6291                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6292                 }
6293                 
6294                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6295                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6296                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6297                 
6298                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6299                 emitpcode(POC_IORLW, popGetLit(0xe0));
6300                 
6301                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6302                 break;
6303                 
6304         case 4:
6305                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6306                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6307                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6308                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6309                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6310                 break;
6311         case 5:
6312                 if(same) {
6313                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6314                 } else {
6315                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6316                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6317                 }
6318                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6319                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6320                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6321                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6322                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6323                 break;
6324                 
6325         case 6:
6326                 if(same) {
6327                         emitpcode(POC_MOVLW, popGetLit(0x00));
6328                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6329                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6330                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6331                         emitpcode(POC_IORLW, popGetLit(0x01));
6332                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6333                 } else {
6334                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6335                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6336                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6337                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6338                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6339                 }
6340                 break;
6341                 
6342         case 7:
6343                 if(same) {
6344                         emitpcode(POC_MOVLW, popGetLit(0x00));
6345                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6346                         emitpcode(POC_MOVLW, popGetLit(0xff));
6347                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6348                 } else {
6349                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6350                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6351                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6352                 }
6353                 
6354         default:
6355                 break;
6356         }
6357 }
6358
6359 /*-----------------------------------------------------------------*/
6360 /* shiftR1Left2Result - shift right one byte from left to result   */
6361 /*-----------------------------------------------------------------*/
6362 static void shiftR1Left2Result (operand *left, int offl,
6363                                                                 operand *result, int offr,
6364                                                                 int shCount, int sign)
6365 {
6366         int same;
6367         
6368         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6369         
6370         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6371         
6372         /* Copy the msb into the carry if signed. */
6373         if(sign) {
6374                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6375                 return;
6376         }
6377         
6378         
6379         
6380         switch(shCount) {
6381         case 1:
6382                 emitCLRC;
6383                 if(same) 
6384                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6385                 else {
6386                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6387                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6388                 }
6389                 break;
6390         case 2:
6391                 emitCLRC;
6392                 if(same) {
6393                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6394                 } else {
6395                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6396                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6397                 }
6398                 emitCLRC;
6399                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6400                 
6401                 break;
6402         case 3:
6403                 if(same)
6404                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6405                 else {
6406                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6407                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6408                 }
6409                 
6410                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6411                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6412                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6413                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6414                 break;
6415                 
6416         case 4:
6417                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6418                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6419                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6420                 break;
6421                 
6422         case 5:
6423                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6424                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6425                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6426                 emitCLRC;
6427                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6428                 
6429                 break;
6430         case 6:
6431                 
6432                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6433                 emitpcode(POC_ANDLW, popGetLit(0x80));
6434                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6435                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6436                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6437                 break;
6438                 
6439         case 7:
6440                 
6441                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6442                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6443                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6444                 
6445                 break;
6446                 
6447         default:
6448                 break;
6449         }
6450 }
6451
6452 /*-----------------------------------------------------------------*/
6453 /* shiftL1Left2Result - shift left one byte from left to result    */
6454 /*-----------------------------------------------------------------*/
6455 static void shiftL1Left2Result (operand *left, int offl,
6456                                                                 operand *result, int offr, int shCount)
6457 {
6458         int same;
6459         
6460         //    char *l;
6461         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6462         
6463         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6464         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6465         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6466         //    MOVA(l);
6467         /* shift left accumulator */
6468         //AccLsh(shCount); // don't comment out just yet...
6469         //    aopPut(AOP(result),"a",offr);
6470         
6471         switch(shCount) {
6472         case 1:
6473                 /* Shift left 1 bit position */
6474                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6475                 if(same) {
6476                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6477                 } else {
6478                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6479                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6480                 }
6481                 break;
6482         case 2:
6483                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6484                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6485                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6486                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6487                 break;
6488         case 3:
6489                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6490                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6491                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6492                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6493                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6494                 break;
6495         case 4:
6496                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6497                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6498                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6499                 break;
6500         case 5:
6501                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6502                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6503                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6504                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6505                 break;
6506         case 6:
6507                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6508                 emitpcode(POC_ANDLW, popGetLit(0x30));
6509                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6510                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6511                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6512                 break;
6513         case 7:
6514                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6515                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6516                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6517                 break;
6518                 
6519         default:
6520                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6521         }
6522         
6523 }
6524
6525 /*-----------------------------------------------------------------*/
6526 /* movLeft2Result - move byte from left to result                  */
6527 /*-----------------------------------------------------------------*/
6528 static void movLeft2Result (operand *left, int offl,
6529                                                         operand *result, int offr)
6530 {
6531         char *l;
6532         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6533         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6534                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6535                 
6536                 if (*l == '@' && (IS_AOP_PREG(result))) {
6537                         pic14_emitcode("mov","a,%s",l);
6538                         aopPut(AOP(result),"a",offr);
6539                 } else {
6540                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6541                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6542                 }
6543         }
6544 }
6545
6546 /*-----------------------------------------------------------------*/
6547 /* shiftL2Left2Result - shift left two bytes from left to result   */
6548 /*-----------------------------------------------------------------*/
6549 static void shiftL2Left2Result (operand *left, int offl,
6550                                                                 operand *result, int offr, int shCount)
6551 {
6552         
6553         
6554         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6555         
6556         if(pic14_sameRegs(AOP(result), AOP(left))) {
6557                 switch(shCount) {
6558                 case 0:
6559                         break;
6560                 case 1:
6561                 case 2:
6562                 case 3:
6563                         
6564                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6565                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6566                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6567                         
6568                         while(--shCount) {
6569                                 emitCLRC;
6570                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6571                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6572                         }
6573                         
6574                         break;
6575                 case 4:
6576                 case 5:
6577                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6578                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6579                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6580                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6581                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6582                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6583                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6584                         if(shCount >=5) {
6585                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6586                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6587                         }
6588                         break;
6589                 case 6:
6590                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6591                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6592                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6593                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6594                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6595                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6596                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6597                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6598                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6599                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6600                         break;
6601                 case 7:
6602                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6603                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6604                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6605                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6606                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6607                 }
6608                 
6609         } else {
6610                 switch(shCount) {
6611                 case 0:
6612                         break;
6613                 case 1:
6614                 case 2:
6615                 case 3:
6616                 /* note, use a mov/add for the shift since the mov has a
6617                         chance of getting optimized out */
6618                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6619                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6620                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6621                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6622                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6623                         
6624                         while(--shCount) {
6625                                 emitCLRC;
6626                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6627                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6628                         }
6629                         break;
6630                         
6631                 case 4:
6632                 case 5:
6633                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6634                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6635                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6636                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6637                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6638                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6639                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6640                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6641                         
6642                         
6643                         if(shCount == 5) {
6644                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6645                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6646                         }
6647                         break;
6648                 case 6:
6649                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6650                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6651                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6652                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6653                         
6654                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6655                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6656                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6657                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6658                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6659                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6660                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6661                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6662                         break;
6663                 case 7:
6664                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6665                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6666                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6667                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6668                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6669                 }
6670         }
6671         
6672 }
6673 /*-----------------------------------------------------------------*/
6674 /* shiftR2Left2Result - shift right two bytes from left to result  */
6675 /*-----------------------------------------------------------------*/
6676 static void shiftR2Left2Result (operand *left, int offl,
6677                                                                 operand *result, int offr,
6678                                                                 int shCount, int sign)
6679 {
6680         int same=0;
6681         
6682         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6683         same = pic14_sameRegs(AOP(result), AOP(left));
6684         
6685         if(same && ((offl + MSB16) == offr)){
6686                 same=1;
6687                 /* don't crash result[offr] */
6688                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6689                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6690         }
6691         /* else {
6692         movLeft2Result(left,offl, result, offr);
6693         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6694         }
6695         */
6696         /* a:x >> shCount (x = lsb(result))*/
6697         /*
6698         if(sign)
6699         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6700         else {
6701         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6702         */
6703         switch(shCount) {
6704         case 0:
6705                 break;
6706         case 1:
6707         case 2:
6708         case 3:
6709                 if(sign)
6710                         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6711                 else
6712                         emitCLRC;
6713                 
6714                 if(same) {
6715                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6716                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6717                 } else {
6718                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6719                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6720                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6721                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6722                 }
6723                 
6724                 while(--shCount) {
6725                         if(sign)
6726                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6727                         else
6728                                 emitCLRC;
6729                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6730                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6731                 }
6732                 break;
6733         case 4:
6734         case 5:
6735                 if(same) {
6736                         
6737                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6738                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6739                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6740                         
6741                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6742                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6743                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6744                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6745                 } else {
6746                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6747                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6748                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6749                         
6750                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6751                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6752                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6753                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6754                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6755                 }
6756                 
6757                 if(shCount >=5) {
6758                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6759                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6760                 }
6761                 
6762                 if(sign) {
6763                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6764                         emitpcode(POC_BTFSC, 
6765                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6766                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6767                 }
6768                 
6769                 break;
6770                 
6771         case 6:
6772                 if(same) {
6773                         
6774                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6775                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6776                         
6777                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6778                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6779                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6780                         emitpcode(POC_ANDLW,popGetLit(0x03));
6781                         if(sign) {
6782                                 emitpcode(POC_BTFSC, 
6783                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6784                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6785                         }
6786                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6787                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6788                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6789                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6790                 } else {
6791                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6792                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6793                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6794                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6795                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6796                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6797                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6798                         emitpcode(POC_ANDLW,popGetLit(0x03));
6799                         if(sign) {
6800                                 emitpcode(POC_BTFSC, 
6801                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6802                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6803                         }
6804                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6805                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6806                         
6807                         
6808                 }
6809                 
6810                 break;
6811         case 7:
6812                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6813                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6814                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6815                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6816                 if(sign) {
6817                         emitSKPNC;
6818                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6819                 } else 
6820                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6821   }
6822 }
6823
6824
6825 /*-----------------------------------------------------------------*/
6826 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6827 /*-----------------------------------------------------------------*/
6828 static void shiftLLeftOrResult (operand *left, int offl,
6829                                                                 operand *result, int offr, int shCount)
6830 {
6831         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6832         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6833         /* shift left accumulator */
6834         AccLsh(shCount);
6835         /* or with result */
6836         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6837         /* back to result */
6838         aopPut(AOP(result),"a",offr);
6839 }
6840
6841 /*-----------------------------------------------------------------*/
6842 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6843 /*-----------------------------------------------------------------*/
6844 static void shiftRLeftOrResult (operand *left, int offl,
6845                                                                 operand *result, int offr, int shCount)
6846 {
6847         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6848         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6849         /* shift right accumulator */
6850         AccRsh(shCount);
6851         /* or with result */
6852         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6853         /* back to result */
6854         aopPut(AOP(result),"a",offr);
6855 }
6856
6857 /*-----------------------------------------------------------------*/
6858 /* genlshOne - left shift a one byte quantity by known count       */
6859 /*-----------------------------------------------------------------*/
6860 static void genlshOne (operand *result, operand *left, int shCount)
6861 {       
6862         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6863         shiftL1Left2Result(left, LSB, result, LSB, shCount);
6864 }
6865
6866 /*-----------------------------------------------------------------*/
6867 /* genlshTwo - left shift two bytes by known amount != 0           */
6868 /*-----------------------------------------------------------------*/
6869 static void genlshTwo (operand *result,operand *left, int shCount)
6870 {
6871         int size;
6872         
6873         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6874         size = pic14_getDataSize(result);
6875         
6876         /* if shCount >= 8 */
6877         if (shCount >= 8) {
6878                 shCount -= 8 ;
6879                 
6880                 if (size > 1){
6881                         if (shCount)
6882                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6883                         else 
6884                                 movLeft2Result(left, LSB, result, MSB16);
6885                 }
6886                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6887         }
6888         
6889         /*  1 <= shCount <= 7 */
6890         else {  
6891                 if(size == 1)
6892                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6893                 else 
6894                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6895         }
6896 }
6897
6898 /*-----------------------------------------------------------------*/
6899 /* shiftLLong - shift left one long from left to result            */
6900 /* offl = LSB or MSB16                                             */
6901 /*-----------------------------------------------------------------*/
6902 static void shiftLLong (operand *left, operand *result, int offr )
6903 {
6904         char *l;
6905         int size = AOP_SIZE(result);
6906         
6907         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6908         if(size >= LSB+offr){
6909                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6910                 MOVA(l);
6911                 pic14_emitcode("add","a,acc");
6912                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6913                         size >= MSB16+offr && offr != LSB )
6914                         pic14_emitcode("xch","a,%s",
6915                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6916                 else      
6917                         aopPut(AOP(result),"a",LSB+offr);
6918         }
6919         
6920         if(size >= MSB16+offr){
6921                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6922                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6923                         MOVA(l);
6924                 }
6925                 pic14_emitcode("rlc","a");
6926                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6927                         size >= MSB24+offr && offr != LSB)
6928                         pic14_emitcode("xch","a,%s",
6929                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6930                 else      
6931                         aopPut(AOP(result),"a",MSB16+offr);
6932         }
6933         
6934         if(size >= MSB24+offr){
6935                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6936                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6937                         MOVA(l);
6938                 }
6939                 pic14_emitcode("rlc","a");
6940                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6941                         size >= MSB32+offr && offr != LSB )
6942                         pic14_emitcode("xch","a,%s",
6943                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6944                 else      
6945                         aopPut(AOP(result),"a",MSB24+offr);
6946         }
6947         
6948         if(size > MSB32+offr){
6949                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6950                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6951                         MOVA(l);  
6952                 }
6953                 pic14_emitcode("rlc","a");
6954                 aopPut(AOP(result),"a",MSB32+offr);
6955         }
6956         if(offr != LSB)
6957                 aopPut(AOP(result),zero,LSB);       
6958 }
6959
6960 /*-----------------------------------------------------------------*/
6961 /* genlshFour - shift four byte by a known amount != 0             */
6962 /*-----------------------------------------------------------------*/
6963 static void genlshFour (operand *result, operand *left, int shCount)
6964 {
6965         int size;
6966         
6967         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6968         size = AOP_SIZE(result);
6969         
6970         /* if shifting more that 3 bytes */
6971         if (shCount >= 24 ) {
6972                 shCount -= 24;
6973                 if (shCount)
6974                 /* lowest order of left goes to the highest
6975                 order of the destination */
6976                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6977                 else
6978                         movLeft2Result(left, LSB, result, MSB32);
6979                 aopPut(AOP(result),zero,LSB);
6980                 aopPut(AOP(result),zero,MSB16);
6981                 aopPut(AOP(result),zero,MSB32);
6982                 return;
6983         }
6984         
6985         /* more than two bytes */
6986         else if ( shCount >= 16 ) {
6987                 /* lower order two bytes goes to higher order two bytes */
6988                 shCount -= 16;
6989                 /* if some more remaining */
6990                 if (shCount)
6991                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6992                 else {
6993                         movLeft2Result(left, MSB16, result, MSB32);
6994                         movLeft2Result(left, LSB, result, MSB24);
6995                 }
6996                 aopPut(AOP(result),zero,MSB16);
6997                 aopPut(AOP(result),zero,LSB);
6998                 return;
6999         }    
7000         
7001         /* if more than 1 byte */
7002         else if ( shCount >= 8 ) {
7003                 /* lower order three bytes goes to higher order  three bytes */
7004                 shCount -= 8;
7005                 if(size == 2){
7006                         if(shCount)
7007                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7008                         else
7009                                 movLeft2Result(left, LSB, result, MSB16);
7010                 }
7011                 else{   /* size = 4 */
7012                         if(shCount == 0){
7013                                 movLeft2Result(left, MSB24, result, MSB32);
7014                                 movLeft2Result(left, MSB16, result, MSB24);
7015                                 movLeft2Result(left, LSB, result, MSB16);
7016                                 aopPut(AOP(result),zero,LSB);
7017                         }
7018                         else if(shCount == 1)
7019                                 shiftLLong(left, result, MSB16);
7020                         else{
7021                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7022                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7023                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7024                                 aopPut(AOP(result),zero,LSB);
7025                         }
7026                 }
7027         }
7028         
7029         /* 1 <= shCount <= 7 */
7030         else if(shCount <= 2){
7031                 shiftLLong(left, result, LSB);
7032                 if(shCount == 2)
7033                         shiftLLong(result, result, LSB);
7034         }
7035         /* 3 <= shCount <= 7, optimize */
7036         else{
7037                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7038                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7039                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7040         }
7041 }
7042
7043 /*-----------------------------------------------------------------*/
7044 /* genLeftShiftLiteral - left shifting by known count              */
7045 /*-----------------------------------------------------------------*/
7046 static void genLeftShiftLiteral (operand *left,
7047                                                                  operand *right,
7048                                                                  operand *result,
7049                                                                  iCode *ic)
7050 {    
7051         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7052         int size;
7053         
7054         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7055         freeAsmop(right,NULL,ic,TRUE);
7056         
7057         aopOp(left,ic,FALSE);
7058         aopOp(result,ic,FALSE);
7059         
7060         size = getSize(operandType(result));
7061         
7062 #if VIEW_SIZE
7063         pic14_emitcode("; shift left ","result %d, left %d",size,
7064                 AOP_SIZE(left));
7065 #endif
7066         
7067         /* I suppose that the left size >= result size */
7068         if(shCount == 0){
7069                 while(size--){
7070                         movLeft2Result(left, size, result, size);
7071                 }
7072         }
7073         
7074         else if(shCount >= (size * 8))
7075                 while(size--)
7076                         aopPut(AOP(result),zero,size);
7077                 else{
7078                         switch (size) {
7079                         case 1:
7080                                 genlshOne (result,left,shCount);
7081                                 break;
7082                                 
7083                         case 2:
7084                         case 3:
7085                                 genlshTwo (result,left,shCount);
7086                                 break;
7087                                 
7088                         case 4:
7089                                 genlshFour (result,left,shCount);
7090                                 break;
7091                         }
7092                 }
7093                 freeAsmop(left,NULL,ic,TRUE);
7094                 freeAsmop(result,NULL,ic,TRUE);
7095 }
7096
7097 /*-----------------------------------------------------------------*
7098 * genMultiAsm - repeat assembly instruction for size of register.
7099 * if endian == 1, then the high byte (i.e base address + size of 
7100 * register) is used first else the low byte is used first;
7101 *-----------------------------------------------------------------*/
7102 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7103 {
7104         
7105         int offset = 0;
7106         
7107         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7108         
7109         if(!reg)
7110                 return;
7111         
7112         if(!endian) {
7113                 endian = 1;
7114         } else {
7115                 endian = -1;
7116                 offset = size-1;
7117         }
7118         
7119         while(size--) {
7120                 emitpcode(poc,    popGet(AOP(reg),offset));
7121                 offset += endian;
7122         }
7123         
7124 }
7125 /*-----------------------------------------------------------------*/
7126 /* genLeftShift - generates code for left shifting                 */
7127 /*-----------------------------------------------------------------*/
7128 static void genLeftShift (iCode *ic)
7129 {
7130         operand *left,*right, *result;
7131         int size, offset;
7132         char *l;
7133         symbol *tlbl , *tlbl1;
7134         pCodeOp *pctemp;
7135         
7136         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7137         
7138         right = IC_RIGHT(ic);
7139         left  = IC_LEFT(ic);
7140         result = IC_RESULT(ic);
7141         
7142         aopOp(right,ic,FALSE);
7143         
7144         /* if the shift count is known then do it 
7145         as efficiently as possible */
7146         if (AOP_TYPE(right) == AOP_LIT) {
7147                 genLeftShiftLiteral (left,right,result,ic);
7148                 return ;
7149         }
7150         
7151         /* shift count is unknown then we have to form 
7152         a loop get the loop count in B : Note: we take
7153         only the lower order byte since shifting
7154         more that 32 bits make no sense anyway, ( the
7155         largest size of an object can be only 32 bits ) */  
7156         
7157         
7158         aopOp(left,ic,FALSE);
7159         aopOp(result,ic,FALSE);
7160         
7161         /* now move the left to the result if they are not the
7162         same */
7163         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7164                 AOP_SIZE(result) > 1) {
7165                 
7166                 size = AOP_SIZE(result);
7167                 offset=0;
7168                 while (size--) {
7169                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7170                         if (*l == '@' && (IS_AOP_PREG(result))) {
7171                                 
7172                                 pic14_emitcode("mov","a,%s",l);
7173                                 aopPut(AOP(result),"a",offset);
7174                         } else {
7175                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7176                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7177                                 //aopPut(AOP(result),l,offset);
7178                         }
7179                         offset++;
7180                 }
7181         }
7182         
7183         size = AOP_SIZE(result);
7184         
7185         /* if it is only one byte then */
7186         if (size == 1) {
7187                 if(optimized_for_speed) {
7188                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7189                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7190                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7191                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7192                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7193                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7194                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7195                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7196                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7197                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7198                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7199                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7200                 } else {
7201                         
7202                         tlbl = newiTempLabel(NULL);
7203                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7204                                 emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7205                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7206                         }
7207                         
7208                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7209                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7210                         emitpLabel(tlbl->key);
7211                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7212                         emitpcode(POC_ADDLW,  popGetLit(1));
7213                         emitSKPC;
7214                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7215                 }
7216                 goto release ;
7217         }
7218         
7219         if (pic14_sameRegs(AOP(left),AOP(result))) {
7220                 
7221                 tlbl = newiTempLabel(NULL);
7222                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7223                 genMultiAsm(POC_RRF, result, size,1);
7224                 emitpLabel(tlbl->key);
7225                 genMultiAsm(POC_RLF, result, size,0);
7226                 emitpcode(POC_ADDLW,  popGetLit(1));
7227                 emitSKPC;
7228                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7229                 goto release;
7230         }
7231         
7232         //tlbl = newiTempLabel(NULL);
7233         //offset = 0 ;   
7234         //tlbl1 = newiTempLabel(NULL);
7235         
7236         //reAdjustPreg(AOP(result));    
7237         
7238         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7239         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7240         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7241         //MOVA(l);
7242         //pic14_emitcode("add","a,acc");         
7243         //aopPut(AOP(result),"a",offset++);
7244         //while (--size) {
7245         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7246         //  MOVA(l);
7247         //  pic14_emitcode("rlc","a");         
7248         //  aopPut(AOP(result),"a",offset++);
7249         //}
7250         //reAdjustPreg(AOP(result));
7251         
7252         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7253         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7254         
7255         
7256         tlbl = newiTempLabel(NULL);
7257         tlbl1= newiTempLabel(NULL);
7258         
7259         size = AOP_SIZE(result);
7260         offset = 1;
7261         
7262         pctemp = popGetTempReg();  /* grab a temporary working register. */
7263         
7264         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7265         
7266         /* offset should be 0, 1 or 3 */
7267         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7268         emitSKPNZ;
7269         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7270         
7271         emitpcode(POC_MOVWF, pctemp);
7272         
7273         
7274         emitpLabel(tlbl->key);
7275         
7276         emitCLRC;
7277         emitpcode(POC_RLF,  popGet(AOP(result),0));
7278         while(--size)
7279                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7280         
7281         emitpcode(POC_DECFSZ,  pctemp);
7282         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7283         emitpLabel(tlbl1->key);
7284         
7285         popReleaseTempReg(pctemp);
7286         
7287         
7288 release:
7289         freeAsmop (right,NULL,ic,TRUE);
7290         freeAsmop(left,NULL,ic,TRUE);
7291         freeAsmop(result,NULL,ic,TRUE);
7292 }
7293
7294 /*-----------------------------------------------------------------*/
7295 /* genrshOne - right shift a one byte quantity by known count      */
7296 /*-----------------------------------------------------------------*/
7297 static void genrshOne (operand *result, operand *left,
7298                                            int shCount, int sign)
7299 {
7300         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7301         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7302 }
7303
7304 /*-----------------------------------------------------------------*/
7305 /* genrshTwo - right shift two bytes by known amount != 0          */
7306 /*-----------------------------------------------------------------*/
7307 static void genrshTwo (operand *result,operand *left,
7308                                            int shCount, int sign)
7309 {
7310         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7311         /* if shCount >= 8 */
7312         if (shCount >= 8) {
7313                 shCount -= 8 ;
7314                 if (shCount)
7315                         shiftR1Left2Result(left, MSB16, result, LSB,
7316                         shCount, sign);
7317                 else
7318                         movLeft2Result(left, MSB16, result, LSB);
7319                 
7320                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7321                 
7322                 if(sign) {
7323                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7324                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7325                 }
7326         }
7327         
7328         /*  1 <= shCount <= 7 */
7329         else
7330                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7331 }
7332
7333 /*-----------------------------------------------------------------*/
7334 /* shiftRLong - shift right one long from left to result           */
7335 /* offl = LSB or MSB16                                             */
7336 /*-----------------------------------------------------------------*/
7337 static void shiftRLong (operand *left, int offl,
7338                                                 operand *result, int sign)
7339 {
7340         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7341         if(!sign)
7342                 pic14_emitcode("clr","c");
7343         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7344         if(sign)
7345                 pic14_emitcode("mov","c,acc.7");
7346         pic14_emitcode("rrc","a");
7347         aopPut(AOP(result),"a",MSB32-offl);
7348         if(offl == MSB16)
7349                 /* add sign of "a" */
7350                 addSign(result, MSB32, sign);
7351         
7352         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7353         pic14_emitcode("rrc","a");
7354         aopPut(AOP(result),"a",MSB24-offl);
7355         
7356         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7357         pic14_emitcode("rrc","a");
7358         aopPut(AOP(result),"a",MSB16-offl);
7359         
7360         if(offl == LSB){
7361                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7362                 pic14_emitcode("rrc","a");
7363                 aopPut(AOP(result),"a",LSB);
7364         }
7365 }
7366
7367 /*-----------------------------------------------------------------*/
7368 /* genrshFour - shift four byte by a known amount != 0             */
7369 /*-----------------------------------------------------------------*/
7370 static void genrshFour (operand *result, operand *left,
7371                                                 int shCount, int sign)
7372 {
7373         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7374         /* if shifting more that 3 bytes */
7375         if(shCount >= 24 ) {
7376                 shCount -= 24;
7377                 if(shCount)
7378                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7379                 else
7380                         movLeft2Result(left, MSB32, result, LSB);
7381                 
7382                 addSign(result, MSB16, sign);
7383         }
7384         else if(shCount >= 16){
7385                 shCount -= 16;
7386                 if(shCount)
7387                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7388                 else{
7389                         movLeft2Result(left, MSB24, result, LSB);
7390                         movLeft2Result(left, MSB32, result, MSB16);
7391                 }
7392                 addSign(result, MSB24, sign);
7393         }
7394         else if(shCount >= 8){
7395                 shCount -= 8;
7396                 if(shCount == 1)
7397                         shiftRLong(left, MSB16, result, sign);
7398                 else if(shCount == 0){
7399                         movLeft2Result(left, MSB16, result, LSB);
7400                         movLeft2Result(left, MSB24, result, MSB16);
7401                         movLeft2Result(left, MSB32, result, MSB24);
7402                         addSign(result, MSB32, sign);
7403                 }
7404                 else{
7405                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7406                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7407                         /* the last shift is signed */
7408                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7409                         addSign(result, MSB32, sign);
7410                 }
7411         }
7412         else{   /* 1 <= shCount <= 7 */
7413                 if(shCount <= 2){
7414                         shiftRLong(left, LSB, result, sign);
7415                         if(shCount == 2)
7416                                 shiftRLong(result, LSB, result, sign);
7417                 }
7418                 else{
7419                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7420                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7421                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7422                 }
7423         }
7424 }
7425
7426 /*-----------------------------------------------------------------*/
7427 /* genRightShiftLiteral - right shifting by known count            */
7428 /*-----------------------------------------------------------------*/
7429 static void genRightShiftLiteral (operand *left,
7430                                                                   operand *right,
7431                                                                   operand *result,
7432                                                                   iCode *ic,
7433                                                                   int sign)
7434 {    
7435         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7436         int lsize,res_size;
7437         
7438         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7439         freeAsmop(right,NULL,ic,TRUE);
7440         
7441         aopOp(left,ic,FALSE);
7442         aopOp(result,ic,FALSE);
7443         
7444 #if VIEW_SIZE
7445         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7446                 AOP_SIZE(left));
7447 #endif
7448         
7449         lsize = pic14_getDataSize(left);
7450         res_size = pic14_getDataSize(result);
7451         /* test the LEFT size !!! */
7452         
7453         /* I suppose that the left size >= result size */
7454         if(shCount == 0){
7455                 while(res_size--)
7456                         movLeft2Result(left, lsize, result, res_size);
7457         }
7458         
7459         else if(shCount >= (lsize * 8)){
7460                 
7461                 if(res_size == 1) {
7462                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7463                         if(sign) {
7464                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7465                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7466                         }
7467                 } else {
7468                         
7469                         if(sign) {
7470                                 emitpcode(POC_MOVLW, popGetLit(0));
7471                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7472                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7473                                 while(res_size--)
7474                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7475                                 
7476                         } else {
7477                                 
7478                                 while(res_size--)
7479                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7480                         }
7481                 }
7482         } else {
7483                 
7484                 switch (res_size) {
7485                 case 1:
7486                         genrshOne (result,left,shCount,sign);
7487                         break;
7488                         
7489                 case 2:
7490                         genrshTwo (result,left,shCount,sign);
7491                         break;
7492                         
7493                 case 4:
7494                         genrshFour (result,left,shCount,sign);
7495                         break;
7496                 default :
7497                         break;
7498                 }
7499                 
7500         }
7501         
7502         freeAsmop(left,NULL,ic,TRUE);
7503         freeAsmop(result,NULL,ic,TRUE);
7504 }
7505
7506 /*-----------------------------------------------------------------*/
7507 /* genSignedRightShift - right shift of signed number              */
7508 /*-----------------------------------------------------------------*/
7509 static void genSignedRightShift (iCode *ic)
7510 {
7511         operand *right, *left, *result;
7512         int size, offset;
7513         //  char *l;
7514         symbol *tlbl, *tlbl1 ;
7515         pCodeOp *pctemp;
7516         
7517         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7518         
7519         /* we do it the hard way put the shift count in b
7520         and loop thru preserving the sign */
7521         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7522         
7523         right = IC_RIGHT(ic);
7524         left  = IC_LEFT(ic);
7525         result = IC_RESULT(ic);
7526         
7527         aopOp(right,ic,FALSE);  
7528         aopOp(left,ic,FALSE);
7529         aopOp(result,ic,FALSE);
7530         
7531         
7532         if ( AOP_TYPE(right) == AOP_LIT) {
7533                 genRightShiftLiteral (left,right,result,ic,1);
7534                 return ;
7535         }
7536         /* shift count is unknown then we have to form 
7537         a loop get the loop count in B : Note: we take
7538         only the lower order byte since shifting
7539         more that 32 bits make no sense anyway, ( the
7540         largest size of an object can be only 32 bits ) */  
7541         
7542         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7543         //pic14_emitcode("inc","b");
7544         //freeAsmop (right,NULL,ic,TRUE);
7545         //aopOp(left,ic,FALSE);
7546         //aopOp(result,ic,FALSE);
7547         
7548         /* now move the left to the result if they are not the
7549         same */
7550         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7551                 AOP_SIZE(result) > 1) {
7552                 
7553                 size = AOP_SIZE(result);
7554                 offset=0;
7555                 while (size--) { 
7556                 /*
7557                 l = aopGet(AOP(left),offset,FALSE,TRUE);
7558                 if (*l == '@' && IS_AOP_PREG(result)) {
7559                 
7560                   pic14_emitcode("mov","a,%s",l);
7561                   aopPut(AOP(result),"a",offset);
7562                   } else
7563                   aopPut(AOP(result),l,offset);
7564                         */
7565                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7566                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7567                         
7568                         offset++;
7569                 }
7570         }
7571         
7572         /* mov the highest order bit to OVR */    
7573         tlbl = newiTempLabel(NULL);
7574         tlbl1= newiTempLabel(NULL);
7575         
7576         size = AOP_SIZE(result);
7577         offset = size - 1;
7578         
7579         pctemp = popGetTempReg();  /* grab a temporary working register. */
7580         
7581         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7582         
7583         /* offset should be 0, 1 or 3 */
7584         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7585         emitSKPNZ;
7586         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7587         
7588         emitpcode(POC_MOVWF, pctemp);
7589         
7590         
7591         emitpLabel(tlbl->key);
7592         
7593         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7594         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7595         
7596         while(--size) {
7597                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7598         }
7599         
7600         emitpcode(POC_DECFSZ,  pctemp);
7601         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7602         emitpLabel(tlbl1->key);
7603         
7604         popReleaseTempReg(pctemp);
7605 #if 0
7606         size = AOP_SIZE(result);
7607         offset = size - 1;
7608         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7609         pic14_emitcode("rlc","a");
7610         pic14_emitcode("mov","ov,c");
7611         /* if it is only one byte then */
7612         if (size == 1) {
7613                 l = aopGet(AOP(left),0,FALSE,FALSE);
7614                 MOVA(l);
7615                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7616                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7617                 pic14_emitcode("mov","c,ov");
7618                 pic14_emitcode("rrc","a");
7619                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7620                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7621                 aopPut(AOP(result),"a",0);
7622                 goto release ;
7623         }
7624         
7625         reAdjustPreg(AOP(result));
7626         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7627         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7628         pic14_emitcode("mov","c,ov");
7629         while (size--) {
7630                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7631                 MOVA(l);
7632                 pic14_emitcode("rrc","a");         
7633                 aopPut(AOP(result),"a",offset--);
7634         }
7635         reAdjustPreg(AOP(result));
7636         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7637         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7638         
7639 release:
7640 #endif
7641         
7642         freeAsmop(left,NULL,ic,TRUE);
7643         freeAsmop(result,NULL,ic,TRUE);
7644         freeAsmop(right,NULL,ic,TRUE);
7645 }
7646
7647 /*-----------------------------------------------------------------*/
7648 /* genRightShift - generate code for right shifting                */
7649 /*-----------------------------------------------------------------*/
7650 static void genRightShift (iCode *ic)
7651 {
7652         operand *right, *left, *result;
7653         sym_link *retype ;
7654         int size, offset;
7655         char *l;
7656         symbol *tlbl, *tlbl1 ;
7657         
7658         /* if signed then we do it the hard way preserve the
7659         sign bit moving it inwards */
7660         retype = getSpec(operandType(IC_RESULT(ic)));
7661         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7662         
7663         if (!SPEC_USIGN(retype)) {
7664                 genSignedRightShift (ic);
7665                 return ;
7666         }
7667         
7668         /* signed & unsigned types are treated the same : i.e. the
7669         signed is NOT propagated inwards : quoting from the
7670         ANSI - standard : "for E1 >> E2, is equivalent to division
7671         by 2**E2 if unsigned or if it has a non-negative value,
7672         otherwise the result is implementation defined ", MY definition
7673         is that the sign does not get propagated */
7674         
7675         right = IC_RIGHT(ic);
7676         left  = IC_LEFT(ic);
7677         result = IC_RESULT(ic);
7678         
7679         aopOp(right,ic,FALSE);
7680         
7681         /* if the shift count is known then do it 
7682         as efficiently as possible */
7683         if (AOP_TYPE(right) == AOP_LIT) {
7684                 genRightShiftLiteral (left,right,result,ic, 0);
7685                 return ;
7686         }
7687         
7688         /* shift count is unknown then we have to form 
7689         a loop get the loop count in B : Note: we take
7690         only the lower order byte since shifting
7691         more that 32 bits make no sense anyway, ( the
7692         largest size of an object can be only 32 bits ) */  
7693         
7694         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7695         pic14_emitcode("inc","b");
7696         aopOp(left,ic,FALSE);
7697         aopOp(result,ic,FALSE);
7698         
7699         /* now move the left to the result if they are not the
7700         same */
7701         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7702                 AOP_SIZE(result) > 1) {
7703                 
7704                 size = AOP_SIZE(result);
7705                 offset=0;
7706                 while (size--) {
7707                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7708                         if (*l == '@' && IS_AOP_PREG(result)) {
7709                                 
7710                                 pic14_emitcode("mov","a,%s",l);
7711                                 aopPut(AOP(result),"a",offset);
7712                         } else
7713                                 aopPut(AOP(result),l,offset);
7714                         offset++;
7715                 }
7716         }
7717         
7718         tlbl = newiTempLabel(NULL);
7719         tlbl1= newiTempLabel(NULL);
7720         size = AOP_SIZE(result);
7721         offset = size - 1;
7722         
7723         /* if it is only one byte then */
7724         if (size == 1) {
7725                 
7726                 tlbl = newiTempLabel(NULL);
7727                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7728                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7729                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7730                 }
7731                 
7732                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7733                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7734                 emitpLabel(tlbl->key);
7735                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7736                 emitpcode(POC_ADDLW,  popGetLit(1));
7737                 emitSKPC;
7738                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7739                 
7740                 goto release ;
7741         }
7742         
7743         reAdjustPreg(AOP(result));
7744         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7745         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7746         CLRC;
7747         while (size--) {
7748                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7749                 MOVA(l);
7750                 pic14_emitcode("rrc","a");         
7751                 aopPut(AOP(result),"a",offset--);
7752         }
7753         reAdjustPreg(AOP(result));
7754         
7755         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7756         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7757         
7758 release:
7759         freeAsmop(left,NULL,ic,TRUE);
7760         freeAsmop (right,NULL,ic,TRUE);
7761         freeAsmop(result,NULL,ic,TRUE);
7762 }
7763
7764 /*-----------------------------------------------------------------*/
7765 /* genUnpackBits - generates code for unpacking bits               */
7766 /*-----------------------------------------------------------------*/
7767 static void genUnpackBits (operand *result, char *rname, int ptype)
7768 {    
7769         int shCnt ;
7770         int rlen = 0 ;
7771         sym_link *etype;
7772         int offset = 0 ;
7773         
7774         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7775         etype = getSpec(operandType(result));
7776         
7777         /* read the first byte  */
7778         switch (ptype) {
7779                 
7780         case POINTER:
7781         case IPOINTER:
7782                 pic14_emitcode("mov","a,@%s",rname);
7783                 break;
7784                 
7785         case PPOINTER:
7786                 pic14_emitcode("movx","a,@%s",rname);
7787                 break;
7788                 
7789         case FPOINTER:
7790                 pic14_emitcode("movx","a,@dptr");
7791                 break;
7792                 
7793         case CPOINTER:
7794                 pic14_emitcode("clr","a");
7795                 pic14_emitcode("movc","a","@a+dptr");
7796                 break;
7797                 
7798         case GPOINTER:
7799                 pic14_emitcode("lcall","__gptrget");
7800                 break;
7801         }
7802         
7803         /* if we have bitdisplacement then it fits   */
7804         /* into this byte completely or if length is */
7805         /* less than a byte                          */
7806         if ((shCnt = SPEC_BSTR(etype)) || 
7807                 (SPEC_BLEN(etype) <= 8))  {
7808                 
7809                 /* shift right acc */
7810                 AccRsh(shCnt);
7811                 
7812                 pic14_emitcode("anl","a,#0x%02x",
7813                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7814                 aopPut(AOP(result),"a",offset);
7815                 return ;
7816         }
7817         
7818         /* bit field did not fit in a byte  */
7819         rlen = SPEC_BLEN(etype) - 8;
7820         aopPut(AOP(result),"a",offset++);
7821         
7822         while (1)  {
7823                 
7824                 switch (ptype) {
7825                 case POINTER:
7826                 case IPOINTER:
7827                         pic14_emitcode("inc","%s",rname);
7828                         pic14_emitcode("mov","a,@%s",rname);
7829                         break;
7830                         
7831                 case PPOINTER:
7832                         pic14_emitcode("inc","%s",rname);
7833                         pic14_emitcode("movx","a,@%s",rname);
7834                         break;
7835                         
7836                 case FPOINTER:
7837                         pic14_emitcode("inc","dptr");
7838                         pic14_emitcode("movx","a,@dptr");
7839                         break;
7840                         
7841                 case CPOINTER:
7842                         pic14_emitcode("clr","a");
7843                         pic14_emitcode("inc","dptr");
7844                         pic14_emitcode("movc","a","@a+dptr");
7845                         break;
7846                         
7847                 case GPOINTER:
7848                         pic14_emitcode("inc","dptr");
7849                         pic14_emitcode("lcall","__gptrget");
7850                         break;
7851                 }
7852                 
7853                 rlen -= 8;            
7854                 /* if we are done */
7855                 if ( rlen <= 0 )
7856                         break ;
7857                 
7858                 aopPut(AOP(result),"a",offset++);
7859                 
7860         }
7861         
7862         if (rlen) {
7863                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7864                 aopPut(AOP(result),"a",offset);        
7865         }
7866         
7867         return ;
7868 }
7869
7870 #if 0
7871 /*-----------------------------------------------------------------*/
7872 /* genDataPointerGet - generates code when ptr offset is known     */
7873 /*-----------------------------------------------------------------*/
7874 static void genDataPointerGet (operand *left, 
7875                                                            operand *result, 
7876                                                            iCode *ic)
7877 {
7878         int size , offset = 0;
7879         
7880         
7881         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7882         
7883         
7884         /* optimization - most of the time, left and result are the same
7885         * address, but different types. for the pic code, we could omit
7886         * the following
7887         */
7888         
7889         aopOp(result,ic,TRUE);
7890         
7891         DEBUGpic14_AopType(__LINE__,left,NULL,result);
7892         
7893         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7894         
7895         size = AOP_SIZE(result);
7896         
7897         while (size--) {
7898                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7899                 offset++;
7900         }
7901         
7902         freeAsmop(left,NULL,ic,TRUE);
7903         freeAsmop(result,NULL,ic,TRUE);
7904 }
7905 #endif
7906 /*-----------------------------------------------------------------*/
7907 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7908 /*-----------------------------------------------------------------*/
7909 static void genNearPointerGet (operand *left, 
7910                                                            operand *result, 
7911                                                            iCode *ic)
7912 {
7913         asmop *aop = NULL;
7914         //regs *preg = NULL ;
7915         char *rname ;
7916         sym_link *rtype, *retype;
7917         sym_link *ltype = operandType(left);    
7918         //char buffer[80];
7919         
7920         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7921         
7922         rtype = operandType(result);
7923         retype= getSpec(rtype);
7924         
7925         aopOp(left,ic,FALSE);
7926         
7927         /* if left is rematerialisable and
7928         result is not bit variable type and
7929         the left is pointer to data space i.e
7930         lower 128 bytes of space */
7931         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7932                 !IS_BITVAR(retype)         &&
7933                 DCL_TYPE(ltype) == POINTER) {
7934                 //genDataPointerGet (left,result,ic);
7935                 return ;
7936         }
7937         
7938         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7939         
7940         /* if the value is already in a pointer register
7941         then don't need anything more */
7942         if (!AOP_INPREG(AOP(left))) {
7943                 /* otherwise get a free pointer register */
7944                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7945                 /*
7946                 aop = newAsmop(0);
7947                 preg = getFreePtr(ic,&aop,FALSE);
7948                 pic14_emitcode("mov","%s,%s",
7949                 preg->name,
7950                 aopGet(AOP(left),0,FALSE,TRUE));
7951                 rname = preg->name ;
7952                 */
7953                 rname ="BAD";
7954         } else
7955                 rname = aopGet(AOP(left),0,FALSE,FALSE);
7956         
7957         aopOp (result,ic,FALSE);
7958         
7959         /* if bitfield then unpack the bits */
7960         if (IS_BITFIELD(retype)) 
7961                 genUnpackBits (result,rname,POINTER);
7962         else {
7963                 /* we have can just get the values */
7964                 int size = AOP_SIZE(result);
7965                 int offset = 0 ;  
7966                 
7967                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7968                 
7969                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7970                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7971                 while(size--) {
7972                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7973                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7974                         if(size)
7975                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7976                 }
7977                 /*
7978                 while (size--) {
7979                 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7980                 
7981                   pic14_emitcode("mov","a,@%s",rname);
7982                   aopPut(AOP(result),"a",offset);
7983                   } else {
7984                   sprintf(buffer,"@%s",rname);
7985                   aopPut(AOP(result),buffer,offset);
7986                   }
7987                   offset++ ;
7988                   if (size)
7989                   pic14_emitcode("inc","%s",rname);
7990                   }
7991                 */
7992         }
7993         
7994         /* now some housekeeping stuff */
7995         if (aop) {
7996                 /* we had to allocate for this iCode */
7997                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7998                 freeAsmop(NULL,aop,ic,TRUE);
7999         } else { 
8000         /* we did not allocate which means left
8001         already in a pointer register, then
8002         if size > 0 && this could be used again
8003         we have to point it back to where it 
8004                 belongs */
8005                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8006                 if (AOP_SIZE(result) > 1 &&
8007                         !OP_SYMBOL(left)->remat &&
8008                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8009                         ic->depth )) {
8010                         int size = AOP_SIZE(result) - 1;
8011                         while (size--)
8012                                 pic14_emitcode("dec","%s",rname);
8013                 }
8014         }
8015         
8016         /* done */
8017         freeAsmop(left,NULL,ic,TRUE);
8018         freeAsmop(result,NULL,ic,TRUE);
8019         
8020 }
8021
8022 /*-----------------------------------------------------------------*/
8023 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8024 /*-----------------------------------------------------------------*/
8025 static void genPagedPointerGet (operand *left, 
8026                                                                 operand *result, 
8027                                                                 iCode *ic)
8028 {
8029         asmop *aop = NULL;
8030         regs *preg = NULL ;
8031         char *rname ;
8032         sym_link *rtype, *retype;    
8033         
8034         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8035         
8036         rtype = operandType(result);
8037         retype= getSpec(rtype);
8038         
8039         aopOp(left,ic,FALSE);
8040         
8041         /* if the value is already in a pointer register
8042         then don't need anything more */
8043         if (!AOP_INPREG(AOP(left))) {
8044                 /* otherwise get a free pointer register */
8045                 aop = newAsmop(0);
8046                 preg = getFreePtr(ic,&aop,FALSE);
8047                 pic14_emitcode("mov","%s,%s",
8048                         preg->name,
8049                         aopGet(AOP(left),0,FALSE,TRUE));
8050                 rname = preg->name ;
8051         } else
8052                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8053         
8054         freeAsmop(left,NULL,ic,TRUE);
8055         aopOp (result,ic,FALSE);
8056         
8057         /* if bitfield then unpack the bits */
8058         if (IS_BITFIELD(retype)) 
8059                 genUnpackBits (result,rname,PPOINTER);
8060         else {
8061                 /* we have can just get the values */
8062                 int size = AOP_SIZE(result);
8063                 int offset = 0 ;  
8064                 
8065                 while (size--) {
8066                         
8067                         pic14_emitcode("movx","a,@%s",rname);
8068                         aopPut(AOP(result),"a",offset);
8069                         
8070                         offset++ ;
8071                         
8072                         if (size)
8073                                 pic14_emitcode("inc","%s",rname);
8074                 }
8075         }
8076         
8077         /* now some housekeeping stuff */
8078         if (aop) {
8079                 /* we had to allocate for this iCode */
8080                 freeAsmop(NULL,aop,ic,TRUE);
8081         } else { 
8082         /* we did not allocate which means left
8083         already in a pointer register, then
8084         if size > 0 && this could be used again
8085         we have to point it back to where it 
8086                 belongs */
8087                 if (AOP_SIZE(result) > 1 &&
8088                         !OP_SYMBOL(left)->remat &&
8089                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8090                         ic->depth )) {
8091                         int size = AOP_SIZE(result) - 1;
8092                         while (size--)
8093                                 pic14_emitcode("dec","%s",rname);
8094                 }
8095         }
8096         
8097         /* done */
8098         freeAsmop(result,NULL,ic,TRUE);
8099         
8100         
8101 }
8102
8103 /*-----------------------------------------------------------------*/
8104 /* genFarPointerGet - gget value from far space                    */
8105 /*-----------------------------------------------------------------*/
8106 static void genFarPointerGet (operand *left,
8107                                                           operand *result, iCode *ic)
8108 {
8109         int size, offset ;
8110         sym_link *retype = getSpec(operandType(result));
8111         
8112         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8113         
8114         aopOp(left,ic,FALSE);
8115         
8116         /* if the operand is already in dptr 
8117         then we do nothing else we move the value to dptr */
8118         if (AOP_TYPE(left) != AOP_STR) {
8119                 /* if this is remateriazable */
8120                 if (AOP_TYPE(left) == AOP_IMMD)
8121                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8122                 else { /* we need to get it byte by byte */
8123                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8124                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8125                         if (options.model == MODEL_FLAT24)
8126                         {
8127                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8128                         }
8129                 }
8130         }
8131         /* so dptr know contains the address */
8132         freeAsmop(left,NULL,ic,TRUE);
8133         aopOp(result,ic,FALSE);
8134         
8135         /* if bit then unpack */
8136         if (IS_BITFIELD(retype)) 
8137                 genUnpackBits(result,"dptr",FPOINTER);
8138         else {
8139                 size = AOP_SIZE(result);
8140                 offset = 0 ;
8141                 
8142                 while (size--) {
8143                         pic14_emitcode("movx","a,@dptr");
8144                         aopPut(AOP(result),"a",offset++);
8145                         if (size)
8146                                 pic14_emitcode("inc","dptr");
8147                 }
8148         }
8149         
8150         freeAsmop(result,NULL,ic,TRUE);
8151 }
8152 #if 0
8153 /*-----------------------------------------------------------------*/
8154 /* genCodePointerGet - get value from code space                  */
8155 /*-----------------------------------------------------------------*/
8156 static void genCodePointerGet (operand *left,
8157                                                            operand *result, iCode *ic)
8158 {
8159         int size, offset ;
8160         sym_link *retype = getSpec(operandType(result));
8161         
8162         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8163         
8164         aopOp(left,ic,FALSE);
8165         
8166         /* if the operand is already in dptr 
8167         then we do nothing else we move the value to dptr */
8168         if (AOP_TYPE(left) != AOP_STR) {
8169                 /* if this is remateriazable */
8170                 if (AOP_TYPE(left) == AOP_IMMD)
8171                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8172                 else { /* we need to get it byte by byte */
8173                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8174                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8175                         if (options.model == MODEL_FLAT24)
8176                         {
8177                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8178                         }
8179                 }
8180         }
8181         /* so dptr know contains the address */
8182         freeAsmop(left,NULL,ic,TRUE);
8183         aopOp(result,ic,FALSE);
8184         
8185         /* if bit then unpack */
8186         if (IS_BITFIELD(retype)) 
8187                 genUnpackBits(result,"dptr",CPOINTER);
8188         else {
8189                 size = AOP_SIZE(result);
8190                 offset = 0 ;
8191                 
8192                 while (size--) {
8193                         pic14_emitcode("clr","a");
8194                         pic14_emitcode("movc","a,@a+dptr");
8195                         aopPut(AOP(result),"a",offset++);
8196                         if (size)
8197                                 pic14_emitcode("inc","dptr");
8198                 }
8199         }
8200         
8201         freeAsmop(result,NULL,ic,TRUE);
8202 }
8203 #endif
8204 /*-----------------------------------------------------------------*/
8205 /* genGenPointerGet - gget value from generic pointer space        */
8206 /*-----------------------------------------------------------------*/
8207 static void genGenPointerGet (operand *left,
8208                                                           operand *result, iCode *ic)
8209 {
8210         int size, offset ;
8211         sym_link *retype = getSpec(operandType(result));
8212         
8213         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8214         aopOp(left,ic,FALSE);
8215         aopOp(result,ic,FALSE);
8216         
8217         
8218         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8219         
8220         /* if the operand is already in dptr 
8221         then we do nothing else we move the value to dptr */
8222         //  if (AOP_TYPE(left) != AOP_STR) {
8223         /* if this is remateriazable */
8224         if (AOP_TYPE(left) == AOP_IMMD) {
8225                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8226                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8227         }
8228         else { /* we need to get it byte by byte */
8229                 
8230                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8231                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8232                 
8233                 size = AOP_SIZE(result);
8234                 offset = 0 ;
8235                 
8236                 while(size--) {
8237                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8238                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8239                         if(size)
8240                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8241                 }
8242                 goto release;
8243         }
8244         //}
8245         /* so dptr know contains the address */
8246         
8247         /* if bit then unpack */
8248         //if (IS_BITFIELD(retype)) 
8249         //  genUnpackBits(result,"dptr",GPOINTER);
8250         
8251 release:
8252         freeAsmop(left,NULL,ic,TRUE);
8253         freeAsmop(result,NULL,ic,TRUE);
8254         
8255 }
8256
8257 /*-----------------------------------------------------------------*/
8258 /* genConstPointerGet - get value from const generic pointer space */
8259 /*-----------------------------------------------------------------*/
8260 static void genConstPointerGet (operand *left,
8261                                                                 operand *result, iCode *ic)
8262 {
8263         //sym_link *retype = getSpec(operandType(result));
8264         symbol *albl = newiTempLabel(NULL);
8265         symbol *blbl = newiTempLabel(NULL);
8266         PIC_OPCODE poc;
8267         pCodeOp *pcop;
8268         
8269         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8270         aopOp(left,ic,FALSE);
8271         aopOp(result,ic,FALSE);
8272         
8273         
8274         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8275         
8276         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8277         
8278         emitpcode(POC_CALL,popGetLabel(albl->key));
8279         pcop = popGetLabel(blbl->key);
8280         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8281         emitpcode(POC_GOTO,pcop);
8282         emitpLabel(albl->key);
8283         
8284         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8285         
8286         emitpcode(poc,popGet(AOP(left),1));
8287         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8288         emitpcode(poc,popGet(AOP(left),0));
8289         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8290         
8291         emitpLabel(blbl->key);
8292         
8293         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8294         
8295         
8296         freeAsmop(left,NULL,ic,TRUE);
8297         freeAsmop(result,NULL,ic,TRUE);
8298         
8299 }
8300 /*-----------------------------------------------------------------*/
8301 /* genPointerGet - generate code for pointer get                   */
8302 /*-----------------------------------------------------------------*/
8303 static void genPointerGet (iCode *ic)
8304 {
8305         operand *left, *result ;
8306         sym_link *type, *etype;
8307         int p_type;
8308         
8309         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8310         
8311         left = IC_LEFT(ic);
8312         result = IC_RESULT(ic) ;
8313         
8314         /* depending on the type of pointer we need to
8315         move it to the correct pointer register */
8316         type = operandType(left);
8317         etype = getSpec(type);
8318         
8319         if (IS_PTR_CONST(type))
8320                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8321         
8322         /* if left is of type of pointer then it is simple */
8323         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8324                 p_type = DCL_TYPE(type);
8325         else {
8326                 /* we have to go by the storage class */
8327                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8328                 
8329                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8330                 
8331                 if (SPEC_OCLS(etype)->codesp ) {
8332                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8333                         //p_type = CPOINTER ; 
8334                 }
8335                 else
8336                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8337                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8338                         /*p_type = FPOINTER ;*/ 
8339                         else
8340                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8341                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8342                                 /*        p_type = PPOINTER; */
8343                                 else
8344                                         if (SPEC_OCLS(etype) == idata )
8345                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8346                                         /*      p_type = IPOINTER; */
8347                                         else
8348                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8349                                         /*      p_type = POINTER ; */
8350         }
8351         
8352         /* now that we have the pointer type we assign
8353         the pointer values */
8354         switch (p_type) {
8355                 
8356         case POINTER: 
8357         case IPOINTER:
8358                 genNearPointerGet (left,result,ic);
8359                 break;
8360                 
8361         case PPOINTER:
8362                 genPagedPointerGet(left,result,ic);
8363                 break;
8364                 
8365         case FPOINTER:
8366                 genFarPointerGet (left,result,ic);
8367                 break;
8368                 
8369         case CPOINTER:
8370                 genConstPointerGet (left,result,ic);
8371                 //pic14_emitcodePointerGet (left,result,ic);
8372                 break;
8373                 
8374         case GPOINTER:
8375                 if (IS_PTR_CONST(type))
8376                         genConstPointerGet (left,result,ic);
8377                 else
8378                         genGenPointerGet (left,result,ic);
8379                 break;
8380         }
8381         
8382 }
8383
8384 /*-----------------------------------------------------------------*/
8385 /* genPackBits - generates code for packed bit storage             */
8386 /*-----------------------------------------------------------------*/
8387 static void genPackBits (sym_link    *etype ,
8388                                                  operand *right ,
8389                                                  char *rname, int p_type)
8390 {
8391         int shCount = 0 ;
8392         int offset = 0  ;
8393         int rLen = 0 ;
8394         int blen, bstr ;   
8395         char *l ;
8396         
8397         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8398         blen = SPEC_BLEN(etype);
8399         bstr = SPEC_BSTR(etype);
8400         
8401         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8402         MOVA(l);   
8403         
8404         /* if the bit lenth is less than or    */
8405         /* it exactly fits a byte then         */
8406         if (SPEC_BLEN(etype) <= 8 )  {
8407                 shCount = SPEC_BSTR(etype) ;
8408                 
8409                 /* shift left acc */
8410                 AccLsh(shCount);
8411                 
8412                 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8413                         
8414                         
8415                         switch (p_type) {
8416                         case POINTER:
8417                                 pic14_emitcode ("mov","b,a");
8418                                 pic14_emitcode("mov","a,@%s",rname);
8419                                 break;
8420                                 
8421                         case FPOINTER:
8422                                 pic14_emitcode ("mov","b,a");
8423                                 pic14_emitcode("movx","a,@dptr");
8424                                 break;
8425                                 
8426                         case GPOINTER:
8427                                 pic14_emitcode ("push","b");
8428                                 pic14_emitcode ("push","acc");
8429                                 pic14_emitcode ("lcall","__gptrget");
8430                                 pic14_emitcode ("pop","b");
8431                                 break;
8432                         }
8433                         
8434                         pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8435                                 ((unsigned char)(0xFF << (blen+bstr)) | 
8436                                 (unsigned char)(0xFF >> (8-bstr)) ) );
8437                         pic14_emitcode ("orl","a,b");
8438                         if (p_type == GPOINTER)
8439                                 pic14_emitcode("pop","b");
8440                 }
8441         }
8442         
8443         switch (p_type) {
8444         case POINTER:
8445                 pic14_emitcode("mov","@%s,a",rname);
8446                 break;
8447                 
8448         case FPOINTER:
8449                 pic14_emitcode("movx","@dptr,a");
8450                 break;
8451                 
8452         case GPOINTER:
8453                 DEBUGpic14_emitcode(";lcall","__gptrput");
8454                 break;
8455         }
8456         
8457         /* if we r done */
8458         if ( SPEC_BLEN(etype) <= 8 )
8459                 return ;
8460         
8461         pic14_emitcode("inc","%s",rname);
8462         rLen = SPEC_BLEN(etype) ;     
8463         
8464         /* now generate for lengths greater than one byte */
8465         while (1) {
8466                 
8467                 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8468                 
8469                 rLen -= 8 ;
8470                 if (rLen <= 0 )
8471                         break ;
8472                 
8473                 switch (p_type) {
8474                 case POINTER:
8475                         if (*l == '@') {
8476                                 MOVA(l);
8477                                 pic14_emitcode("mov","@%s,a",rname);
8478                         } else
8479                                 pic14_emitcode("mov","@%s,%s",rname,l);
8480                         break;
8481                         
8482                 case FPOINTER:
8483                         MOVA(l);
8484                         pic14_emitcode("movx","@dptr,a");
8485                         break;
8486                         
8487                 case GPOINTER:
8488                         MOVA(l);
8489                         DEBUGpic14_emitcode(";lcall","__gptrput");
8490                         break;  
8491                 }   
8492                 pic14_emitcode ("inc","%s",rname);
8493         }
8494         
8495         MOVA(l);
8496         
8497         /* last last was not complete */
8498         if (rLen)   {
8499                 /* save the byte & read byte */
8500                 switch (p_type) {
8501                 case POINTER:
8502                         pic14_emitcode ("mov","b,a");
8503                         pic14_emitcode("mov","a,@%s",rname);
8504                         break;
8505                         
8506                 case FPOINTER:
8507                         pic14_emitcode ("mov","b,a");
8508                         pic14_emitcode("movx","a,@dptr");
8509                         break;
8510                         
8511                 case GPOINTER:
8512                         pic14_emitcode ("push","b");
8513                         pic14_emitcode ("push","acc");
8514                         pic14_emitcode ("lcall","__gptrget");
8515                         pic14_emitcode ("pop","b");
8516                         break;
8517                 }
8518                 
8519                 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8520                 pic14_emitcode ("orl","a,b");
8521         }
8522         
8523         if (p_type == GPOINTER)
8524                 pic14_emitcode("pop","b");
8525         
8526         switch (p_type) {
8527                 
8528         case POINTER:
8529                 pic14_emitcode("mov","@%s,a",rname);
8530                 break;
8531                 
8532         case FPOINTER:
8533                 pic14_emitcode("movx","@dptr,a");
8534                 break;
8535                 
8536         case GPOINTER:
8537                 DEBUGpic14_emitcode(";lcall","__gptrput");
8538                 break;      
8539         }
8540 }
8541 /*-----------------------------------------------------------------*/
8542 /* genDataPointerSet - remat pointer to data space                 */
8543 /*-----------------------------------------------------------------*/
8544 static void genDataPointerSet(operand *right,
8545                                                           operand *result,
8546                                                           iCode *ic)
8547 {
8548         int size, offset = 0 ;
8549         char *l, buffer[256];
8550         
8551         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8552         aopOp(right,ic,FALSE);
8553         
8554         l = aopGet(AOP(result),0,FALSE,TRUE);
8555         size = AOP_SIZE(right);
8556         /*
8557         if ( AOP_TYPE(result) == AOP_PCODE) {
8558         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8559         AOP(result)->aopu.pcop->name,
8560         PCOI(AOP(result)->aopu.pcop)->offset);
8561         }
8562         */
8563         
8564         // tsd, was l+1 - the underline `_' prefix was being stripped
8565         while (size--) {
8566                 if (offset) {
8567                         sprintf(buffer,"(%s + %d)",l,offset);
8568                         fprintf(stderr,"oops  %s\n",buffer);
8569                 } else
8570                         sprintf(buffer,"%s",l);
8571                 
8572                 if (AOP_TYPE(right) == AOP_LIT) {
8573                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8574                         lit = lit >> (8*offset);
8575                         if(lit&0xff) {
8576                                 pic14_emitcode("movlw","%d",lit);
8577                                 pic14_emitcode("movwf","%s",buffer);
8578                                 
8579                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8580                                 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8581                                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8582                                 
8583                         } else {
8584                                 pic14_emitcode("clrf","%s",buffer);
8585                                 //emitpcode(POC_CLRF, popRegFromString(buffer));
8586                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
8587                         }
8588                 }else {
8589                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8590                         pic14_emitcode("movwf","%s",buffer);
8591                         
8592                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8593                         //emitpcode(POC_MOVWF, popRegFromString(buffer));
8594                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
8595                         
8596                 }
8597                 
8598                 offset++;
8599         }
8600         
8601         freeAsmop(right,NULL,ic,TRUE);
8602         freeAsmop(result,NULL,ic,TRUE);
8603 }
8604
8605 /*-----------------------------------------------------------------*/
8606 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8607 /*-----------------------------------------------------------------*/
8608 static void genNearPointerSet (operand *right,
8609                                                            operand *result, 
8610                                                            iCode *ic)
8611 {
8612         asmop *aop = NULL;
8613         char *l;
8614         sym_link *retype;
8615         sym_link *ptype = operandType(result);
8616         
8617         
8618         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8619         retype= getSpec(operandType(right));
8620         
8621         aopOp(result,ic,FALSE);
8622         
8623         
8624         /* if the result is rematerializable &
8625         in data space & not a bit variable */
8626         //if (AOP_TYPE(result) == AOP_IMMD &&
8627         if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8628                 DCL_TYPE(ptype) == POINTER   &&
8629                 !IS_BITFIELD(retype)) {
8630                 genDataPointerSet (right,result,ic);
8631                 freeAsmop(result,NULL,ic,TRUE);
8632                 return;
8633         }
8634         
8635         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8636         aopOp(right,ic,FALSE);
8637         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8638         
8639         /* if the value is already in a pointer register
8640         then don't need anything more */
8641         if (!AOP_INPREG(AOP(result))) {
8642                 /* otherwise get a free pointer register */
8643                 //aop = newAsmop(0);
8644                 //preg = getFreePtr(ic,&aop,FALSE);
8645                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8646                 //pic14_emitcode("mov","%s,%s",
8647                 //         preg->name,
8648                 //         aopGet(AOP(result),0,FALSE,TRUE));
8649                 //rname = preg->name ;
8650                 //pic14_emitcode("movwf","fsr");
8651                 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8652                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8653                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8654                 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8655                 goto release;
8656                 
8657         }// else
8658         //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8659         
8660         
8661         /* if bitfield then unpack the bits */
8662         if (IS_BITFIELD(retype)) {
8663                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8664                         "The programmer is obviously confused");
8665                 //genPackBits (retype,right,rname,POINTER);
8666                 exit(1);
8667         }
8668         else {
8669                 /* we have can just get the values */
8670                 int size = AOP_SIZE(right);
8671                 int offset = 0 ;    
8672                 
8673                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8674                 while (size--) {
8675                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8676                         if (*l == '@' ) {
8677                                 //MOVA(l);
8678                                 //pic14_emitcode("mov","@%s,a",rname);
8679                                 pic14_emitcode("movf","indf,w ;1");
8680                         } else {
8681                                 
8682                                 if (AOP_TYPE(right) == AOP_LIT) {
8683                                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8684                                         if(lit) {
8685                                                 pic14_emitcode("movlw","%s",l);
8686                                                 pic14_emitcode("movwf","indf ;2");
8687                                         } else 
8688                                                 pic14_emitcode("clrf","indf");
8689                                 }else {
8690                                         pic14_emitcode("movf","%s,w",l);
8691                                         pic14_emitcode("movwf","indf ;2");
8692                                 }
8693                                 //pic14_emitcode("mov","@%s,%s",rname,l);
8694                         }
8695                         if (size)
8696                                 pic14_emitcode("incf","fsr,f ;3");
8697                         //pic14_emitcode("inc","%s",rname);
8698                         offset++;
8699                 }
8700         }
8701         
8702         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8703         /* now some housekeeping stuff */
8704         if (aop) {
8705                 /* we had to allocate for this iCode */
8706                 freeAsmop(NULL,aop,ic,TRUE);
8707         } else { 
8708         /* we did not allocate which means left
8709         already in a pointer register, then
8710         if size > 0 && this could be used again
8711         we have to point it back to where it 
8712                 belongs */
8713                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8714                 if (AOP_SIZE(right) > 1 &&
8715                         !OP_SYMBOL(result)->remat &&
8716                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8717                         ic->depth )) {
8718                         int size = AOP_SIZE(right) - 1;
8719                         while (size--)
8720                                 pic14_emitcode("decf","fsr,f");
8721                         //pic14_emitcode("dec","%s",rname);
8722                 }
8723         }
8724         
8725         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8726         /* done */
8727 release:
8728         freeAsmop(right,NULL,ic,TRUE);
8729         freeAsmop(result,NULL,ic,TRUE);
8730 }
8731
8732 /*-----------------------------------------------------------------*/
8733 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8734 /*-----------------------------------------------------------------*/
8735 static void genPagedPointerSet (operand *right,
8736                                                                 operand *result, 
8737                                                                 iCode *ic)
8738 {
8739         asmop *aop = NULL;
8740         regs *preg = NULL ;
8741         char *rname , *l;
8742         sym_link *retype;
8743         
8744         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8745         
8746         retype= getSpec(operandType(right));
8747         
8748         aopOp(result,ic,FALSE);
8749         
8750         /* if the value is already in a pointer register
8751         then don't need anything more */
8752         if (!AOP_INPREG(AOP(result))) {
8753                 /* otherwise get a free pointer register */
8754                 aop = newAsmop(0);
8755                 preg = getFreePtr(ic,&aop,FALSE);
8756                 pic14_emitcode("mov","%s,%s",
8757                         preg->name,
8758                         aopGet(AOP(result),0,FALSE,TRUE));
8759                 rname = preg->name ;
8760         } else
8761                 rname = aopGet(AOP(result),0,FALSE,FALSE);
8762         
8763         freeAsmop(result,NULL,ic,TRUE);
8764         aopOp (right,ic,FALSE);
8765         
8766         /* if bitfield then unpack the bits */
8767         if (IS_BITFIELD(retype)) 
8768                 genPackBits (retype,right,rname,PPOINTER);
8769         else {
8770                 /* we have can just get the values */
8771                 int size = AOP_SIZE(right);
8772                 int offset = 0 ;  
8773                 
8774                 while (size--) {
8775                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8776                         
8777                         MOVA(l);
8778                         pic14_emitcode("movx","@%s,a",rname);
8779                         
8780                         if (size)
8781                                 pic14_emitcode("inc","%s",rname);
8782                         
8783                         offset++;
8784                 }
8785         }
8786         
8787         /* now some housekeeping stuff */
8788         if (aop) {
8789                 /* we had to allocate for this iCode */
8790                 freeAsmop(NULL,aop,ic,TRUE);
8791         } else { 
8792         /* we did not allocate which means left
8793         already in a pointer register, then
8794         if size > 0 && this could be used again
8795         we have to point it back to where it 
8796                 belongs */
8797                 if (AOP_SIZE(right) > 1 &&
8798                         !OP_SYMBOL(result)->remat &&
8799                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8800                         ic->depth )) {
8801                         int size = AOP_SIZE(right) - 1;
8802                         while (size--)
8803                                 pic14_emitcode("dec","%s",rname);
8804                 }
8805         }
8806         
8807         /* done */
8808         freeAsmop(right,NULL,ic,TRUE);
8809         
8810         
8811 }
8812
8813 /*-----------------------------------------------------------------*/
8814 /* genFarPointerSet - set value from far space                     */
8815 /*-----------------------------------------------------------------*/
8816 static void genFarPointerSet (operand *right,
8817                                                           operand *result, iCode *ic)
8818 {
8819         int size, offset ;
8820         sym_link *retype = getSpec(operandType(right));
8821         
8822         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8823         aopOp(result,ic,FALSE);
8824         
8825         /* if the operand is already in dptr 
8826         then we do nothing else we move the value to dptr */
8827         if (AOP_TYPE(result) != AOP_STR) {
8828                 /* if this is remateriazable */
8829                 if (AOP_TYPE(result) == AOP_IMMD)
8830                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8831                 else { /* we need to get it byte by byte */
8832                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8833                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8834                         if (options.model == MODEL_FLAT24)
8835                         {
8836                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8837                         }
8838                 }
8839         }
8840         /* so dptr know contains the address */
8841         freeAsmop(result,NULL,ic,TRUE);
8842         aopOp(right,ic,FALSE);
8843         
8844         /* if bit then unpack */
8845         if (IS_BITFIELD(retype)) 
8846                 genPackBits(retype,right,"dptr",FPOINTER);
8847         else {
8848                 size = AOP_SIZE(right);
8849                 offset = 0 ;
8850                 
8851                 while (size--) {
8852                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8853                         MOVA(l);
8854                         pic14_emitcode("movx","@dptr,a");
8855                         if (size)
8856                                 pic14_emitcode("inc","dptr");
8857                 }
8858         }
8859         
8860         freeAsmop(right,NULL,ic,TRUE);
8861 }
8862
8863 /*-----------------------------------------------------------------*/
8864 /* genGenPointerSet - set value from generic pointer space         */
8865 /*-----------------------------------------------------------------*/
8866 static void genGenPointerSet (operand *right,
8867                                                           operand *result, iCode *ic)
8868 {
8869         int size, offset ;
8870         sym_link *retype = getSpec(operandType(right));
8871         
8872         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8873         
8874         aopOp(result,ic,FALSE);
8875         aopOp(right,ic,FALSE);
8876         size = AOP_SIZE(right);
8877         
8878         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8879         
8880         /* if the operand is already in dptr 
8881         then we do nothing else we move the value to dptr */
8882         if (AOP_TYPE(result) != AOP_STR) {
8883                 /* if this is remateriazable */
8884                 if (AOP_TYPE(result) == AOP_IMMD) {
8885                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8886                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8887                 }
8888                 else { /* we need to get it byte by byte */
8889                         //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8890                         size = AOP_SIZE(right);
8891                         offset = 0 ;
8892                         
8893                         /* hack hack! see if this the FSR. If so don't load W */
8894                         if(AOP_TYPE(right) != AOP_ACC) {
8895                                 
8896                                 
8897                                 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8898                                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8899                                 
8900                                 if(AOP_SIZE(result) > 1) {
8901                                         emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8902                                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8903                                         emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8904                                         
8905                                 }
8906                                 
8907                                 //if(size==2)
8908                                 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8909                                 //if(size==4) {
8910                                 //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8911                                 //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8912                                 //}
8913                                 
8914                                 while(size--) {
8915                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8916                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8917                                         
8918                                         if(size)
8919                                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8920                                 }
8921                                 
8922                                 
8923                                 goto release;
8924                         } 
8925                         
8926                         if(aopIdx(AOP(result),0) != 4) {
8927                                 
8928                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8929                                 goto release;
8930                         }
8931                         
8932                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8933                         goto release;
8934                         
8935                 }
8936         }
8937         /* so dptr know contains the address */
8938         
8939         
8940         /* if bit then unpack */
8941         if (IS_BITFIELD(retype)) 
8942                 genPackBits(retype,right,"dptr",GPOINTER);
8943         else {
8944                 size = AOP_SIZE(right);
8945                 offset = 0 ;
8946                 
8947                 DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8948                 
8949                 while (size--) {
8950                         
8951                         emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8952                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8953                         
8954                         if (AOP_TYPE(right) == AOP_LIT) 
8955                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8956                         else
8957                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8958                         
8959                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8960                         
8961                         offset++;
8962                 }
8963         }
8964         
8965 release:
8966         freeAsmop(right,NULL,ic,TRUE);
8967         freeAsmop(result,NULL,ic,TRUE);
8968 }
8969
8970 /*-----------------------------------------------------------------*/
8971 /* genPointerSet - stores the value into a pointer location        */
8972 /*-----------------------------------------------------------------*/
8973 static void genPointerSet (iCode *ic)
8974 {    
8975         operand *right, *result ;
8976         sym_link *type, *etype;
8977         int p_type;
8978         
8979         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8980         
8981         right = IC_RIGHT(ic);
8982         result = IC_RESULT(ic) ;
8983         
8984         /* depending on the type of pointer we need to
8985         move it to the correct pointer register */
8986         type = operandType(result);
8987         etype = getSpec(type);
8988         /* if left is of type of pointer then it is simple */
8989         if (IS_PTR(type) && !IS_FUNC(type->next)) {
8990                 p_type = DCL_TYPE(type);
8991         }
8992         else {
8993                 /* we have to go by the storage class */
8994                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8995                 
8996                 /*  if (SPEC_OCLS(etype)->codesp ) { */
8997                 /*      p_type = CPOINTER ;  */
8998                 /*  } */
8999                 /*  else */
9000                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9001                 /*    p_type = FPOINTER ; */
9002                 /*      else */
9003                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9004                 /*        p_type = PPOINTER ; */
9005                 /*    else */
9006                 /*        if (SPEC_OCLS(etype) == idata ) */
9007                 /*      p_type = IPOINTER ; */
9008                 /*        else */
9009                 /*      p_type = POINTER ; */
9010         }
9011         
9012         /* now that we have the pointer type we assign
9013         the pointer values */
9014         switch (p_type) {
9015                 
9016         case POINTER:
9017         case IPOINTER:
9018                 genNearPointerSet (right,result,ic);
9019                 break;
9020                 
9021         case PPOINTER:
9022                 genPagedPointerSet (right,result,ic);
9023                 break;
9024                 
9025         case FPOINTER:
9026                 genFarPointerSet (right,result,ic);
9027                 break;
9028                 
9029         case GPOINTER:
9030                 genGenPointerSet (right,result,ic);
9031                 break;
9032                 
9033         default:
9034                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9035                         "genPointerSet: illegal pointer type");
9036         }
9037 }
9038
9039 /*-----------------------------------------------------------------*/
9040 /* genIfx - generate code for Ifx statement                        */
9041 /*-----------------------------------------------------------------*/
9042 static void genIfx (iCode *ic, iCode *popIc)
9043 {
9044         operand *cond = IC_COND(ic);
9045         int isbit =0;
9046         
9047         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9048         
9049         aopOp(cond,ic,FALSE);
9050         
9051         /* get the value into acc */
9052         if (AOP_TYPE(cond) != AOP_CRY)
9053                 pic14_toBoolean(cond);
9054         else
9055                 isbit = 1;
9056         /* the result is now in the accumulator */
9057         freeAsmop(cond,NULL,ic,TRUE);
9058         
9059         /* if there was something to be popped then do it */
9060         if (popIc)
9061                 genIpop(popIc);
9062         
9063         /* if the condition is  a bit variable */
9064         if (isbit && IS_ITEMP(cond) && 
9065                 SPIL_LOC(cond)) {
9066                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9067                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9068         }
9069         else {
9070                 if (isbit && !IS_ITEMP(cond))
9071                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9072                 else
9073                         genIfxJump(ic,"a");
9074         }
9075         ic->generated = 1;
9076         
9077 }
9078
9079 /*-----------------------------------------------------------------*/
9080 /* genAddrOf - generates code for address of                       */
9081 /*-----------------------------------------------------------------*/
9082 static void genAddrOf (iCode *ic)
9083 {
9084         operand *right, *result, *left;
9085         int size, offset ;
9086         
9087         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9088         
9089         
9090         //aopOp(IC_RESULT(ic),ic,FALSE);
9091         
9092         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9093         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9094         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9095         
9096         DEBUGpic14_AopType(__LINE__,left,right,result);
9097         
9098         size = AOP_SIZE(IC_RESULT(ic));
9099         offset = 0;
9100         
9101         while (size--) {
9102                 /* fixing bug #863624, reported from (errolv) */
9103                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9104                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9105                 
9106 #if 0
9107                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9108                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9109 #endif
9110                 offset++;
9111         }
9112         
9113         freeAsmop(left,NULL,ic,FALSE);
9114         freeAsmop(result,NULL,ic,TRUE);
9115         
9116 }
9117
9118 #if 0
9119 /*-----------------------------------------------------------------*/
9120 /* genFarFarAssign - assignment when both are in far space         */
9121 /*-----------------------------------------------------------------*/
9122 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9123 {
9124         int size = AOP_SIZE(right);
9125         int offset = 0;
9126         char *l ;
9127         /* first push the right side on to the stack */
9128         while (size--) {
9129                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9130                 MOVA(l);
9131                 pic14_emitcode ("push","acc");
9132         }
9133         
9134         freeAsmop(right,NULL,ic,FALSE);
9135         /* now assign DPTR to result */
9136         aopOp(result,ic,FALSE);
9137         size = AOP_SIZE(result);
9138         while (size--) {
9139                 pic14_emitcode ("pop","acc");
9140                 aopPut(AOP(result),"a",--offset);
9141         }
9142         freeAsmop(result,NULL,ic,FALSE);
9143         
9144 }
9145 #endif
9146
9147 /*-----------------------------------------------------------------*/
9148 /* genAssign - generate code for assignment                        */
9149 /*-----------------------------------------------------------------*/
9150 static void genAssign (iCode *ic)
9151 {
9152         operand *result, *right;
9153         int size, offset,know_W;
9154         unsigned long lit = 0L;
9155         
9156         result = IC_RESULT(ic);
9157         right  = IC_RIGHT(ic) ;
9158         
9159         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9160         
9161         /* if they are the same */
9162         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9163                 return ;
9164         
9165         aopOp(right,ic,FALSE);
9166         aopOp(result,ic,TRUE);
9167         
9168         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9169         
9170         /* if they are the same registers */
9171         if (pic14_sameRegs(AOP(right),AOP(result)))
9172                 goto release;
9173         
9174         /* if the result is a bit */
9175         if (AOP_TYPE(result) == AOP_CRY) {
9176                 
9177         /* if the right size is a literal then
9178                 we know what the value is */
9179                 if (AOP_TYPE(right) == AOP_LIT) {
9180                         
9181                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9182                                 popGet(AOP(result),0));
9183                         
9184                         if (((int) operandLitValue(right))) 
9185                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9186                                 AOP(result)->aopu.aop_dir,
9187                                 AOP(result)->aopu.aop_dir);
9188                         else
9189                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9190                                 AOP(result)->aopu.aop_dir,
9191                                 AOP(result)->aopu.aop_dir);
9192                         goto release;
9193                 }
9194                 
9195                 /* the right is also a bit variable */
9196                 if (AOP_TYPE(right) == AOP_CRY) {
9197                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9198                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9199                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9200                         
9201                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9202                                 AOP(result)->aopu.aop_dir,
9203                                 AOP(result)->aopu.aop_dir);
9204                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9205                                 AOP(right)->aopu.aop_dir,
9206                                 AOP(right)->aopu.aop_dir);
9207                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9208                                 AOP(result)->aopu.aop_dir,
9209                                 AOP(result)->aopu.aop_dir);
9210                         goto release ;
9211                 }
9212                 
9213                 /* we need to or */
9214                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9215                 pic14_toBoolean(right);
9216                 emitSKPZ;
9217                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9218                 //aopPut(AOP(result),"a",0);
9219                 goto release ;
9220         }
9221         
9222         /* bit variables done */
9223         /* general case */
9224         size = AOP_SIZE(result);
9225         offset = 0 ;
9226         if(AOP_TYPE(right) == AOP_LIT)
9227                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9228         
9229         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9230                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9231                 if(aopIdx(AOP(result),0) == 4) {
9232                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9233                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9234                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9235                         goto release;
9236                 } else
9237                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9238         }
9239         
9240         know_W=-1;
9241         while (size--) {
9242                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9243                 if(AOP_TYPE(right) == AOP_LIT) {
9244                         if(lit&0xff) {
9245                                 if(know_W != (int)(lit&0xff))
9246                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9247                                 know_W = lit&0xff;
9248                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9249                         } else
9250                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9251                         
9252                         lit >>= 8;
9253                         
9254                 } else if (AOP_TYPE(right) == AOP_CRY) {
9255                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9256                         if(offset == 0) {
9257                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9258                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9259                         }
9260                 } else {
9261                         mov2w (AOP(right), offset);
9262                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9263                 }
9264                 
9265                 offset++;
9266         }
9267         
9268         
9269 release:
9270         freeAsmop (right,NULL,ic,FALSE);
9271         freeAsmop (result,NULL,ic,TRUE);
9272 }   
9273
9274 /*-----------------------------------------------------------------*/
9275 /* genJumpTab - genrates code for jump table                       */
9276 /*-----------------------------------------------------------------*/
9277 static void genJumpTab (iCode *ic)
9278 {
9279         symbol *jtab;
9280         char *l;
9281         
9282         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9283         
9284         aopOp(IC_JTCOND(ic),ic,FALSE);
9285         /* get the condition into accumulator */
9286         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9287         MOVA(l);
9288         /* multiply by three */
9289         pic14_emitcode("add","a,acc");
9290         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9291         
9292         jtab = newiTempLabel(NULL);
9293         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9294         pic14_emitcode("jmp","@a+dptr");
9295         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9296         
9297         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9298         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9299         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9300         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9301         emitSKPNC;
9302         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9303         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9304         emitpLabel(jtab->key);
9305         
9306         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9307         
9308         /* now generate the jump labels */
9309         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9310         jtab = setNextItem(IC_JTLABELS(ic))) {
9311                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9312                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9313                 
9314         }
9315         
9316 }
9317
9318 /*-----------------------------------------------------------------*/
9319 /* genMixedOperation - gen code for operators between mixed types  */
9320 /*-----------------------------------------------------------------*/
9321 /*
9322 TSD - Written for the PIC port - but this unfortunately is buggy.
9323 This routine is good in that it is able to efficiently promote 
9324 types to different (larger) sizes. Unfortunately, the temporary
9325 variables that are optimized out by this routine are sometimes
9326 used in other places. So until I know how to really parse the 
9327 iCode tree, I'm going to not be using this routine :(.
9328 */
9329 static int genMixedOperation (iCode *ic)
9330 {
9331 #if 0
9332         operand *result = IC_RESULT(ic);
9333         sym_link *ctype = operandType(IC_LEFT(ic));
9334         operand *right = IC_RIGHT(ic);
9335         int ret = 0;
9336         int big,small;
9337         int offset;
9338         
9339         iCode *nextic;
9340         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9341         
9342         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9343         
9344         nextic = ic->next;
9345         if(!nextic)
9346                 return 0;
9347         
9348         nextright = IC_RIGHT(nextic);
9349         nextleft  = IC_LEFT(nextic);
9350         nextresult = IC_RESULT(nextic);
9351         
9352         aopOp(right,ic,FALSE);
9353         aopOp(result,ic,FALSE);
9354         aopOp(nextright,  nextic, FALSE);
9355         aopOp(nextleft,   nextic, FALSE);
9356         aopOp(nextresult, nextic, FALSE);
9357         
9358         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9359                 
9360                 operand *t = right;
9361                 right = nextright;
9362                 nextright = t; 
9363                 
9364                 pic14_emitcode(";remove right +","");
9365                 
9366         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9367         /*
9368         operand *t = right;
9369         right = nextleft;
9370         nextleft = t; 
9371                 */
9372                 pic14_emitcode(";remove left +","");
9373         } else
9374                 return 0;
9375         
9376         big = AOP_SIZE(nextleft);
9377         small = AOP_SIZE(nextright);
9378         
9379         switch(nextic->op) {
9380                 
9381         case '+':
9382                 pic14_emitcode(";optimize a +","");
9383                 /* if unsigned or not an integral type */
9384                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9385                         pic14_emitcode(";add a bit to something","");
9386                 } else {
9387                         
9388                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9389                         
9390                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9391                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9392                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9393                         } else
9394                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9395                         
9396                         offset = 0;
9397                         while(--big) {
9398                                 
9399                                 offset++;
9400                                 
9401                                 if(--small) {
9402                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9403                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9404                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9405                                         }
9406                                         
9407                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9408                                         emitSKPNC;
9409                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9410                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9411                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9412                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9413                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9414                                         
9415                                 } else {
9416                                         pic14_emitcode("rlf","known_zero,w");
9417                                         
9418                                         /*
9419                                         if right is signed
9420                                         btfsc  right,7
9421                                         addlw ff
9422                                         */
9423                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9424                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9425                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9426                                         } else {
9427                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9428                                         }
9429                                 }
9430                         }
9431                         ret = 1;
9432                 }
9433         }
9434         ret = 1;
9435         
9436 release:
9437         freeAsmop(right,NULL,ic,TRUE);
9438         freeAsmop(result,NULL,ic,TRUE);
9439         freeAsmop(nextright,NULL,ic,TRUE);
9440         freeAsmop(nextleft,NULL,ic,TRUE);
9441         if(ret)
9442                 nextic->generated = 1;
9443         
9444         return ret;
9445 #else
9446         return 0;
9447 #endif
9448 }
9449 /*-----------------------------------------------------------------*/
9450 /* genCast - gen code for casting                                  */
9451 /*-----------------------------------------------------------------*/
9452 static void genCast (iCode *ic)
9453 {
9454         operand *result = IC_RESULT(ic);
9455         sym_link *ctype = operandType(IC_LEFT(ic));
9456         sym_link *rtype = operandType(IC_RIGHT(ic));
9457         operand *right = IC_RIGHT(ic);
9458         int size, offset ;
9459         
9460         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9461         /* if they are equivalent then do nothing */
9462         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9463                 return ;
9464         
9465         aopOp(right,ic,FALSE) ;
9466         aopOp(result,ic,FALSE);
9467         
9468         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9469         
9470         /* if the result is a bit */
9471         if (AOP_TYPE(result) == AOP_CRY) {
9472         /* if the right size is a literal then
9473                 we know what the value is */
9474                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9475                 if (AOP_TYPE(right) == AOP_LIT) {
9476                         
9477                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9478                                 popGet(AOP(result),0));
9479                         
9480                         if (((int) operandLitValue(right))) 
9481                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9482                                 AOP(result)->aopu.aop_dir,
9483                                 AOP(result)->aopu.aop_dir);
9484                         else
9485                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9486                                 AOP(result)->aopu.aop_dir,
9487                                 AOP(result)->aopu.aop_dir);
9488                         
9489                         goto release;
9490                 }
9491                 
9492                 /* the right is also a bit variable */
9493                 if (AOP_TYPE(right) == AOP_CRY) {
9494                         
9495                         emitCLRC;
9496                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9497                         
9498                         pic14_emitcode("clrc","");
9499                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9500                                 AOP(right)->aopu.aop_dir,
9501                                 AOP(right)->aopu.aop_dir);
9502                         aopPut(AOP(result),"c",0);
9503                         goto release ;
9504                 }
9505                 
9506                 /* we need to or */
9507                 if (AOP_TYPE(right) == AOP_REG) {
9508                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9509                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9510                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9511                 }
9512                 pic14_toBoolean(right);
9513                 aopPut(AOP(result),"a",0);
9514                 goto release ;
9515         }
9516         
9517         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9518                 int offset = 1;
9519                 size = AOP_SIZE(result);
9520                 
9521                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9522                 
9523                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9524                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9525                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9526                 
9527                 while (size--)
9528                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9529                 
9530                 goto release;
9531         }
9532         
9533         /* if they are the same size : or less */
9534         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9535                 
9536                 /* if they are in the same place */
9537                 if (pic14_sameRegs(AOP(right),AOP(result)))
9538                         goto release;
9539                 
9540                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9541                 if (IS_PTR_CONST(rtype))
9542                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9543                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9544                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9545                 
9546                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9547                         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9548                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9549                         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9550                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9551                         if(AOP_SIZE(result) <2)
9552                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9553                         
9554                 } else {
9555                         
9556                         /* if they in different places then copy */
9557                         size = AOP_SIZE(result);
9558                         offset = 0 ;
9559                         while (size--) {
9560                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9561                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9562                                 
9563                                 //aopPut(AOP(result),
9564                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9565                                 // offset);
9566                                 
9567                                 offset++;
9568                         }
9569                 }
9570                 goto release;
9571         }
9572         
9573         
9574         /* if the result is of type pointer */
9575         if (IS_PTR(ctype)) {
9576                 
9577                 int p_type;
9578                 sym_link *type = operandType(right);
9579                 sym_link *etype = getSpec(type);
9580                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9581                 
9582                 /* pointer to generic pointer */
9583                 if (IS_GENPTR(ctype)) {
9584                         char *l = zero;
9585                         
9586                         if (IS_PTR(type)) 
9587                                 p_type = DCL_TYPE(type);
9588                         else {
9589                                 /* we have to go by the storage class */
9590                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9591                                 
9592                                 /*    if (SPEC_OCLS(etype)->codesp )  */
9593                                 /*        p_type = CPOINTER ;  */
9594                                 /*    else */
9595                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9596                                 /*      p_type = FPOINTER ; */
9597                                 /*        else */
9598                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9599                                 /*          p_type = PPOINTER; */
9600                                 /*      else */
9601                                 /*          if (SPEC_OCLS(etype) == idata ) */
9602                                 /*        p_type = IPOINTER ; */
9603                                 /*          else */
9604                                 /*        p_type = POINTER ; */
9605                         }
9606                         
9607                         /* the first two bytes are known */
9608                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9609                         size = GPTRSIZE - 1; 
9610                         offset = 0 ;
9611                         while (size--) {
9612                                 if(offset < AOP_SIZE(right)) {
9613                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9614                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9615                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9616                                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9617                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9618                                         } else { 
9619                                                 aopPut(AOP(result),
9620                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9621                                                         offset);
9622                                         }
9623                                 } else 
9624                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9625                                 offset++;
9626                         }
9627                         /* the last byte depending on type */
9628                         switch (p_type) {
9629                         case IPOINTER:
9630                         case POINTER:
9631                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9632                                 break;
9633                         case FPOINTER:
9634                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9635                                 l = one;
9636                                 break;
9637                         case CPOINTER:
9638                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9639                                 l = "#0x02";
9640                                 break;        
9641                         case PPOINTER:
9642                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9643                                 l = "#0x03";
9644                                 break;
9645                                 
9646                         default:
9647                                 /* this should never happen */
9648                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9649                                         "got unknown pointer type");
9650                                 exit(1);
9651                         }
9652                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9653                         goto release ;
9654                 }
9655                 
9656                 /* just copy the pointers */
9657                 size = AOP_SIZE(result);
9658                 offset = 0 ;
9659                 while (size--) {
9660                         aopPut(AOP(result),
9661                                 aopGet(AOP(right),offset,FALSE,FALSE),
9662                                 offset);
9663                         offset++;
9664                 }
9665                 goto release ;
9666         }
9667         
9668         
9669         
9670         /* so we now know that the size of destination is greater
9671         than the size of the source.
9672         Now, if the next iCode is an operator then we might be
9673         able to optimize the operation without performing a cast.
9674         */
9675         if(genMixedOperation(ic))
9676                 goto release;
9677         
9678         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9679         
9680         /* we move to result for the size of source */
9681         size = AOP_SIZE(right);
9682         offset = 0 ;
9683         while (size--) {
9684                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9685                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9686                 offset++;
9687         }
9688         
9689         /* now depending on the sign of the destination */
9690         size = AOP_SIZE(result) - AOP_SIZE(right);
9691         /* if unsigned or not an integral type */
9692         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9693                 while (size--)
9694                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9695         } else {
9696                 /* we need to extend the sign :{ */
9697                 
9698                 if(size == 1) {
9699                         /* Save one instruction of casting char to int */
9700                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9701                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9702                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9703                 } else {
9704                         emitpcodeNULLop(POC_CLRW);
9705                         
9706                         if(offset)
9707                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9708                         else
9709                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9710                         
9711                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9712                         
9713                         while (size--)
9714                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9715                 }
9716         }
9717         
9718 release:
9719         freeAsmop(right,NULL,ic,TRUE);
9720         freeAsmop(result,NULL,ic,TRUE);
9721         
9722 }
9723
9724 /*-----------------------------------------------------------------*/
9725 /* genDjnz - generate decrement & jump if not zero instrucion      */
9726 /*-----------------------------------------------------------------*/
9727 static int genDjnz (iCode *ic, iCode *ifx)
9728 {
9729         symbol *lbl, *lbl1;
9730         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9731         
9732         if (!ifx)
9733                 return 0;
9734         
9735                 /* if the if condition has a false label
9736         then we cannot save */
9737         if (IC_FALSE(ifx))
9738                 return 0;
9739         
9740                 /* if the minus is not of the form 
9741         a = a - 1 */
9742         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9743                 !IS_OP_LITERAL(IC_RIGHT(ic)))
9744                 return 0;
9745         
9746         if (operandLitValue(IC_RIGHT(ic)) != 1)
9747                 return 0;
9748         
9749                 /* if the size of this greater than one then no
9750         saving */
9751         if (getSize(operandType(IC_RESULT(ic))) > 1)
9752                 return 0;
9753         
9754         /* otherwise we can save BIG */
9755         lbl = newiTempLabel(NULL);
9756         lbl1= newiTempLabel(NULL);
9757         
9758         aopOp(IC_RESULT(ic),ic,FALSE);
9759         
9760         if (IS_AOP_PREG(IC_RESULT(ic))) {
9761                 pic14_emitcode("dec","%s",
9762                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9763                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9764                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9765         } else {  
9766                 
9767                 
9768                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9769                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9770                 
9771                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9772                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9773                 
9774         }
9775         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9776         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9777         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9778         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9779         
9780         
9781         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9782         ifx->generated = 1;
9783         return 1;
9784 }
9785
9786 /*-----------------------------------------------------------------*/
9787 /* genReceive - generate code for a receive iCode                  */
9788 /*-----------------------------------------------------------------*/
9789 static void genReceive (iCode *ic)
9790 {
9791         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9792         
9793         if (isOperandInFarSpace(IC_RESULT(ic)) &&
9794                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9795                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9796                 
9797                 int size = getSize(operandType(IC_RESULT(ic)));
9798                 int offset =  fReturnSizePic - size;
9799                 while (size--) {
9800                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9801                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
9802                         offset++;
9803                 }
9804                 aopOp(IC_RESULT(ic),ic,FALSE);
9805                 size = AOP_SIZE(IC_RESULT(ic));
9806                 offset = 0;
9807                 while (size--) {
9808                         pic14_emitcode ("pop","acc");
9809                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9810                 }
9811                 
9812         } else {
9813                 _G.accInUse++;
9814                 aopOp(IC_RESULT(ic),ic,FALSE);
9815                 _G.accInUse--;
9816                 assignResultValue(IC_RESULT(ic));
9817         }
9818         
9819         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9820 }
9821
9822 /*-----------------------------------------------------------------*/
9823 /* genDummyRead - generate code for dummy read of volatiles        */
9824 /*-----------------------------------------------------------------*/
9825 static void
9826 genDummyRead (iCode * ic)
9827 {
9828         pic14_emitcode ("; genDummyRead","");
9829         pic14_emitcode ("; not implemented","");
9830         
9831         ic = ic;
9832 }
9833
9834 /*-----------------------------------------------------------------*/
9835 /* genpic14Code - generate code for pic14 based controllers        */
9836 /*-----------------------------------------------------------------*/
9837 /*
9838 * At this point, ralloc.c has gone through the iCode and attempted
9839 * to optimize in a way suitable for a PIC. Now we've got to generate
9840 * PIC instructions that correspond to the iCode.
9841 *
9842 * Once the instructions are generated, we'll pass through both the
9843 * peep hole optimizer and the pCode optimizer.
9844 *-----------------------------------------------------------------*/
9845
9846 void genpic14Code (iCode *lic)
9847 {
9848         iCode *ic;
9849         int cln = 0;
9850         
9851         lineHead = lineCurr = NULL;
9852         
9853         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9854         addpBlock(pb);
9855         
9856         /* if debug information required */
9857         if (options.debug && currFunc) { 
9858                 if (currFunc) {
9859                         debugFile->writeFunction (currFunc, lic);
9860                 }
9861         }
9862         
9863         
9864         for (ic = lic ; ic ; ic = ic->next ) {
9865                 
9866                 DEBUGpic14_emitcode(";ic","");
9867                 if ( cln != ic->lineno ) {
9868                         if ( options.debug ) {
9869                                 debugFile->writeCLine (ic);
9870                         }
9871                         /*
9872                         pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9873                         pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9874                         printCLine(ic->filename, ic->lineno));
9875                         */
9876                         if (!options.noCcodeInAsm) {
9877                                 addpCode2pBlock(pb,
9878                                         newpCodeCSource(ic->lineno, 
9879                                         ic->filename, 
9880                                         printCLine(ic->filename, ic->lineno)));
9881                         }
9882                         
9883                         cln = ic->lineno ;
9884                 }
9885                 
9886                 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9887                 
9888                 /* if the result is marked as
9889                 spilt and rematerializable or code for
9890                 this has already been generated then
9891                 do nothing */
9892                 if (resultRemat(ic) || ic->generated ) 
9893                         continue ;
9894                 
9895                 /* depending on the operation */
9896                 switch (ic->op) {
9897                 case '!' :
9898                         genNot(ic);
9899                         break;
9900                         
9901                 case '~' :
9902                         genCpl(ic);
9903                         break;
9904                         
9905                 case UNARYMINUS:
9906                         genUminus (ic);
9907                         break;
9908                         
9909                 case IPUSH:
9910                         genIpush (ic);
9911                         break;
9912                         
9913                 case IPOP:
9914                 /* IPOP happens only when trying to restore a 
9915                 spilt live range, if there is an ifx statement
9916                 following this pop then the if statement might
9917                 be using some of the registers being popped which
9918                 would destory the contents of the register so
9919                 we need to check for this condition and handle it */
9920                         if (ic->next            && 
9921                                 ic->next->op == IFX &&
9922                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9923                                 genIfx (ic->next,ic);
9924                         else
9925                                 genIpop (ic);
9926                         break; 
9927                         
9928                 case CALL:
9929                         genCall (ic);
9930                         break;
9931                         
9932                 case PCALL:
9933                         genPcall (ic);
9934                         break;
9935                         
9936                 case FUNCTION:
9937                         genFunction (ic);
9938                         break;
9939                         
9940                 case ENDFUNCTION:
9941                         genEndFunction (ic);
9942                         break;
9943                         
9944                 case RETURN:
9945                         genRet (ic);
9946                         break;
9947                         
9948                 case LABEL:
9949                         genLabel (ic);
9950                         break;
9951                         
9952                 case GOTO:
9953                         genGoto (ic);
9954                         break;
9955                         
9956                 case '+' :
9957                         genPlus (ic) ;
9958                         break;
9959                         
9960                 case '-' :
9961                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9962                                 genMinus (ic);
9963                         break;
9964                         
9965                 case '*' :
9966                         genMult (ic);
9967                         break;
9968                         
9969                 case '/' :
9970                         genDiv (ic) ;
9971                         break;
9972                         
9973                 case '%' :
9974                         genMod (ic);
9975                         break;
9976                         
9977                 case '>' :
9978                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
9979                         break;
9980                         
9981                 case '<' :
9982                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9983                         break;
9984                         
9985                 case LE_OP:
9986                 case GE_OP:
9987                 case NE_OP:
9988                         
9989                 /* note these two are xlated by algebraic equivalence
9990                         during parsing SDCC.y */
9991                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9992                                 "got '>=' or '<=' shouldn't have come here");
9993                         break;  
9994                         
9995                 case EQ_OP:
9996                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9997                         break;      
9998                         
9999                 case AND_OP:
10000                         genAndOp (ic);
10001                         break;
10002                         
10003                 case OR_OP:
10004                         genOrOp (ic);
10005                         break;
10006                         
10007                 case '^' :
10008                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10009                         break;
10010                         
10011                 case '|' :
10012                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10013                         break;
10014                         
10015                 case BITWISEAND:
10016                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10017                         break;
10018                         
10019                 case INLINEASM:
10020                         genInline (ic);
10021                         break;
10022                         
10023                 case RRC:
10024                         genRRC (ic);
10025                         break;
10026                         
10027                 case RLC:
10028                         genRLC (ic);
10029                         break;
10030                         
10031                 case GETHBIT:
10032                         genGetHbit (ic);
10033                         break;
10034                         
10035                 case LEFT_OP:
10036                         genLeftShift (ic);
10037                         break;
10038                         
10039                 case RIGHT_OP:
10040                         genRightShift (ic);
10041                         break;
10042                         
10043                 case GET_VALUE_AT_ADDRESS:
10044                         genPointerGet(ic);
10045                         break;
10046                         
10047                 case '=' :
10048                         if (POINTER_SET(ic))
10049                                 genPointerSet(ic);
10050                         else
10051                                 genAssign(ic);
10052                         break;
10053                         
10054                 case IFX:
10055                         genIfx (ic,NULL);
10056                         break;
10057                         
10058                 case ADDRESS_OF:
10059                         genAddrOf (ic);
10060                         break;
10061                         
10062                 case JUMPTABLE:
10063                         genJumpTab (ic);
10064                         break;
10065                         
10066                 case CAST:
10067                         genCast (ic);
10068                         break;
10069                         
10070                 case RECEIVE:
10071                         genReceive(ic);
10072                         break;
10073                         
10074                 case SEND:
10075                         addSet(&_G.sendSet,ic);
10076                         break;
10077                         
10078                 case DUMMY_READ_VOLATILE:
10079                         genDummyRead (ic);
10080                         break;
10081                         
10082                 default :
10083                         ic = ic;
10084                 }
10085         }
10086
10087         
10088         /* now we are ready to call the
10089         peep hole optimizer */
10090         if (!options.nopeep) {
10091                 peepHole (&lineHead);
10092         }
10093         /* now do the actual printing */
10094         printLine (lineHead,codeOutFile);
10095         
10096 #ifdef PCODE_DEBUG
10097         DFPRINTF((stderr,"printing pBlock\n\n"));
10098         printpBlock(stdout,pb);
10099 #endif
10100         
10101         return;
10102 }