Tidied up tabs.
[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                 /*
1346                 if (offset)
1347                 sprintf(s,"(%s + %d)",
1348                 aop->aopu.aop_dir,
1349                 offset);
1350                 else
1351                 sprintf(s,"%s",aop->aopu.aop_dir);
1352                 pcop->name = Safe_calloc(1,strlen(s)+1);
1353                 strcpy(pcop->name,s);   
1354                 */
1355                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1356                 strcpy(pcop->name,aop->aopu.aop_dir);   
1357                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1358                 if(PCOR(pcop)->r == NULL) {
1359                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1360                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1361                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1362                 } else {
1363                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1364                 }
1365                 PCOR(pcop)->instance = offset;
1366                 
1367                 return pcop;
1368 #endif
1369                 
1370         case AOP_REG:
1371                 {
1372                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1373                         
1374                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1375                         PCOR(pcop)->rIdx = rIdx;
1376                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1377                         PCOR(pcop)->r->wasUsed=1;
1378                         PCOR(pcop)->r->isFree=0;
1379                         
1380                         PCOR(pcop)->instance = offset;
1381                         pcop->type = PCOR(pcop)->r->pc_type;
1382                         //rs = aop->aopu.aop_reg[offset]->name;
1383                         DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1384                         return pcop;
1385                 }
1386                 
1387         case AOP_CRY:
1388                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1389                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1390                 //if(PCOR(pcop)->r == NULL)
1391                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1392                 return pcop;
1393                 
1394         case AOP_LIT:
1395                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1396                 
1397         case AOP_STR:
1398                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1399                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1400                 /*
1401                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1402                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1403                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1404                 pcop->type = PCOR(pcop)->r->pc_type;
1405                 pcop->name = PCOR(pcop)->r->name;
1406                 
1407                   return pcop;
1408                 */
1409                 
1410         case AOP_PCODE:
1411                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1412                         __LINE__, 
1413                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1414                 pcop = pCodeOpCopy(aop->aopu.pcop);
1415                 PCOI(pcop)->offset = offset;
1416                 return pcop;
1417         }
1418         
1419         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1420                 "popGet got unsupported aop->type");
1421         exit(0);
1422 }
1423 /*-----------------------------------------------------------------*/
1424 /* aopPut - puts a string for a aop                                                        */
1425 /*-----------------------------------------------------------------*/
1426 void aopPut (asmop *aop, char *s, int offset)
1427 {
1428         char *d = buffer ;
1429         symbol *lbl ;
1430         
1431         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1432         
1433         if (aop->size && offset > ( aop->size - 1)) {
1434                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1435                         "aopPut got offset > aop->size");
1436                 exit(0);
1437         }
1438         
1439         /* will assign value to value */
1440         /* depending on where it is ofcourse */
1441         switch (aop->type) {
1442         case AOP_DIR:
1443                 if (offset) {
1444                         sprintf(d,"(%s + %d)",
1445                                 aop->aopu.aop_dir,offset);
1446                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1447                         
1448                 } else
1449                         sprintf(d,"%s",aop->aopu.aop_dir);
1450                 
1451                 if (strcmp(d,s)) {
1452                         DEBUGpic14_emitcode(";","%d",__LINE__);
1453                         if(strcmp(s,"W"))
1454                                 pic14_emitcode("movf","%s,w",s);
1455                         pic14_emitcode("movwf","%s",d);
1456                         
1457                         if(strcmp(s,"W")) {
1458                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1459                                 if(offset >= aop->size) {
1460                                         emitpcode(POC_CLRF,popGet(aop,offset));
1461                                         break;
1462                                 } else
1463                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1464                         }
1465                         
1466                         emitpcode(POC_MOVWF,popGet(aop,offset));
1467                         
1468                         
1469                 }
1470                 break;
1471                 
1472         case AOP_REG:
1473                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1474                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1475                         /*
1476                         if (*s == '@'             ||
1477                         strcmp(s,"r0") == 0 ||
1478                         strcmp(s,"r1") == 0 ||
1479                         strcmp(s,"r2") == 0 ||
1480                         strcmp(s,"r3") == 0 ||
1481                         strcmp(s,"r4") == 0 ||
1482                         strcmp(s,"r5") == 0 ||
1483                         strcmp(s,"r6") == 0 || 
1484                         strcmp(s,"r7") == 0 )
1485                         pic14_emitcode("mov","%s,%s  ; %d",
1486                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1487                         else
1488                         */
1489                         
1490                         if(strcmp(s,"W")==0 )
1491                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1492                         
1493                         pic14_emitcode("movwf","%s",
1494                                 aop->aopu.aop_reg[offset]->name);
1495                         
1496                         if(strcmp(s,zero)==0) {
1497                                 emitpcode(POC_CLRF,popGet(aop,offset));
1498                                 
1499                         } else if(strcmp(s,"W")==0) {
1500                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1501                                 pcop->type = PO_GPR_REGISTER;
1502                                 
1503                                 PCOR(pcop)->rIdx = -1;
1504                                 PCOR(pcop)->r = NULL;
1505                                 
1506                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1507                                 pcop->name = Safe_strdup(s);
1508                                 emitpcode(POC_MOVFW,pcop);
1509                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1510                         } else if(strcmp(s,one)==0) {
1511                                 emitpcode(POC_CLRF,popGet(aop,offset));
1512                                 emitpcode(POC_INCF,popGet(aop,offset));
1513                         } else {
1514                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1515                         }
1516                 }
1517                 break;
1518                 
1519         case AOP_DPTR:
1520         case AOP_DPTR2:
1521                 
1522                 if (aop->type == AOP_DPTR2)
1523                 {
1524                         genSetDPTR(1);
1525                 }
1526                 
1527                 if (aop->code) {
1528                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1529                                 "aopPut writting to code space");
1530                         exit(0);
1531                 }
1532                 
1533                 while (offset > aop->coff) {
1534                         aop->coff++;
1535                         pic14_emitcode ("inc","dptr");
1536                 }
1537                 
1538                 while (offset < aop->coff) {
1539                         aop->coff-- ;
1540                         pic14_emitcode("lcall","__decdptr");
1541                 }
1542                 
1543                 aop->coff = offset;
1544                 
1545                 /* if not in accumulater */
1546                 MOVA(s);
1547                 
1548                 pic14_emitcode ("movx","@dptr,a");
1549                 
1550                 if (aop->type == AOP_DPTR2)
1551                 {
1552                         genSetDPTR(0);
1553                 }
1554                 break;
1555                 
1556         case AOP_R0:
1557         case AOP_R1:
1558                 while (offset > aop->coff) {
1559                         aop->coff++;
1560                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1561                 }
1562                 while (offset < aop->coff) {
1563                         aop->coff-- ;
1564                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1565                 }
1566                 aop->coff = offset;
1567                 
1568                 if (aop->paged) {
1569                         MOVA(s);                         
1570                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1571                         
1572                 } else
1573                         if (*s == '@') {
1574                                 MOVA(s);
1575                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1576                         } else
1577                                 if (strcmp(s,"r0") == 0 ||
1578                                         strcmp(s,"r1") == 0 ||
1579                                         strcmp(s,"r2") == 0 ||
1580                                         strcmp(s,"r3") == 0 ||
1581                                         strcmp(s,"r4") == 0 ||
1582                                         strcmp(s,"r5") == 0 ||
1583                                         strcmp(s,"r6") == 0 || 
1584                                         strcmp(s,"r7") == 0 ) {
1585                                         char buffer[10];
1586                                         sprintf(buffer,"a%s",s);
1587                                         pic14_emitcode("mov","@%s,%s",
1588                                                 aop->aopu.aop_ptr->name,buffer);
1589                                 } else
1590                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1591                                 
1592                                 break;
1593                                 
1594         case AOP_STK:
1595                 if (strcmp(s,"a") == 0)
1596                         pic14_emitcode("push","acc");
1597                 else
1598                         pic14_emitcode("push","%s",s);
1599                 
1600                 break;
1601                 
1602         case AOP_CRY:
1603                 /* if bit variable */
1604                 if (!aop->aopu.aop_dir) {
1605                         pic14_emitcode("clr","a");
1606                         pic14_emitcode("rlc","a");
1607                 } else {
1608                         if (s == zero) 
1609                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1610                         else
1611                                 if (s == one)
1612                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1613                                 else
1614                                         if (!strcmp(s,"c"))
1615                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1616                                         else {
1617                                                 lbl = newiTempLabel(NULL);
1618                                                 
1619                                                 if (strcmp(s,"a")) {
1620                                                         MOVA(s);
1621                                                 }
1622                                                 pic14_emitcode("clr","c");
1623                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1624                                                 pic14_emitcode("cpl","c");
1625                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1626                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1627                                         }
1628                 }
1629                 break;
1630                 
1631         case AOP_STR:
1632                 aop->coff = offset;
1633                 if (strcmp(aop->aopu.aop_str[offset],s))
1634                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1635                 break;
1636                 
1637         case AOP_ACC:
1638                 aop->coff = offset;
1639                 if (!offset && (strcmp(s,"acc") == 0))
1640                         break;
1641                 
1642                 if (strcmp(aop->aopu.aop_str[offset],s))
1643                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1644                 break;
1645                 
1646         default :
1647                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1648                         "aopPut got unsupported aop->type");
1649                 exit(0);
1650         }
1651         
1652 }
1653
1654 /*-----------------------------------------------------------------*/
1655 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1656 /*-----------------------------------------------------------------*/
1657 void mov2w (asmop *aop, int offset)
1658 {
1659         
1660         if(!aop)
1661                 return;
1662         
1663         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1664         
1665         if ( aop->type == AOP_PCODE ||
1666                 aop->type == AOP_LIT ||
1667                 aop->type == AOP_IMMD )
1668                 emitpcode(POC_MOVLW,popGet(aop,offset));
1669         else
1670                 emitpcode(POC_MOVFW,popGet(aop,offset));
1671         
1672 }
1673
1674 /*-----------------------------------------------------------------*/
1675 /* reAdjustPreg - points a register back to where it should        */
1676 /*-----------------------------------------------------------------*/
1677 static void reAdjustPreg (asmop *aop)
1678 {
1679         int size ;
1680         
1681         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1682         aop->coff = 0;
1683         if ((size = aop->size) <= 1)
1684                 return ;
1685         size-- ;
1686         switch (aop->type) {
1687         case AOP_R0 :
1688         case AOP_R1 :
1689                 while (size--)
1690                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1691                 break;                  
1692         case AOP_DPTR :
1693         case AOP_DPTR2:
1694                 if (aop->type == AOP_DPTR2)
1695                 {
1696                         genSetDPTR(1);
1697                 } 
1698                 while (size--)
1699                 {
1700                         pic14_emitcode("lcall","__decdptr");
1701                 }
1702                 
1703                 if (aop->type == AOP_DPTR2)
1704                 {
1705                         genSetDPTR(0);
1706                 }
1707                 break;
1708                 
1709         }
1710         
1711 }
1712
1713
1714 #if 0
1715 /*-----------------------------------------------------------------*/
1716 /* opIsGptr: returns non-zero if the passed operand is             */
1717 /* a generic pointer type.                                         */
1718 /*-----------------------------------------------------------------*/ 
1719 static int opIsGptr(operand *op)
1720 {
1721         sym_link *type = operandType(op);
1722         
1723         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1724         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1725         {
1726                 return 1;
1727         }
1728         return 0;          
1729 }
1730 #endif
1731
1732 /*-----------------------------------------------------------------*/
1733 /* pic14_getDataSize - get the operand data size                   */
1734 /*-----------------------------------------------------------------*/
1735 int pic14_getDataSize(operand *op)
1736 {
1737         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1738         
1739         
1740         return AOP_SIZE(op);
1741         
1742         // tsd- in the pic port, the genptr size is 1, so this code here
1743         // fails. ( in the 8051 port, the size was 4).
1744 #if 0
1745         int size;
1746         size = AOP_SIZE(op);
1747         if (size == GPTRSIZE)
1748         {
1749                 sym_link *type = operandType(op);
1750                 if (IS_GENPTR(type))
1751                 {
1752                 /* generic pointer; arithmetic operations
1753                 * should ignore the high byte (pointer type).
1754                         */
1755                         size--;
1756                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1757                 }
1758         }
1759         return size;
1760 #endif
1761 }
1762
1763 /*-----------------------------------------------------------------*/
1764 /* pic14_outAcc - output Acc                                       */
1765 /*-----------------------------------------------------------------*/
1766 void pic14_outAcc(operand *result)
1767 {
1768         int size,offset;
1769         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1770         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1771         
1772         
1773         size = pic14_getDataSize(result);
1774         if(size){
1775                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1776                 size--;
1777                 offset = 1;
1778                 /* unsigned or positive */
1779                 while(size--)
1780                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1781         }
1782         
1783 }
1784
1785 /*-----------------------------------------------------------------*/
1786 /* pic14_outBitC - output a bit C                                  */
1787 /*-----------------------------------------------------------------*/
1788 void pic14_outBitC(operand *result)
1789 {
1790         
1791         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1792         /* if the result is bit */
1793         if (AOP_TYPE(result) == AOP_CRY) 
1794                 aopPut(AOP(result),"c",0);
1795         else {
1796                 pic14_emitcode("clr","a  ; %d", __LINE__);
1797                 pic14_emitcode("rlc","a");
1798                 pic14_outAcc(result);
1799         }
1800 }
1801
1802 /*-----------------------------------------------------------------*/
1803 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1804 /*-----------------------------------------------------------------*/
1805 void pic14_toBoolean(operand *oper)
1806 {
1807         int size = AOP_SIZE(oper) - 1;
1808         int offset = 1;
1809         
1810         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1811         
1812         if ( AOP_TYPE(oper) != AOP_ACC) {
1813                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1814         }
1815         while (size--) {
1816                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1817         }
1818 }
1819
1820
1821 /*-----------------------------------------------------------------*/
1822 /* genNot - generate code for ! operation                          */
1823 /*-----------------------------------------------------------------*/
1824 static void genNot (iCode *ic)
1825 {
1826         symbol *tlbl;
1827         int size;
1828         
1829         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1830         /* assign asmOps to operand & result */
1831         aopOp (IC_LEFT(ic),ic,FALSE);
1832         aopOp (IC_RESULT(ic),ic,TRUE);
1833         
1834         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1835         /* if in bit space then a special case */
1836         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1837                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1838                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1839                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1840                 } else {
1841                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1842                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1843                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1844                 }
1845                 goto release;
1846         }
1847         
1848         size = AOP_SIZE(IC_LEFT(ic));
1849         if(size == 1) {
1850                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1851                 emitpcode(POC_ANDLW,popGetLit(1));
1852                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1853                 goto release;
1854         }
1855         pic14_toBoolean(IC_LEFT(ic));
1856         
1857         tlbl = newiTempLabel(NULL);
1858         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1859         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1860         pic14_outBitC(IC_RESULT(ic));
1861         
1862 release:        
1863         /* release the aops */
1864         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1865         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1866 }
1867
1868
1869 /*-----------------------------------------------------------------*/
1870 /* genCpl - generate code for complement                                                   */
1871 /*-----------------------------------------------------------------*/
1872 static void genCpl (iCode *ic)
1873 {
1874         operand *left, *result;
1875         int size, offset=0;  
1876         
1877         
1878         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1879         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1880         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1881         
1882         /* if both are in bit space then 
1883         a special case */
1884         if (AOP_TYPE(result) == AOP_CRY &&
1885                 AOP_TYPE(left) == AOP_CRY ) { 
1886                 
1887                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1888                 pic14_emitcode("cpl","c"); 
1889                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1890                 goto release; 
1891         } 
1892         
1893         size = AOP_SIZE(result);
1894         while (size--) {
1895                 
1896                 if(AOP_TYPE(left) == AOP_ACC) 
1897                         emitpcode(POC_XORLW, popGetLit(0xff));
1898                 else
1899                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1900                 
1901                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1902                 offset++;
1903         }
1904         
1905         
1906 release:
1907         /* release the aops */
1908         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1909         freeAsmop(result,NULL,ic,TRUE);
1910 }
1911
1912 /*-----------------------------------------------------------------*/
1913 /* genUminusFloat - unary minus for floating points                        */
1914 /*-----------------------------------------------------------------*/
1915 static void genUminusFloat(operand *op,operand *result)
1916 {
1917         int size ,offset =0 ;
1918         char *l;
1919         
1920         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1921         /* for this we just need to flip the 
1922         first it then copy the rest in place */
1923         size = AOP_SIZE(op) - 1;
1924         l = aopGet(AOP(op),3,FALSE,FALSE);
1925         
1926         MOVA(l);          
1927         
1928         pic14_emitcode("cpl","acc.7");
1929         aopPut(AOP(result),"a",3);      
1930         
1931         while(size--) {
1932                 aopPut(AOP(result),
1933                         aopGet(AOP(op),offset,FALSE,FALSE),
1934                         offset);
1935                 offset++;
1936         }                
1937 }
1938
1939 /*-----------------------------------------------------------------*/
1940 /* genUminus - unary minus code generation                                                 */
1941 /*-----------------------------------------------------------------*/
1942 static void genUminus (iCode *ic)
1943 {
1944         int size, i;
1945         sym_link *optype, *rtype;
1946         
1947         
1948         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1949         /* assign asmops */
1950         aopOp(IC_LEFT(ic),ic,FALSE);
1951         aopOp(IC_RESULT(ic),ic,TRUE);
1952         
1953         /* if both in bit space then special
1954         case */
1955         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1956                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1957                 
1958                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
1959                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1960                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
1961                 
1962                 goto release; 
1963         } 
1964         
1965         optype = operandType(IC_LEFT(ic));
1966         rtype = operandType(IC_RESULT(ic));
1967         
1968         /* if float then do float stuff */
1969         if (IS_FLOAT(optype)) {
1970                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1971                 goto release;
1972         }
1973         
1974         /* otherwise subtract from zero by taking the 2's complement */
1975         size = AOP_SIZE(IC_LEFT(ic));
1976         
1977         for(i=0; i<size; i++) {
1978                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1979                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1980                 else {
1981                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1982                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1983                 }
1984         }
1985         
1986         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1987         for(i=1; i<size; i++) {
1988                 emitSKPNZ;
1989                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1990         }
1991         
1992 release:
1993         /* release the aops */
1994         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1995         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
1996 }
1997
1998 /*-----------------------------------------------------------------*/
1999 /* saveRegisters - will look for a call and save the registers     */
2000 /*-----------------------------------------------------------------*/
2001 static void saveRegisters(iCode *lic) 
2002 {
2003         int i;
2004         iCode *ic;
2005         bitVect *rsave;
2006         sym_link *dtype;
2007         
2008         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2009         /* look for call */
2010         for (ic = lic ; ic ; ic = ic->next) 
2011                 if (ic->op == CALL || ic->op == PCALL)
2012                         break;
2013                 
2014                 if (!ic) {
2015                         fprintf(stderr,"found parameter push with no function call\n");
2016                         return ;
2017                 }
2018                 
2019                 /* if the registers have been saved already then
2020                 do nothing */
2021                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2022                         return ;
2023                 
2024                         /* find the registers in use at this time 
2025                 and push them away to safety */
2026                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2027                         ic->rUsed);
2028                 
2029                 ic->regsSaved = 1;
2030                 if (options.useXstack) {
2031                         if (bitVectBitValue(rsave,R0_IDX))
2032                                 pic14_emitcode("mov","b,r0");
2033                         pic14_emitcode("mov","r0,%s",spname);
2034                         for (i = 0 ; i < pic14_nRegs ; i++) {
2035                                 if (bitVectBitValue(rsave,i)) {
2036                                         if (i == R0_IDX)
2037                                                 pic14_emitcode("mov","a,b");
2038                                         else
2039                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2040                                         pic14_emitcode("movx","@r0,a");
2041                                         pic14_emitcode("inc","r0");
2042                                 }
2043                         }
2044                         pic14_emitcode("mov","%s,r0",spname);
2045                         if (bitVectBitValue(rsave,R0_IDX))
2046                                 pic14_emitcode("mov","r0,b");     
2047                 }// else
2048                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2049                 //        if (bitVectBitValue(rsave,i))
2050                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2051                 //}
2052                 
2053                 dtype = operandType(IC_LEFT(ic));
2054                 if (currFunc && dtype && 
2055                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2056                         IFFUNC_ISISR(currFunc->type) &&
2057                         !ic->bankSaved) 
2058                         
2059                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2060                 
2061 }
2062 /*-----------------------------------------------------------------*/
2063 /* unsaveRegisters - pop the pushed registers                                      */
2064 /*-----------------------------------------------------------------*/
2065 static void unsaveRegisters (iCode *ic)
2066 {
2067         int i;
2068         bitVect *rsave;
2069         
2070         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2071         /* find the registers in use at this time 
2072         and push them away to safety */
2073         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2074                 ic->rUsed);
2075         
2076         if (options.useXstack) {
2077                 pic14_emitcode("mov","r0,%s",spname); 
2078                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2079                         if (bitVectBitValue(rsave,i)) {
2080                                 pic14_emitcode("dec","r0");
2081                                 pic14_emitcode("movx","a,@r0");
2082                                 if (i == R0_IDX)
2083                                         pic14_emitcode("mov","b,a");
2084                                 else
2085                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2086                         }       
2087                         
2088                 }
2089                 pic14_emitcode("mov","%s,r0",spname);
2090                 if (bitVectBitValue(rsave,R0_IDX))
2091                         pic14_emitcode("mov","r0,b");
2092         } //else
2093         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2094         //      if (bitVectBitValue(rsave,i))
2095         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2096         //}
2097         
2098 }  
2099
2100
2101 /*-----------------------------------------------------------------*/
2102 /* pushSide -                            */
2103 /*-----------------------------------------------------------------*/
2104 static void pushSide(operand * oper, int size)
2105 {
2106 #if 0
2107         int offset = 0;
2108         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2109         while (size--) {
2110                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2111                 if (AOP_TYPE(oper) != AOP_REG &&
2112                         AOP_TYPE(oper) != AOP_DIR &&
2113                         strcmp(l,"a") ) {
2114                         pic14_emitcode("mov","a,%s",l);
2115                         pic14_emitcode("push","acc");
2116                 } else
2117                         pic14_emitcode("push","%s",l);
2118         }
2119 #endif
2120 }
2121
2122 /*-----------------------------------------------------------------*/
2123 /* assignResultValue -                           */
2124 /*-----------------------------------------------------------------*/
2125 static void assignResultValue(operand * oper)
2126 {
2127         int size = AOP_SIZE(oper);
2128         
2129         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2130         
2131         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2132         
2133         while (size--) {
2134                 if (GpsuedoStkPtr++)
2135                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2136                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2137         }
2138 }
2139
2140
2141 /*-----------------------------------------------------------------*/
2142 /* genIpush - genrate code for pushing this gets a little complex  */
2143 /*-----------------------------------------------------------------*/
2144 static void genIpush (iCode *ic)
2145 {
2146         
2147         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2148 #if 0
2149         int size, offset = 0 ;
2150         char *l;
2151         
2152         
2153         /* if this is not a parm push : ie. it is spill push 
2154         and spill push is always done on the local stack */
2155         if (!ic->parmPush) {
2156                 
2157                 /* and the item is spilt then do nothing */
2158                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2159                         return ;
2160                 
2161                 aopOp(IC_LEFT(ic),ic,FALSE);
2162                 size = AOP_SIZE(IC_LEFT(ic));
2163                 /* push it on the stack */
2164                 while(size--) {
2165                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2166                         if (*l == '#') {
2167                                 MOVA(l);
2168                                 l = "acc";
2169                         }
2170                         pic14_emitcode("push","%s",l);
2171                 }
2172                 return ;                
2173         }
2174         
2175         /* this is a paramter push: in this case we call
2176         the routine to find the call and save those
2177         registers that need to be saved */   
2178         saveRegisters(ic);
2179         
2180         /* then do the push */
2181         aopOp(IC_LEFT(ic),ic,FALSE);
2182         
2183         
2184         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2185         size = AOP_SIZE(IC_LEFT(ic));
2186         
2187         while (size--) {
2188                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2189                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2190                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2191                         strcmp(l,"a") ) {
2192                         pic14_emitcode("mov","a,%s",l);
2193                         pic14_emitcode("push","acc");
2194                 } else
2195                         pic14_emitcode("push","%s",l);
2196         }         
2197         
2198         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2199 #endif
2200 }
2201
2202 /*-----------------------------------------------------------------*/
2203 /* genIpop - recover the registers: can happen only for spilling   */
2204 /*-----------------------------------------------------------------*/
2205 static void genIpop (iCode *ic)
2206 {
2207         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2208 #if 0
2209         int size,offset ;
2210         
2211         
2212         /* if the temp was not pushed then */
2213         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2214                 return ;
2215         
2216         aopOp(IC_LEFT(ic),ic,FALSE);
2217         size = AOP_SIZE(IC_LEFT(ic));
2218         offset = (size-1);
2219         while (size--) 
2220                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2221                 FALSE,TRUE));
2222         
2223         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2224 #endif
2225 }
2226
2227 /*-----------------------------------------------------------------*/
2228 /* unsaverbank - restores the resgister bank from stack                    */
2229 /*-----------------------------------------------------------------*/
2230 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2231 {
2232         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2233 #if 0
2234         int i;
2235         asmop *aop ;
2236         regs *r = NULL;
2237         
2238         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2239         if (popPsw) {
2240                 if (options.useXstack) {
2241                         aop = newAsmop(0);
2242                         r = getFreePtr(ic,&aop,FALSE);
2243                         
2244                         
2245                         pic14_emitcode("mov","%s,_spx",r->name);
2246                         pic14_emitcode("movx","a,@%s",r->name);
2247                         pic14_emitcode("mov","psw,a");
2248                         pic14_emitcode("dec","%s",r->name);
2249                         
2250                 }else
2251                         pic14_emitcode ("pop","psw");
2252         }
2253         
2254         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2255                 if (options.useXstack) {           
2256                         pic14_emitcode("movx","a,@%s",r->name);
2257                         //pic14_emitcode("mov","(%s+%d),a",
2258                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2259                         pic14_emitcode("dec","%s",r->name);
2260                         
2261                 } else 
2262                         pic14_emitcode("pop",""); //"(%s+%d)",
2263                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2264         }
2265         
2266         if (options.useXstack) {
2267                 
2268                 pic14_emitcode("mov","_spx,%s",r->name);
2269                 freeAsmop(NULL,aop,ic,TRUE);
2270                 
2271         }
2272 #endif 
2273 }
2274
2275 /*-----------------------------------------------------------------*/
2276 /* saverbank - saves an entire register bank on the stack                  */
2277 /*-----------------------------------------------------------------*/
2278 static void saverbank (int bank, iCode *ic, bool pushPsw)
2279 {
2280         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2281 #if 0
2282         int i;
2283         asmop *aop ;
2284         regs *r = NULL;
2285         
2286         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2287         if (options.useXstack) {
2288                 
2289                 aop = newAsmop(0);
2290                 r = getFreePtr(ic,&aop,FALSE);  
2291                 pic14_emitcode("mov","%s,_spx",r->name);
2292                 
2293         }
2294         
2295         for (i = 0 ; i < pic14_nRegs ;i++) {
2296                 if (options.useXstack) {
2297                         pic14_emitcode("inc","%s",r->name);
2298                         //pic14_emitcode("mov","a,(%s+%d)",
2299                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2300                         pic14_emitcode("movx","@%s,a",r->name);                 
2301                 } else 
2302                         pic14_emitcode("push","");// "(%s+%d)",
2303                 //regspic14[i].base,8*bank+regspic14[i].offset);
2304         }
2305         
2306         if (pushPsw) {
2307                 if (options.useXstack) {
2308                         pic14_emitcode("mov","a,psw");
2309                         pic14_emitcode("movx","@%s,a",r->name); 
2310                         pic14_emitcode("inc","%s",r->name);
2311                         pic14_emitcode("mov","_spx,%s",r->name);                 
2312                         freeAsmop (NULL,aop,ic,TRUE);
2313                         
2314                 } else
2315                         pic14_emitcode("push","psw");
2316                 
2317                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2318         }
2319         ic->bankSaved = 1;
2320 #endif
2321 }
2322
2323 /*-----------------------------------------------------------------*/
2324 /* genCall - generates a call statement                                                    */
2325 /*-----------------------------------------------------------------*/
2326 static void genCall (iCode *ic)
2327 {
2328         sym_link *dtype;         
2329         symbol *sym;
2330         unsigned char *name;
2331         int isExtern;
2332         
2333         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2334         
2335         /* if caller saves & we have not saved then */
2336         if (!ic->regsSaved)
2337                 saveRegisters(ic);
2338         
2339                 /* if we are calling a function that is not using
2340                 the same register bank then we need to save the
2341         destination registers on the stack */
2342         dtype = operandType(IC_LEFT(ic));
2343         if (currFunc && dtype && 
2344                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2345                 IFFUNC_ISISR(currFunc->type) &&
2346                 !ic->bankSaved) 
2347                 
2348                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2349         
2350         /* if send set is not empty the assign */
2351         if (_G.sendSet) {
2352                 iCode *sic;
2353                 /* For the Pic port, there is no data stack.
2354                 * So parameters passed to functions are stored
2355                 * in registers. (The pCode optimizer will get
2356                 * rid of most of these :).
2357                 */
2358                 int psuedoStkPtr=-1;
2359                 int firstTimeThruLoop = 1;
2360                 
2361                 _G.sendSet = reverseSet(_G.sendSet);
2362                 
2363                 /* First figure how many parameters are getting passed */
2364                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2365                 sic = setNextItem(_G.sendSet)) {
2366                         
2367                         aopOp(IC_LEFT(sic),sic,FALSE);
2368                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2369                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2370                 }
2371                 
2372                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2373                 sic = setNextItem(_G.sendSet)) {
2374                         int size, offset = 0;
2375                         
2376                         aopOp(IC_LEFT(sic),sic,FALSE);
2377                         size = AOP_SIZE(IC_LEFT(sic));
2378                         
2379                         while (size--) {
2380                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2381                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2382                                 
2383                                 if(!firstTimeThruLoop) {
2384                                 /* If this is not the first time we've been through the loop
2385                                 * then we need to save the parameter in a temporary
2386                                 * register. The last byte of the last parameter is
2387                                         * passed in W. */
2388                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2389                                         
2390                                 }
2391                                 firstTimeThruLoop=0;
2392                                 
2393                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2394                                 offset++;
2395                         }
2396                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2397                 }
2398                 _G.sendSet = NULL;
2399         }
2400         /* make the call */
2401         sym = OP_SYMBOL(IC_LEFT(ic));
2402         name = sym->rname[0] ? sym->rname : sym->name;
2403         isExtern = IS_EXTERN(sym->etype);
2404         if (isExtern) {
2405                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2406         }
2407         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2408         if (isExtern) {
2409                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2410         }
2411         GpsuedoStkPtr=0;
2412         /* if we need assign a result value */
2413         if ((IS_ITEMP(IC_RESULT(ic)) && 
2414                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2415                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2416                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2417                 
2418                 _G.accInUse++;
2419                 aopOp(IC_RESULT(ic),ic,FALSE);
2420                 _G.accInUse--;
2421                 
2422                 assignResultValue(IC_RESULT(ic));
2423                 
2424                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2425                         AopType(AOP_TYPE(IC_RESULT(ic))));
2426                 
2427                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2428         }
2429         
2430         /* adjust the stack for parameters if 
2431         required */
2432         if (ic->parmBytes) {
2433                 int i;
2434                 if (ic->parmBytes > 3) {
2435                         pic14_emitcode("mov","a,%s",spname);
2436                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2437                         pic14_emitcode("mov","%s,a",spname);
2438                 } else 
2439                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2440                                 pic14_emitcode("dec","%s",spname);
2441                         
2442         }
2443         
2444         /* if register bank was saved then pop them */
2445         if (ic->bankSaved)
2446                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2447         
2448         /* if we hade saved some registers then unsave them */
2449         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2450                 unsaveRegisters (ic);
2451         
2452         
2453 }
2454
2455 /*-----------------------------------------------------------------*/
2456 /* genPcall - generates a call by pointer statement                        */
2457 /*-----------------------------------------------------------------*/
2458 static void genPcall (iCode *ic)
2459 {
2460         sym_link *dtype;
2461         symbol *albl = newiTempLabel(NULL);
2462         symbol *blbl = newiTempLabel(NULL);
2463         PIC_OPCODE poc;
2464         pCodeOp *pcop;
2465         operand *left;
2466         
2467         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2468         /* if caller saves & we have not saved then */
2469         if (!ic->regsSaved)
2470                 saveRegisters(ic);
2471         
2472                 /* if we are calling a function that is not using
2473                 the same register bank then we need to save the
2474         destination registers on the stack */
2475         dtype = operandType(IC_LEFT(ic));
2476         if (currFunc && dtype && 
2477                 IFFUNC_ISISR(currFunc->type) &&
2478                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2479                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2480         
2481         left = IC_LEFT(ic);
2482         aopOp(left,ic,FALSE);
2483         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2484         
2485         pushSide(IC_LEFT(ic), FPTRSIZE);
2486         
2487         /* if send set is not empty, assign parameters */
2488         if (_G.sendSet) {
2489                 
2490                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2491                 /* no way to pass args - W always gets used to make the call */
2492         }
2493         /* first idea - factor out a common helper function and call it.
2494         But don't know how to get it generated only once in its own block
2495         
2496         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2497                 char *rname;
2498                 char *buffer;
2499                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2500                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2501                 buffer = Safe_calloc(1,strlen(rname)+16);
2502                 sprintf(buffer, "%s_goto_helper", rname);
2503                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2504                 free(buffer);
2505         }
2506         */
2507         emitpcode(POC_CALL,popGetLabel(albl->key));
2508         pcop = popGetLabel(blbl->key);
2509         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2510         emitpcode(POC_GOTO,pcop);
2511         emitpLabel(albl->key);
2512         
2513         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2514         
2515         emitpcode(poc,popGet(AOP(left),1));
2516         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2517         emitpcode(poc,popGet(AOP(left),0));
2518         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2519         
2520         emitpLabel(blbl->key);
2521         
2522         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2523         
2524         /* if we need to assign a result value */
2525         if ((IS_ITEMP(IC_RESULT(ic)) &&
2526                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2527                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2528                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2529                 
2530                 _G.accInUse++;
2531                 aopOp(IC_RESULT(ic),ic,FALSE);
2532                 _G.accInUse--;
2533                 
2534                 assignResultValue(IC_RESULT(ic));
2535                 
2536                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2537         }
2538         
2539         /* if register bank was saved then unsave them */
2540         if (currFunc && dtype && 
2541                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2542                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2543         
2544                 /* if we hade saved some registers then
2545         unsave them */
2546         if (ic->regsSaved)
2547                 unsaveRegisters (ic);
2548         
2549 }
2550
2551 /*-----------------------------------------------------------------*/
2552 /* resultRemat - result  is rematerializable                                       */
2553 /*-----------------------------------------------------------------*/
2554 static int resultRemat (iCode *ic)
2555 {
2556         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2557         if (SKIP_IC(ic) || ic->op == IFX)
2558                 return 0;
2559         
2560         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2561                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2562                 if (sym->remat && !POINTER_SET(ic)) 
2563                         return 1;
2564         }
2565         
2566         return 0;
2567 }
2568
2569 #if defined(__BORLANDC__) || defined(_MSC_VER)
2570 #define STRCASECMP stricmp
2571 #else
2572 #define STRCASECMP strcasecmp
2573 #endif
2574
2575 #if 0
2576 /*-----------------------------------------------------------------*/
2577 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2578 /*-----------------------------------------------------------------*/
2579 static bool inExcludeList(char *s)
2580 {
2581         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2582         int i =0;
2583         
2584         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2585         if (options.excludeRegs[i] &&
2586                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2587                 return FALSE ;
2588         
2589         for ( i = 0 ; options.excludeRegs[i]; i++) {
2590                 if (options.excludeRegs[i] &&
2591                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2592                         return TRUE;
2593         }
2594         return FALSE ;
2595 }
2596 #endif
2597
2598 /*-----------------------------------------------------------------*/
2599 /* genFunction - generated code for function entry                                 */
2600 /*-----------------------------------------------------------------*/
2601 static void genFunction (iCode *ic)
2602 {
2603         symbol *sym;
2604         sym_link *ftype;
2605         
2606         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2607         
2608         labelOffset += (max_key+4);
2609         max_key=0;
2610         GpsuedoStkPtr=0;
2611         _G.nRegsSaved = 0;
2612         /* create the function header */
2613         pic14_emitcode(";","-----------------------------------------");
2614         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2615         pic14_emitcode(";","-----------------------------------------");
2616         
2617         pic14_emitcode("","%s:",sym->rname);
2618         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2619         
2620         ftype = operandType(IC_LEFT(ic));
2621         
2622         /* if critical function then turn interrupts off */
2623         if (IFFUNC_ISCRITICAL(ftype))
2624                 pic14_emitcode("clr","ea");
2625         
2626                 /* here we need to generate the equates for the
2627         register bank if required */
2628 #if 0
2629         if (FUNC_REGBANK(ftype) != rbank) {
2630                 int i ;
2631                 
2632                 rbank = FUNC_REGBANK(ftype);
2633                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2634                         if (strcmp(regspic14[i].base,"0") == 0)
2635                                 pic14_emitcode("","%s = 0x%02x",
2636                                 regspic14[i].dname,
2637                                 8*rbank+regspic14[i].offset);
2638                         else
2639                                 pic14_emitcode ("","%s = %s + 0x%02x",
2640                                 regspic14[i].dname,
2641                                 regspic14[i].base,
2642                                 8*rbank+regspic14[i].offset);
2643                 }
2644         }
2645 #endif
2646         
2647         /* if this is an interrupt service routine */
2648         if (IFFUNC_ISISR(sym->type)) {
2649         /*  already done in pic14createInterruptVect() - delete me
2650         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2651         emitpcodeNULLop(POC_NOP);
2652         emitpcodeNULLop(POC_NOP);
2653         emitpcodeNULLop(POC_NOP);
2654                 */
2655                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2656                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2657                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2658                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2659                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2660                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2661                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2662                 
2663                 pBlockConvert2ISR(pb);
2664 #if 0  
2665                 if (!inExcludeList("acc"))              
2666                         pic14_emitcode ("push","acc");  
2667                 if (!inExcludeList("b"))
2668                         pic14_emitcode ("push","b");
2669                 if (!inExcludeList("dpl"))
2670                         pic14_emitcode ("push","dpl");
2671                 if (!inExcludeList("dph"))
2672                         pic14_emitcode ("push","dph");
2673                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2674                 {
2675                         pic14_emitcode ("push", "dpx");
2676                         /* Make sure we're using standard DPTR */
2677                         pic14_emitcode ("push", "dps");
2678                         pic14_emitcode ("mov", "dps, #0x00");
2679                         if (options.stack10bit)
2680                         { 
2681                                 /* This ISR could conceivably use DPTR2. Better save it. */
2682                                 pic14_emitcode ("push", "dpl1");
2683                                 pic14_emitcode ("push", "dph1");
2684                                 pic14_emitcode ("push", "dpx1");
2685                         }
2686                 }
2687                 /* if this isr has no bank i.e. is going to
2688                 run with bank 0 , then we need to save more
2689 registers :-) */
2690                 if (!FUNC_REGBANK(sym->type)) {
2691                         
2692                 /* if this function does not call any other
2693                 function then we can be economical and
2694                         save only those registers that are used */
2695                         if (! IFFUNC_HASFCALL(sym->type)) {
2696                                 int i;
2697                                 
2698                                 /* if any registers used */
2699                                 if (sym->regsUsed) {
2700                                         /* save the registers used */
2701                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2702                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2703                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2704                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2705                                         }
2706                                 }
2707                                 
2708                         } else {
2709                         /* this function has    a function call cannot
2710                         determines register usage so we will have the
2711                                 entire bank */
2712                                 saverbank(0,ic,FALSE);
2713                         }       
2714                 }
2715 #endif
2716         } else {
2717         /* if callee-save to be used for this function
2718                 then save the registers being used in this function */
2719                 if (IFFUNC_CALLEESAVES(sym->type)) {
2720                         int i;
2721                         
2722                         /* if any registers used */
2723                         if (sym->regsUsed) {
2724                                 /* save the registers used */
2725                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2726                                         if (bitVectBitValue(sym->regsUsed,i) ||
2727                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2728                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2729                                                 _G.nRegsSaved++;
2730                                         }
2731                                 }
2732                         }
2733                 }
2734         }
2735         
2736         /* set the register bank to the desired value */
2737         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2738                 pic14_emitcode("push","psw");
2739                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2740         }
2741         
2742         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2743                 
2744                 if (options.useXstack) {
2745                         pic14_emitcode("mov","r0,%s",spname);
2746                         pic14_emitcode("mov","a,_bp");
2747                         pic14_emitcode("movx","@r0,a");
2748                         pic14_emitcode("inc","%s",spname);
2749                 }
2750                 else
2751                 {
2752                         /* set up the stack */
2753                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2754                 }
2755                 pic14_emitcode ("mov","_bp,%s",spname);
2756         }
2757         
2758         /* adjust the stack for the function */
2759         if (sym->stack) {
2760                 
2761                 int i = sym->stack;
2762                 if (i > 256 ) 
2763                         werror(W_STACK_OVERFLOW,sym->name);
2764                 
2765                 if (i > 3 && sym->recvSize < 4) {                
2766                         
2767                         pic14_emitcode ("mov","a,sp");
2768                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2769                         pic14_emitcode ("mov","sp,a");
2770                         
2771                 }
2772                 else
2773                         while(i--)
2774                                 pic14_emitcode("inc","sp");
2775         }
2776         
2777         if (sym->xstack) {
2778                 
2779                 pic14_emitcode ("mov","a,_spx");
2780                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2781                 pic14_emitcode ("mov","_spx,a");
2782         }
2783         
2784 }
2785
2786 /*-----------------------------------------------------------------*/
2787 /* genEndFunction - generates epilogue for functions                       */
2788 /*-----------------------------------------------------------------*/
2789 static void genEndFunction (iCode *ic)
2790 {
2791         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2792         
2793         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2794         
2795         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2796         {
2797                 pic14_emitcode ("mov","%s,_bp",spname);
2798         }
2799         
2800         /* if use external stack but some variables were
2801         added to the local stack then decrement the
2802         local stack */
2803         if (options.useXstack && sym->stack) {    
2804                 pic14_emitcode("mov","a,sp");
2805                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2806                 pic14_emitcode("mov","sp,a");
2807         }
2808         
2809         
2810         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2811                 if (options.useXstack) {
2812                         pic14_emitcode("mov","r0,%s",spname);
2813                         pic14_emitcode("movx","a,@r0");
2814                         pic14_emitcode("mov","_bp,a");
2815                         pic14_emitcode("dec","%s",spname);
2816                 }
2817                 else
2818                 {
2819                         pic14_emitcode ("pop","_bp");
2820                 }
2821         }
2822         
2823         /* restore the register bank    */        
2824         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2825                 pic14_emitcode ("pop","psw");
2826         
2827         if (IFFUNC_ISISR(sym->type)) {
2828                 
2829                 /* now we need to restore the registers */
2830                 /* if this isr has no bank i.e. is going to
2831                 run with bank 0 , then we need to save more
2832 registers :-) */
2833                 if (!FUNC_REGBANK(sym->type)) {
2834                         
2835                 /* if this function does not call any other
2836                 function then we can be economical and
2837                         save only those registers that are used */
2838                         if (! IFFUNC_HASFCALL(sym->type)) {
2839                                 int i;
2840                                 
2841                                 /* if any registers used */
2842                                 if (sym->regsUsed) {
2843                                         /* save the registers used */
2844                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2845                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2846                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2847                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2848                                         }
2849                                 }
2850                                 
2851                         } else {
2852                         /* this function has    a function call cannot
2853                         determines register usage so we will have the
2854                                 entire bank */
2855                                 unsaverbank(0,ic,FALSE);
2856                         }       
2857                 }
2858 #if 0
2859                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2860                 {
2861                         if (options.stack10bit)
2862                         {
2863                                 pic14_emitcode ("pop", "dpx1");
2864                                 pic14_emitcode ("pop", "dph1");
2865                                 pic14_emitcode ("pop", "dpl1");
2866                         } 
2867                         pic14_emitcode ("pop", "dps");
2868                         pic14_emitcode ("pop", "dpx");
2869                 }
2870                 if (!inExcludeList("dph"))
2871                         pic14_emitcode ("pop","dph");
2872                 if (!inExcludeList("dpl"))
2873                         pic14_emitcode ("pop","dpl");
2874                 if (!inExcludeList("b"))
2875                         pic14_emitcode ("pop","b");
2876                 if (!inExcludeList("acc"))
2877                         pic14_emitcode ("pop","acc");
2878                 
2879                 if (IFFUNC_ISCRITICAL(sym->type))
2880                         pic14_emitcode("setb","ea");
2881 #endif
2882                 
2883                 /* if debug then send end of function */
2884                 /*      if (options.debug && currFunc) { */
2885                 if (currFunc) {
2886                         debugFile->writeEndFunction (currFunc, ic, 1);
2887                 }
2888                 
2889                 pic14_emitcode ("reti","");
2890                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2891                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2892                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2893                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2894                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2895                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2896                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2897                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2898                 emitpcodeNULLop(POC_RETFIE);
2899         }
2900         else {
2901                 if (IFFUNC_ISCRITICAL(sym->type))
2902                         pic14_emitcode("setb","ea");
2903                 
2904                 if (IFFUNC_CALLEESAVES(sym->type)) {
2905                         int i;
2906                         
2907                         /* if any registers used */
2908                         if (sym->regsUsed) {
2909                                 /* save the registers used */
2910                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2911                                         if (bitVectBitValue(sym->regsUsed,i) ||
2912                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2913                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2914                                 }
2915                         }
2916                         
2917                 }
2918                 
2919                 /* if debug then send end of function */
2920                 if (currFunc) {
2921                         debugFile->writeEndFunction (currFunc, ic, 1);
2922                 }
2923                 
2924                 pic14_emitcode ("return","");
2925                 emitpcodeNULLop(POC_RETURN);
2926                 
2927                 /* Mark the end of a function */
2928                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2929         }
2930         
2931 }
2932
2933 /*-----------------------------------------------------------------*/
2934 /* genRet - generate code for return statement                                     */
2935 /*-----------------------------------------------------------------*/
2936 static void genRet (iCode *ic)
2937 {
2938         int size,offset = 0 , pushed = 0;
2939         
2940         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2941         /* if we have no return value then
2942         just generate the "ret" */
2943         if (!IC_LEFT(ic)) 
2944                 goto jumpret;           
2945         
2946                 /* we have something to return then
2947         move the return value into place */
2948         aopOp(IC_LEFT(ic),ic,FALSE);
2949         size = AOP_SIZE(IC_LEFT(ic));
2950         
2951         while (size--) {
2952                 char *l ;
2953                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2954                         /* #NOCHANGE */
2955                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
2956                                 FALSE,TRUE);
2957                         pic14_emitcode("push","%s",l);
2958                         pushed++;
2959                 } else {
2960                         l = aopGet(AOP(IC_LEFT(ic)),offset,
2961                                 FALSE,FALSE);
2962                         if (strcmp(fReturn[offset],l)) {
2963                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
2964                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2965                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2966                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2967                                         emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2968                                 }else {
2969                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2970                                 }
2971                                 if(size) {
2972                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2973                                 }
2974                                 offset++;
2975                         }
2976                 }
2977         }
2978         
2979         if (pushed) {
2980                 while(pushed) {
2981                         pushed--;
2982                         if (strcmp(fReturn[pushed],"a"))
2983                                 pic14_emitcode("pop",fReturn[pushed]);
2984                         else
2985                                 pic14_emitcode("pop","acc");
2986                 }
2987         }
2988         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2989         
2990 jumpret:
2991 /* generate a jump to the return label
2992         if the next is not the return statement */
2993         if (!(ic->next && ic->next->op == LABEL &&
2994                 IC_LABEL(ic->next) == returnLabel)) {
2995                 
2996                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2997                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2998         }
2999         
3000 }
3001
3002 /*-----------------------------------------------------------------*/
3003 /* genLabel - generates a label                                                                    */
3004 /*-----------------------------------------------------------------*/
3005 static void genLabel (iCode *ic)
3006 {
3007         /* special case never generate */
3008         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3009         if (IC_LABEL(ic) == entryLabel)
3010                 return ;
3011         
3012         emitpLabel(IC_LABEL(ic)->key);
3013         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3014 }
3015
3016 /*-----------------------------------------------------------------*/
3017 /* genGoto - generates a goto                                                                      */
3018 /*-----------------------------------------------------------------*/
3019 //tsd
3020 static void genGoto (iCode *ic)
3021 {
3022         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3023         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3024 }
3025
3026
3027 /*-----------------------------------------------------------------*/
3028 /* genMultbits :- multiplication of bits                                                   */
3029 /*-----------------------------------------------------------------*/
3030 static void genMultbits (operand *left, 
3031                                                  operand *right, 
3032                                                  operand *result)
3033 {
3034         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3035         
3036         if(!pic14_sameRegs(AOP(result),AOP(right)))
3037                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3038         
3039         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3040         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3041         emitpcode(POC_BCF,  popGet(AOP(result),0));
3042         
3043 }
3044
3045
3046 /*-----------------------------------------------------------------*/
3047 /* genMultOneByte : 8 bit multiplication & division                        */
3048 /*-----------------------------------------------------------------*/
3049 static void genMultOneByte (operand *left,
3050                                                         operand *right,
3051                                                         operand *result)
3052 {
3053         sym_link *opetype = operandType(result);
3054         
3055         // symbol *lbl ;
3056         int size,offset;
3057         
3058         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3059         DEBUGpic14_AopType(__LINE__,left,right,result);
3060         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3061         
3062         /* (if two literals, the value is computed before) */
3063         /* if one literal, literal on the right */
3064         if (AOP_TYPE(left) == AOP_LIT){
3065                 operand *t = right;
3066                 right = left;
3067                 left = t;
3068         }
3069         
3070         size = AOP_SIZE(result);
3071         if(size == 1) {
3072                 
3073                 if (AOP_TYPE(right) == AOP_LIT){
3074                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3075                                 aopGet(AOP(right),0,FALSE,FALSE), 
3076                                 aopGet(AOP(left),0,FALSE,FALSE), 
3077                                 aopGet(AOP(result),0,FALSE,FALSE));
3078                         pic14_emitcode("call","genMultLit");
3079                 } else {
3080                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3081                                 aopGet(AOP(right),0,FALSE,FALSE), 
3082                                 aopGet(AOP(left),0,FALSE,FALSE), 
3083                                 aopGet(AOP(result),0,FALSE,FALSE));
3084                         pic14_emitcode("call","genMult8X8_8");
3085                         
3086                 }
3087                 genMult8X8_8 (left, right,result);
3088                 
3089                 
3090                 /* signed or unsigned */
3091                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3092                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3093                 //MOVA(l);               
3094                 //pic14_emitcode("mul","ab");
3095                 /* if result size = 1, mul signed = mul unsigned */
3096                 //aopPut(AOP(result),"a",0);
3097                 
3098         } else {        // (size > 1)
3099                 
3100                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3101                         aopGet(AOP(right),0,FALSE,FALSE), 
3102                         aopGet(AOP(left),0,FALSE,FALSE), 
3103                         aopGet(AOP(result),0,FALSE,FALSE));
3104                 
3105                 if (SPEC_USIGN(opetype)){
3106                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3107                         genUMult8X8_16 (left, right, result, NULL);
3108                         
3109                         if (size > 2) {
3110                                 /* for filling the MSBs */
3111                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3112                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3113                         }
3114                 }
3115                 else{
3116                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3117                         
3118                         pic14_emitcode("mov","a,b");
3119                         
3120                         /* adjust the MSB if left or right neg */
3121                         
3122                         /* if one literal */
3123                         if (AOP_TYPE(right) == AOP_LIT){
3124                                 pic14_emitcode("multiply ","right is a lit");
3125                                 /* AND literal negative */
3126                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3127                                         /* adjust MSB (c==0 after mul) */
3128                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3129                                 }
3130                         }
3131                         else{
3132                                 genSMult8X8_16 (left, right, result, NULL);
3133                         }
3134                         
3135                         if(size > 2){
3136                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3137                                 /* get the sign */
3138                                 pic14_emitcode("rlc","a");
3139                                 pic14_emitcode("subb","a,acc");
3140                         }
3141                 }
3142                 
3143                 size -= 2;
3144                 offset = 2;
3145                 if (size > 0)
3146                         while (size--)
3147                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3148                         //aopPut(AOP(result),"a",offset++);
3149         }
3150 }
3151
3152 /*-----------------------------------------------------------------*/
3153 /* genMult - generates code for multiplication                                     */
3154 /*-----------------------------------------------------------------*/
3155 static void genMult (iCode *ic)
3156 {
3157         operand *left = IC_LEFT(ic);
3158         operand *right = IC_RIGHT(ic);
3159         operand *result= IC_RESULT(ic); 
3160         
3161         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3162         /* assign the amsops */
3163         aopOp (left,ic,FALSE);
3164         aopOp (right,ic,FALSE);
3165         aopOp (result,ic,TRUE);
3166         
3167         DEBUGpic14_AopType(__LINE__,left,right,result);
3168         
3169         /* special cases first */
3170         /* both are bits */
3171         if (AOP_TYPE(left) == AOP_CRY &&
3172                 AOP_TYPE(right)== AOP_CRY) {
3173                 genMultbits(left,right,result);
3174                 goto release ;
3175         }
3176         
3177         /* if both are of size == 1 */
3178         if (AOP_SIZE(left) == 1 &&
3179                 AOP_SIZE(right) == 1 ) {
3180                 genMultOneByte(left,right,result);
3181                 goto release ;
3182         }
3183         
3184         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3185         
3186         /* should have been converted to function call */
3187         //assert(0) ;
3188         
3189 release :
3190         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3191         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3192         freeAsmop(result,NULL,ic,TRUE); 
3193 }
3194
3195 /*-----------------------------------------------------------------*/
3196 /* genDivbits :- division of bits                                                                  */
3197 /*-----------------------------------------------------------------*/
3198 static void genDivbits (operand *left, 
3199                                                 operand *right, 
3200                                                 operand *result)
3201 {
3202         
3203         char *l;
3204         
3205         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3206         /* the result must be bit */      
3207         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3208         l = aopGet(AOP(left),0,FALSE,FALSE);
3209         
3210         MOVA(l);          
3211         
3212         pic14_emitcode("div","ab");
3213         pic14_emitcode("rrc","a");
3214         aopPut(AOP(result),"c",0);
3215 }
3216
3217 /*-----------------------------------------------------------------*/
3218 /* genDivOneByte : 8 bit division                                                                  */
3219 /*-----------------------------------------------------------------*/
3220 static void genDivOneByte (operand *left,
3221                                                    operand *right,
3222                                                    operand *result)
3223 {
3224         sym_link *opetype = operandType(result);
3225         char *l ;
3226         symbol *lbl ;
3227         int size,offset;
3228         
3229         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3230         size = AOP_SIZE(result) - 1;
3231         offset = 1;
3232         /* signed or unsigned */
3233         if (SPEC_USIGN(opetype)) {
3234                 /* unsigned is easy */
3235                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3236                 l = aopGet(AOP(left),0,FALSE,FALSE);
3237                 MOVA(l);                
3238                 pic14_emitcode("div","ab");
3239                 aopPut(AOP(result),"a",0);
3240                 while (size--)
3241                         aopPut(AOP(result),zero,offset++);
3242                 return ;
3243         }
3244         
3245         /* signed is a little bit more difficult */
3246         
3247         /* save the signs of the operands */
3248         l = aopGet(AOP(left),0,FALSE,FALSE);      
3249         MOVA(l);          
3250         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3251         pic14_emitcode("push","acc"); /* save it on the stack */
3252         
3253         /* now sign adjust for both left & right */
3254         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3255         MOVA(l);                 
3256         lbl = newiTempLabel(NULL);
3257         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3258         pic14_emitcode("cpl","a");   
3259         pic14_emitcode("inc","a");
3260         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3261         pic14_emitcode("mov","b,a");
3262         
3263         /* sign adjust left side */
3264         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3265         MOVA(l);
3266         
3267         lbl = newiTempLabel(NULL);
3268         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3269         pic14_emitcode("cpl","a");
3270         pic14_emitcode("inc","a");
3271         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3272         
3273         /* now the division */
3274         pic14_emitcode("div","ab");
3275         /* we are interested in the lower order
3276         only */
3277         pic14_emitcode("mov","b,a");
3278         lbl = newiTempLabel(NULL);
3279         pic14_emitcode("pop","acc");     
3280         /* if there was an over flow we don't 
3281         adjust the sign of the result */
3282         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3283         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3284         CLRC;
3285         pic14_emitcode("clr","a");
3286         pic14_emitcode("subb","a,b");
3287         pic14_emitcode("mov","b,a");
3288         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3289         
3290         /* now we are done */
3291         aopPut(AOP(result),"b",0);
3292         if(size > 0){
3293                 pic14_emitcode("mov","c,b.7");
3294                 pic14_emitcode("subb","a,acc");   
3295         }
3296         while (size--)
3297                 aopPut(AOP(result),"a",offset++);
3298         
3299 }
3300
3301 /*-----------------------------------------------------------------*/
3302 /* genDiv - generates code for division                                                    */
3303 /*-----------------------------------------------------------------*/
3304 static void genDiv (iCode *ic)
3305 {
3306         operand *left = IC_LEFT(ic);
3307         operand *right = IC_RIGHT(ic);
3308         operand *result= IC_RESULT(ic); 
3309         
3310         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3311         /* assign the amsops */
3312         aopOp (left,ic,FALSE);
3313         aopOp (right,ic,FALSE);
3314         aopOp (result,ic,TRUE);
3315         
3316         /* special cases first */
3317         /* both are bits */
3318         if (AOP_TYPE(left) == AOP_CRY &&
3319                 AOP_TYPE(right)== AOP_CRY) {
3320                 genDivbits(left,right,result);
3321                 goto release ;
3322         }
3323         
3324         /* if both are of size == 1 */
3325         if (AOP_SIZE(left) == 1 &&
3326                 AOP_SIZE(right) == 1 ) {
3327                 genDivOneByte(left,right,result);
3328                 goto release ;
3329         }
3330         
3331         /* should have been converted to function call */
3332         assert(0);
3333 release :
3334         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3335         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3336         freeAsmop(result,NULL,ic,TRUE); 
3337 }
3338
3339 /*-----------------------------------------------------------------*/
3340 /* genModbits :- modulus of bits                                                                   */
3341 /*-----------------------------------------------------------------*/
3342 static void genModbits (operand *left, 
3343                                                 operand *right, 
3344                                                 operand *result)
3345 {
3346         
3347         char *l;
3348         
3349         /* the result must be bit */      
3350         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3351         l = aopGet(AOP(left),0,FALSE,FALSE);
3352         
3353         MOVA(l);
3354         
3355         pic14_emitcode("div","ab");
3356         pic14_emitcode("mov","a,b");
3357         pic14_emitcode("rrc","a");
3358         aopPut(AOP(result),"c",0);
3359 }
3360
3361 /*-----------------------------------------------------------------*/
3362 /* genModOneByte : 8 bit modulus                                                                   */
3363 /*-----------------------------------------------------------------*/
3364 static void genModOneByte (operand *left,
3365                                                    operand *right,
3366                                                    operand *result)
3367 {
3368         sym_link *opetype = operandType(result);
3369         char *l ;
3370         symbol *lbl ;
3371         
3372         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3373         /* signed or unsigned */
3374         if (SPEC_USIGN(opetype)) {
3375                 /* unsigned is easy */
3376                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3377                 l = aopGet(AOP(left),0,FALSE,FALSE);
3378                 MOVA(l);        
3379                 pic14_emitcode("div","ab");
3380                 aopPut(AOP(result),"b",0);
3381                 return ;
3382         }
3383         
3384         /* signed is a little bit more difficult */
3385         
3386         /* save the signs of the operands */
3387         l = aopGet(AOP(left),0,FALSE,FALSE);      
3388         MOVA(l);
3389         
3390         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3391         pic14_emitcode("push","acc"); /* save it on the stack */
3392         
3393         /* now sign adjust for both left & right */
3394         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3395         MOVA(l);
3396         
3397         lbl = newiTempLabel(NULL);
3398         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3399         pic14_emitcode("cpl","a");   
3400         pic14_emitcode("inc","a");
3401         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3402         pic14_emitcode("mov","b,a"); 
3403         
3404         /* sign adjust left side */
3405         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3406         MOVA(l);
3407         
3408         lbl = newiTempLabel(NULL);
3409         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3410         pic14_emitcode("cpl","a");   
3411         pic14_emitcode("inc","a");
3412         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3413         
3414         /* now the multiplication */
3415         pic14_emitcode("div","ab");
3416         /* we are interested in the lower order
3417         only */
3418         lbl = newiTempLabel(NULL);
3419         pic14_emitcode("pop","acc");     
3420         /* if there was an over flow we don't 
3421         adjust the sign of the result */
3422         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3423         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3424         CLRC ;
3425         pic14_emitcode("clr","a");
3426         pic14_emitcode("subb","a,b");
3427         pic14_emitcode("mov","b,a");
3428         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3429         
3430         /* now we are done */
3431         aopPut(AOP(result),"b",0);
3432         
3433 }
3434
3435 /*-----------------------------------------------------------------*/
3436 /* genMod - generates code for division                                                    */
3437 /*-----------------------------------------------------------------*/
3438 static void genMod (iCode *ic)
3439 {
3440         operand *left = IC_LEFT(ic);
3441         operand *right = IC_RIGHT(ic);
3442         operand *result= IC_RESULT(ic);  
3443         
3444         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3445         /* assign the amsops */
3446         aopOp (left,ic,FALSE);
3447         aopOp (right,ic,FALSE);
3448         aopOp (result,ic,TRUE);
3449         
3450         /* special cases first */
3451         /* both are bits */
3452         if (AOP_TYPE(left) == AOP_CRY &&
3453                 AOP_TYPE(right)== AOP_CRY) {
3454                 genModbits(left,right,result);
3455                 goto release ;
3456         }
3457         
3458         /* if both are of size == 1 */
3459         if (AOP_SIZE(left) == 1 &&
3460                 AOP_SIZE(right) == 1 ) {
3461                 genModOneByte(left,right,result);
3462                 goto release ;
3463         }
3464         
3465         /* should have been converted to function call */
3466         assert(0);
3467         
3468 release :
3469         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3470         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3471         freeAsmop(result,NULL,ic,TRUE); 
3472 }
3473
3474 /*-----------------------------------------------------------------*/
3475 /* genIfxJump :- will create a jump depending on the ifx                   */
3476 /*-----------------------------------------------------------------*/
3477 /*
3478 note: May need to add parameter to indicate when a variable is in bit space.
3479 */
3480 static void genIfxJump (iCode *ic, char *jval)
3481 {
3482         
3483         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3484         /* if true label then we jump if condition
3485         supplied is true */
3486         if ( IC_TRUE(ic) ) {
3487                 
3488                 if(strcmp(jval,"a") == 0)
3489                         emitSKPZ;
3490                 else if (strcmp(jval,"c") == 0)
3491                         emitSKPC;
3492                 else {
3493                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3494                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3495                 }
3496                 
3497                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3498                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3499                 
3500         }
3501         else {
3502                 /* false label is present */
3503                 if(strcmp(jval,"a") == 0)
3504                         emitSKPNZ;
3505                 else if (strcmp(jval,"c") == 0)
3506                         emitSKPNC;
3507                 else {
3508                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3509                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3510                 }
3511                 
3512                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3513                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3514                 
3515         }
3516         
3517         
3518         /* mark the icode as generated */
3519         ic->generated = 1;
3520 }
3521
3522 /*-----------------------------------------------------------------*/
3523 /* genSkip                                                                                                                 */
3524 /*-----------------------------------------------------------------*/
3525 static void genSkip(iCode *ifx,int status_bit)
3526 {
3527         if(!ifx)
3528                 return;
3529         
3530         if ( IC_TRUE(ifx) ) {
3531                 switch(status_bit) {
3532                 case 'z':
3533                         emitSKPNZ;
3534                         break;
3535                         
3536                 case 'c':
3537                         emitSKPNC;
3538                         break;
3539                         
3540                 case 'd':
3541                         emitSKPDC;
3542                         break;
3543                         
3544                 }
3545                 
3546                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3547                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3548                 
3549         } else {
3550                 
3551                 switch(status_bit) {
3552                         
3553                 case 'z':
3554                         emitSKPZ;
3555                         break;
3556                         
3557                 case 'c':
3558                         emitSKPC;
3559                         break;
3560                         
3561                 case 'd':
3562                         emitSKPDC;
3563                         break;
3564                 }
3565                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3566                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3567                 
3568         }
3569         
3570 }
3571
3572 /*-----------------------------------------------------------------*/
3573 /* genSkipc                                                                                                        */
3574 /*-----------------------------------------------------------------*/
3575 static void genSkipc(resolvedIfx *rifx)
3576 {
3577         if(!rifx)
3578                 return;
3579         
3580         if(rifx->condition)
3581                 emitSKPC;
3582         else
3583                 emitSKPNC;
3584         
3585         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3586         rifx->generated = 1;
3587 }
3588
3589 /*-----------------------------------------------------------------*/
3590 /* genSkipz2                                                                                                       */
3591 /*-----------------------------------------------------------------*/
3592 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3593 {
3594         if(!rifx)
3595                 return;
3596         
3597         if( (rifx->condition ^ invert_condition) & 1)
3598                 emitSKPZ;
3599         else
3600                 emitSKPNZ;
3601         
3602         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3603         rifx->generated = 1;
3604 }
3605
3606 /*-----------------------------------------------------------------*/
3607 /* genSkipz                                                        */
3608 /*-----------------------------------------------------------------*/
3609 static void genSkipz(iCode *ifx, int condition)
3610 {
3611         if(!ifx)
3612                 return;
3613         
3614         if(condition)
3615                 emitSKPNZ;
3616         else
3617                 emitSKPZ;
3618         
3619         if ( IC_TRUE(ifx) )
3620                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3621         else
3622                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3623         
3624         if ( IC_TRUE(ifx) )
3625                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3626         else
3627                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3628         
3629 }
3630 /*-----------------------------------------------------------------*/
3631 /* genSkipCond                                                     */
3632 /*-----------------------------------------------------------------*/
3633 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3634 {
3635         if(!rifx)
3636                 return;
3637         
3638         if(rifx->condition)
3639                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3640         else
3641                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3642         
3643         
3644         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3645         rifx->generated = 1;
3646 }
3647
3648 #if 0
3649 /*-----------------------------------------------------------------*/
3650 /* genChkZeroes :- greater or less than comparison                 */
3651 /*     For each byte in a literal that is zero, inclusive or the   */
3652 /*     the corresponding byte in the operand with W                */
3653 /*     returns true if any of the bytes are zero                   */
3654 /*-----------------------------------------------------------------*/
3655 static int genChkZeroes(operand *op, int lit,  int size)
3656 {
3657         
3658         int i;
3659         int flag =1;
3660         
3661         while(size--) {
3662                 i = (lit >> (size*8)) & 0xff;
3663                 
3664                 if(i==0) {
3665                         if(flag) 
3666                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3667                         else
3668                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3669                         flag = 0;
3670                 }
3671         }
3672         
3673         return (flag==0);
3674 }
3675 #endif
3676
3677 /*-----------------------------------------------------------------*/
3678 /* genCmp :- greater or less than comparison                       */
3679 /*-----------------------------------------------------------------*/
3680 static void genCmp (operand *left,operand *right,
3681                                         operand *result, iCode *ifx, int sign)
3682 {
3683         int size; //, offset = 0 ;
3684         unsigned long lit = 0L,i = 0;
3685         resolvedIfx rFalseIfx;
3686         //  resolvedIfx rTrueIfx;
3687         symbol *truelbl;
3688         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3689         /*
3690         if(ifx) {
3691         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3692         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3693         }
3694         */
3695         
3696         resolveIfx(&rFalseIfx,ifx);
3697         truelbl  = newiTempLabel(NULL);
3698         size = max(AOP_SIZE(left),AOP_SIZE(right));
3699         
3700         DEBUGpic14_AopType(__LINE__,left,right,result);
3701         
3702 #define _swapp
3703         
3704         /* if literal is on the right then swap with left */
3705         if ((AOP_TYPE(right) == AOP_LIT)) {
3706                 operand *tmp = right ;
3707                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3708                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3709 #ifdef _swapp
3710                 
3711                 lit = (lit - 1) & mask;
3712                 right = left;
3713                 left = tmp;
3714                 rFalseIfx.condition ^= 1;
3715 #endif
3716                 
3717         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3718                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3719         }
3720         
3721         
3722         //if(IC_TRUE(ifx) == NULL)
3723         /* if left & right are bit variables */
3724         if (AOP_TYPE(left) == AOP_CRY &&
3725                 AOP_TYPE(right) == AOP_CRY ) {
3726                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3727                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3728         } else {
3729         /* subtract right from left if at the
3730         end the carry flag is set then we know that
3731                 left is greater than right */
3732                 
3733                 symbol *lbl  = newiTempLabel(NULL);
3734                 
3735 #ifndef _swapp
3736                 if(AOP_TYPE(right) == AOP_LIT) {
3737                         
3738                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3739                         
3740                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3741                         
3742                         /* special cases */
3743                         
3744                         if(lit == 0) {
3745                                 
3746                                 if(sign != 0) 
3747                                         genSkipCond(&rFalseIfx,left,size-1,7);
3748                                 else 
3749                                         /* no need to compare to 0...*/
3750                                         /* NOTE: this is a de-generate compare that most certainly 
3751                                         *       creates some dead code. */
3752                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3753                                 
3754                                 if(ifx) ifx->generated = 1;
3755                                 return;
3756                                 
3757                         }
3758                         size--;
3759                         
3760                         if(size == 0) {
3761                                 //i = (lit >> (size*8)) & 0xff;
3762                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3763                                 
3764                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3765                                 
3766                                 i = ((0-lit) & 0xff);
3767                                 if(sign) {
3768                                         if( i == 0x81) { 
3769                                         /* lit is 0x7f, all signed chars are less than
3770                                                 * this except for 0x7f itself */
3771                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3772                                                 genSkipz2(&rFalseIfx,0);
3773                                         } else {
3774                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3775                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3776                                                 genSkipc(&rFalseIfx);
3777                                         }
3778                                         
3779                                 } else {
3780                                         if(lit == 1) {
3781                                                 genSkipz2(&rFalseIfx,1);
3782                                         } else {
3783                                                 emitpcode(POC_ADDLW, popGetLit(i));
3784                                                 genSkipc(&rFalseIfx);
3785                                         }
3786                                 }
3787                                 
3788                                 if(ifx) ifx->generated = 1;
3789                                 return;
3790                         }
3791                         
3792                         /* chars are out of the way. now do ints and longs */
3793                         
3794                         
3795                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3796                         
3797                         /* special cases */
3798                         
3799                         if(sign) {
3800                                 
3801                                 if(lit == 0) {
3802                                         genSkipCond(&rFalseIfx,left,size,7);
3803                                         if(ifx) ifx->generated = 1;
3804                                         return;
3805                                 }
3806                                 
3807                                 if(lit <0x100) {
3808                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3809                                         
3810                                         //rFalseIfx.condition ^= 1;
3811                                         //genSkipCond(&rFalseIfx,left,size,7);
3812                                         //rFalseIfx.condition ^= 1;
3813                                         
3814                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3815                                         if(rFalseIfx.condition)
3816                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3817                                         else
3818                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3819                                         
3820                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3821                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3822                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3823                                         
3824                                         while(size > 1)
3825                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3826                                         
3827                                         if(rFalseIfx.condition) {
3828                                                 emitSKPZ;
3829                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3830                                                 
3831                                         } else {
3832                                                 emitSKPNZ;
3833                                         }
3834                                         
3835                                         genSkipc(&rFalseIfx);
3836                                         emitpLabel(truelbl->key);
3837                                         if(ifx) ifx->generated = 1;
3838                                         return;
3839                                         
3840                                 }
3841                                 
3842                                 if(size == 1) {
3843                                         
3844                                         if( (lit & 0xff) == 0) {
3845                                                 /* lower byte is zero */
3846                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3847                                                 i = ((lit >> 8) & 0xff) ^0x80;
3848                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3849                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3850                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3851                                                 genSkipc(&rFalseIfx);
3852                                                 
3853                                                 
3854                                                 if(ifx) ifx->generated = 1;
3855                                                 return;
3856                                                 
3857                                         }
3858                                 } else {
3859                                         /* Special cases for signed longs */
3860                                         if( (lit & 0xffffff) == 0) {
3861                                                 /* lower byte is zero */
3862                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3863                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3864                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3865                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3866                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3867                                                 genSkipc(&rFalseIfx);
3868                                                 
3869                                                 
3870                                                 if(ifx) ifx->generated = 1;
3871                                                 return;
3872                                                 
3873                                         }
3874                                         
3875                                 }
3876                                 
3877                                 
3878                                 if(lit & (0x80 << (size*8))) {
3879                                         /* lit is negative */
3880                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3881                                         
3882                                         //genSkipCond(&rFalseIfx,left,size,7);
3883                                         
3884                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3885                                         
3886                                         if(rFalseIfx.condition)
3887                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3888                                         else
3889                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3890                                         
3891                                         
3892                                 } else {
3893                                         /* lit is positive */
3894                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3895                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3896                                         if(rFalseIfx.condition)
3897                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3898                                         else
3899                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3900                                         
3901                                 }
3902                                 
3903                                 /* There are no more special cases, so perform a general compare */
3904                                 
3905                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3906                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3907                                 
3908                                 while(size--) {
3909                                         
3910                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3911                                         emitSKPNZ;
3912                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3913                                 }
3914                                 //rFalseIfx.condition ^= 1;
3915                                 genSkipc(&rFalseIfx);
3916                                 
3917                                 emitpLabel(truelbl->key);
3918                                 
3919                                 if(ifx) ifx->generated = 1;
3920                                 return;
3921                                 
3922                                 
3923                         }
3924
3925
3926                         /* sign is out of the way. So now do an unsigned compare */
3927                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3928
3929
3930                         /* General case - compare to an unsigned literal on the right.*/
3931
3932                         i = (lit >> (size*8)) & 0xff;
3933                         emitpcode(POC_MOVLW, popGetLit(i));
3934                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3935                         while(size--) {
3936                                 i = (lit >> (size*8)) & 0xff;
3937                                 
3938                                 if(i) {
3939                                         emitpcode(POC_MOVLW, popGetLit(i));
3940                                         emitSKPNZ;
3941                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3942                                 } else {
3943                                 /* this byte of the lit is zero, 
3944                                         *if it's not the last then OR in the variable */
3945                                         if(size)
3946                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
3947                                 }
3948                         }
3949
3950
3951                 emitpLabel(lbl->key);
3952                 //if(emitFinalCheck)
3953                 genSkipc(&rFalseIfx);
3954                 if(sign)
3955                         emitpLabel(truelbl->key);
3956
3957                 if(ifx) ifx->generated = 1;
3958                 return;
3959
3960
3961                 }
3962 #endif  // _swapp
3963
3964                 if(AOP_TYPE(left) == AOP_LIT) {
3965                         //symbol *lbl = newiTempLabel(NULL);
3966                         
3967                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3968                         
3969                         
3970                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3971                         
3972                         /* Special cases */
3973                         if((lit == 0) && (sign == 0)){
3974                                 
3975                                 size--;
3976                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3977                                 while(size) 
3978                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
3979                                 
3980                                 genSkipz2(&rFalseIfx,0);
3981                                 if(ifx) ifx->generated = 1;
3982                                 return;
3983                         }
3984                         
3985                         if(size==1) {
3986                                 /* Special cases */
3987                                 lit &= 0xff;
3988                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3989                                         /* degenerate compare can never be true */
3990                                         if(rFalseIfx.condition == 0)
3991                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3992                                         
3993                                         if(ifx) ifx->generated = 1;
3994                                         return;
3995                                 }
3996                                 
3997                                 if(sign) {
3998                                         /* signed comparisons to a literal byte */
3999                                         
4000                                         int lp1 = (lit+1) & 0xff;
4001                                         
4002                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4003                                         switch (lp1) {
4004                                         case 0:
4005                                                 rFalseIfx.condition ^= 1;
4006                                                 genSkipCond(&rFalseIfx,right,0,7);
4007                                                 break;
4008                                         case 0x7f:
4009                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4010                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
4011                                                 genSkipz2(&rFalseIfx,1);
4012                                                 break;
4013                                         default:
4014                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4015                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4016                                                 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4017                                                 rFalseIfx.condition ^= 1;
4018                                                 genSkipc(&rFalseIfx);
4019                                                 break;
4020                                         }
4021                                         if(ifx) ifx->generated = 1;
4022                                 } else {
4023                                         /* unsigned comparisons to a literal byte */
4024                                         
4025                                         switch(lit & 0xff ) {
4026                                         case 0:
4027                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4028                                                 genSkipz2(&rFalseIfx,0);
4029                                                 if(ifx) ifx->generated = 1;
4030                                                 break;
4031                                         case 0x7f:
4032                                                 genSkipCond(&rFalseIfx,right,0,7);
4033                                                 if(ifx) ifx->generated = 1;
4034                                                 break;
4035                                                 
4036                                         default:
4037                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4038                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4039                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4040                                                 rFalseIfx.condition ^= 1;
4041                                                 if (AOP_TYPE(result) == AOP_CRY) {
4042                                                         genSkipc(&rFalseIfx);
4043                                                         if(ifx) ifx->generated = 1;
4044                                                 } else {
4045                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4046                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4047                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4048                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4049                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4050                                                 }       
4051                                                 break;
4052                                         }
4053                                 }
4054                                 
4055                                 //goto check_carry;
4056                                 return;
4057                                 
4058                         } else {
4059                                 
4060                                 /* Size is greater than 1 */
4061                                 
4062                                 if(sign) {
4063                                         int lp1 = lit+1;
4064                                         
4065                                         size--;
4066                                         
4067                                         if(lp1 == 0) {
4068                                                 /* this means lit = 0xffffffff, or -1 */
4069                                                 
4070                                                 
4071                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4072                                                 rFalseIfx.condition ^= 1;
4073                                                 genSkipCond(&rFalseIfx,right,size,7);
4074                                                 if(ifx) ifx->generated = 1;
4075                                                 return;
4076                                         }
4077                                         
4078                                         if(lit == 0) {
4079                                                 int s = size;
4080                                                 
4081                                                 if(rFalseIfx.condition) {
4082                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4083                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4084                                                 }
4085                                                 
4086                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4087                                                 while(size--)
4088                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4089                                                 
4090                                                 
4091                                                 emitSKPZ;
4092                                                 if(rFalseIfx.condition) {
4093                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4094                                                         emitpLabel(truelbl->key);
4095                                                 }else {
4096                                                         rFalseIfx.condition ^= 1;
4097                                                         genSkipCond(&rFalseIfx,right,s,7);
4098                                                 }
4099                                                 
4100                                                 if(ifx) ifx->generated = 1;
4101                                                 return;
4102                                         }
4103                                         
4104                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4105                                                 /* lower byte of signed word is zero */
4106                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4107                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4108                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4109                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4110                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4111                                                 rFalseIfx.condition ^= 1;
4112                                                 genSkipc(&rFalseIfx);
4113                                                 
4114                                                 
4115                                                 if(ifx) ifx->generated = 1;
4116                                                 return;
4117                                         }
4118                                         
4119                                         if(lit & (0x80 << (size*8))) {
4120                                                 /* Lit is less than zero */
4121                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4122                                                 //rFalseIfx.condition ^= 1;
4123                                                 //genSkipCond(&rFalseIfx,left,size,7);
4124                                                 //rFalseIfx.condition ^= 1;
4125                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4126                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4127                                                 
4128                                                 if(rFalseIfx.condition)
4129                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4130                                                 else
4131                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4132                                                 
4133                                                 
4134                                         } else {
4135                                                 /* Lit is greater than or equal to zero */
4136                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4137                                                 //rFalseIfx.condition ^= 1;
4138                                                 //genSkipCond(&rFalseIfx,right,size,7);
4139                                                 //rFalseIfx.condition ^= 1;
4140                                                 
4141                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4142                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4143                                                 
4144                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4145                                                 if(rFalseIfx.condition)
4146                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4147                                                 else
4148                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4149                                                 
4150                                         }
4151                                         
4152                                         
4153                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4154                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4155                                         
4156                                         while(size--) {
4157                                                 
4158                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4159                                                 emitSKPNZ;
4160                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4161                                         }
4162                                         rFalseIfx.condition ^= 1;
4163                                         //rFalseIfx.condition = 1;
4164                                         genSkipc(&rFalseIfx);
4165                                         
4166                                         emitpLabel(truelbl->key);
4167                                         
4168                                         if(ifx) ifx->generated = 1;
4169                                         return;
4170                                         // end of if (sign)
4171                                 } else {
4172                                         
4173                                         /* compare word or long to an unsigned literal on the right.*/
4174                                         
4175                                         
4176                                         size--;
4177                                         if(lit < 0xff) {
4178                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4179                                                 switch (lit) {
4180                                                 case 0:
4181                                                         break; /* handled above */
4182                                                 /*
4183                                                 case 0xff:
4184                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4185                                                         while(size--)
4186                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4187                                                         genSkipz2(&rFalseIfx,0);
4188                                                         break;
4189                                                 */
4190                                                 default:
4191                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4192                                                         while(--size)
4193                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4194                                                         
4195                                                         emitSKPZ;
4196                                                         if(rFalseIfx.condition)
4197                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4198                                                         else
4199                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4200                                                         
4201                                                         
4202                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4203                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4204                                                         
4205                                                         rFalseIfx.condition ^= 1;
4206                                                         genSkipc(&rFalseIfx);
4207                                                 }
4208                                                 
4209                                                 emitpLabel(truelbl->key);
4210                                                 
4211                                                 if(ifx) ifx->generated = 1;
4212                                                 return;
4213                                         }
4214                                         
4215                                         
4216                                         lit++;
4217                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4218                                         i = (lit >> (size*8)) & 0xff;
4219                                         
4220                                         emitpcode(POC_MOVLW, popGetLit(i));
4221                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4222                                         
4223                                         while(size--) {
4224                                                 i = (lit >> (size*8)) & 0xff;
4225                                                 
4226                                                 if(i) {
4227                                                         emitpcode(POC_MOVLW, popGetLit(i));
4228                                                         emitSKPNZ;
4229                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230                                                 } else {
4231                                                 /* this byte of the lit is zero, 
4232                                                         *if it's not the last then OR in the variable */
4233                                                         if(size)
4234                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4235                                                 }
4236                                         }
4237                                         
4238                                         
4239                                         emitpLabel(lbl->key);
4240                                         
4241                                         rFalseIfx.condition ^= 1;
4242                                         genSkipc(&rFalseIfx);
4243                                 }
4244                                 
4245                                 if(sign)
4246                                         emitpLabel(truelbl->key);
4247                                 if(ifx) ifx->generated = 1;
4248                                 return;
4249                         }
4250                 }
4251                 /* Compare two variables */
4252                 
4253                 DEBUGpic14_emitcode(";sign","%d",sign);
4254                 
4255                 size--;
4256                 if(sign) {
4257                         /* Sigh. thus sucks... */
4258                         if(size) {
4259                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4260                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4261                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4262                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4263                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4264                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4265                         } else {
4266                                 /* Signed char comparison */
4267                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4268                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4269                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4270                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4271                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4272                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4273                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4274                                 
4275                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4276                                 genSkipc(&rFalseIfx);
4277                                 
4278                                 if(ifx) ifx->generated = 1;
4279                                 return;
4280                         }
4281                         
4282                 } else {
4283                         
4284                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4285                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4286                 }
4287                 
4288                 
4289                 /* The rest of the bytes of a multi-byte compare */
4290                 while (size) {
4291                         
4292                         emitSKPZ;
4293                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4294                         size--;
4295                         
4296                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4297                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4298                         
4299                         
4300                 }
4301                 
4302                 emitpLabel(lbl->key);
4303                 
4304                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4305                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4306                         (AOP_TYPE(result) == AOP_REG)) {
4307                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4308                         emitpcode(POC_RLF, popGet(AOP(result),0));
4309                 } else {
4310                         genSkipc(&rFalseIfx);
4311                 }       
4312                 //genSkipc(&rFalseIfx);
4313                 if(ifx) ifx->generated = 1;
4314                 
4315                 return;
4316                 
4317         }
4318         
4319         // check_carry:
4320         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4321                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4322                 pic14_outBitC(result);
4323         } else {
4324                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4325                 /* if the result is used in the next
4326                 ifx conditional branch then generate
4327                 code a little differently */
4328                 if (ifx )
4329                         genIfxJump (ifx,"c");
4330                 else
4331                         pic14_outBitC(result);
4332                 /* leave the result in acc */
4333         }
4334         
4335 }
4336
4337 /*-----------------------------------------------------------------*/
4338 /* genCmpGt :- greater than comparison                             */
4339 /*-----------------------------------------------------------------*/
4340 static void genCmpGt (iCode *ic, iCode *ifx)
4341 {
4342         operand *left, *right, *result;
4343         sym_link *letype , *retype;
4344         int sign ;
4345         
4346         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4347         left = IC_LEFT(ic);
4348         right= IC_RIGHT(ic);
4349         result = IC_RESULT(ic);
4350         
4351         letype = getSpec(operandType(left));
4352         retype =getSpec(operandType(right));
4353         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4354         /* assign the amsops */
4355         aopOp (left,ic,FALSE);
4356         aopOp (right,ic,FALSE);
4357         aopOp (result,ic,TRUE);
4358         
4359         genCmp(right, left, result, ifx, sign);
4360         
4361         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4362         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4363         freeAsmop(result,NULL,ic,TRUE); 
4364 }
4365
4366 /*-----------------------------------------------------------------*/
4367 /* genCmpLt - less than comparisons                                */
4368 /*-----------------------------------------------------------------*/
4369 static void genCmpLt (iCode *ic, iCode *ifx)
4370 {
4371         operand *left, *right, *result;
4372         sym_link *letype , *retype;
4373         int sign ;
4374         
4375         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4376         left = IC_LEFT(ic);
4377         right= IC_RIGHT(ic);
4378         result = IC_RESULT(ic);
4379         
4380         letype = getSpec(operandType(left));
4381         retype =getSpec(operandType(right));
4382         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4383         
4384         /* assign the amsops */
4385         aopOp (left,ic,FALSE);
4386         aopOp (right,ic,FALSE);
4387         aopOp (result,ic,TRUE);
4388         
4389         genCmp(left, right, result, ifx, sign);
4390         
4391         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4392         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4393         freeAsmop(result,NULL,ic,TRUE); 
4394 }
4395
4396 /*-----------------------------------------------------------------*/
4397 /* genc16bit2lit - compare a 16 bit value to a literal             */
4398 /*-----------------------------------------------------------------*/
4399 static void genc16bit2lit(operand *op, int lit, int offset)
4400 {
4401         int i;
4402         
4403         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4404         if( (lit&0xff) == 0) 
4405                 i=1;
4406         else
4407                 i=0;
4408         
4409         switch( BYTEofLONG(lit,i)) { 
4410         case 0:
4411                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4412                 break;
4413         case 1:
4414                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4415                 break;
4416         case 0xff:
4417                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4418                 break;
4419         default:
4420                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4421                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4422         }
4423         
4424         i ^= 1;
4425         
4426         switch( BYTEofLONG(lit,i)) { 
4427         case 0:
4428                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4429                 break;
4430         case 1:
4431                 emitSKPNZ;
4432                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4433                 break;
4434         case 0xff:
4435                 emitSKPNZ;
4436                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4437                 break;
4438         default:
4439                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4440                 emitSKPNZ;
4441                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4442                 
4443         }
4444         
4445 }
4446
4447 /*-----------------------------------------------------------------*/
4448 /* gencjneshort - compare and jump if not equal                    */
4449 /*-----------------------------------------------------------------*/
4450 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4451 {
4452         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4453         int offset = 0;
4454         int res_offset = 0;  /* the result may be a different size then left or right */
4455         int res_size = AOP_SIZE(result);
4456         resolvedIfx rIfx;
4457         symbol *lbl;
4458         
4459         unsigned long lit = 0L;
4460         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4461         DEBUGpic14_AopType(__LINE__,left,right,result);
4462         if(result)
4463                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4464         resolveIfx(&rIfx,ifx);
4465         lbl =  newiTempLabel(NULL);
4466         
4467         
4468         /* if the left side is a literal or 
4469         if the right is in a pointer register and left 
4470         is not */
4471         if ((AOP_TYPE(left) == AOP_LIT) || 
4472                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4473                 operand *t = right;
4474                 right = left;
4475                 left = t;
4476         }
4477         if(AOP_TYPE(right) == AOP_LIT)
4478                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4479         
4480         /* if the right side is a literal then anything goes */
4481         if (AOP_TYPE(right) == AOP_LIT &&
4482                 AOP_TYPE(left) != AOP_DIR ) {
4483                 switch(size) {
4484                 case 2:
4485                         genc16bit2lit(left, lit, 0);
4486                         emitSKPNZ;
4487                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4488                         break;
4489                 default:
4490                         while (size--) {
4491                                 if(lit & 0xff) {
4492                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4493                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4494                                 } else {
4495                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4496                                 }
4497                                 
4498                                 emitSKPNZ;
4499                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4500                                 offset++;
4501                                 if(res_offset < res_size-1)
4502                                         res_offset++;
4503                                 lit >>= 8;
4504                         }
4505                         break;
4506                 }
4507         }
4508         
4509         /* if the right side is in a register or in direct space or
4510         if the left is a pointer register & right is not */    
4511         else if (AOP_TYPE(right) == AOP_REG ||
4512                 AOP_TYPE(right) == AOP_DIR || 
4513                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4514                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4515                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4516                 int lbl_key = lbl->key;
4517                 
4518                 if(result) {
4519                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4520                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4521                 }else {
4522                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4523                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4524                                 __FUNCTION__,__LINE__);
4525                         return;
4526                 }
4527                 
4528                 /*     switch(size) { */
4529                 /*     case 2: */
4530                 /*       genc16bit2lit(left, lit, 0); */
4531                 /*       emitSKPNZ; */
4532                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4533                 /*       break; */
4534                 /*     default: */
4535                 while (size--) {
4536                         int emit_skip=1;
4537                         if((AOP_TYPE(left) == AOP_DIR) && 
4538                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4539                                 
4540                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4541                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4542                                 
4543                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4544                                 
4545                                 switch (lit & 0xff) {
4546                                 case 0:
4547                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4548                                         break;
4549                                 case 1:
4550                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4551                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4552                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4553                                         emit_skip=0;
4554                                         break;
4555                                 case 0xff:
4556                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4557                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4558                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4559                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4560                                         emit_skip=0;
4561                                         break;
4562                                 default:
4563                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4564                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4565                                 }
4566                                 lit >>= 8;
4567                                 
4568                         } else {
4569                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4570                         }
4571                         if(emit_skip) {
4572                                 if(AOP_TYPE(result) == AOP_CRY) {
4573                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4574                                         if(rIfx.condition)
4575                                                 emitSKPNZ;
4576                                         else
4577                                                 emitSKPZ;
4578                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4579                                 } else {
4580                                         /* fix me. probably need to check result size too */
4581                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4582                                         if(rIfx.condition)
4583                                                 emitSKPZ;
4584                                         else
4585                                                 emitSKPNZ;
4586                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4587                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4588                                 }
4589                                 if(ifx)
4590                                         ifx->generated=1;
4591                         }
4592                         emit_skip++;
4593                         offset++;
4594                         if(res_offset < res_size-1)
4595                                 res_offset++;
4596                 }
4597                 /*       break; */
4598                 /*     } */
4599         } else if(AOP_TYPE(right) == AOP_REG &&
4600                 AOP_TYPE(left) != AOP_DIR){
4601                 
4602                 while(size--) {
4603                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4604                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4605                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4606                         if(rIfx.condition)
4607                                 emitSKPNZ;
4608                         else
4609                                 emitSKPZ;
4610                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4611                         offset++;
4612                         if(res_offset < res_size-1)
4613                                 res_offset++;
4614                 }
4615                 
4616         }else{
4617                 /* right is a pointer reg need both a & b */
4618                 while(size--) {
4619                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4620                         if(strcmp(l,"b"))
4621                                 pic14_emitcode("mov","b,%s",l);
4622                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4623                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4624                         offset++;
4625                 }
4626         }
4627         
4628         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4629         if(!rIfx.condition)
4630                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4631         
4632         emitpLabel(lbl->key);
4633         
4634         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4635         
4636         if(ifx)
4637                 ifx->generated = 1;
4638 }
4639
4640 #if 0
4641 /*-----------------------------------------------------------------*/
4642 /* gencjne - compare and jump if not equal                         */
4643 /*-----------------------------------------------------------------*/
4644 static void gencjne(operand *left, operand *right, iCode *ifx)
4645 {
4646         symbol *tlbl  = newiTempLabel(NULL);
4647         
4648         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4649         gencjneshort(left, right, lbl);
4650         
4651         pic14_emitcode("mov","a,%s",one);
4652         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4653         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4654         pic14_emitcode("clr","a");
4655         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4656         
4657         emitpLabel(lbl->key);
4658         emitpLabel(tlbl->key);
4659         
4660 }
4661 #endif
4662
4663 /*-----------------------------------------------------------------*/
4664 /* genCmpEq - generates code for equal to                          */
4665 /*-----------------------------------------------------------------*/
4666 static void genCmpEq (iCode *ic, iCode *ifx)
4667 {
4668         operand *left, *right, *result;
4669         unsigned long lit = 0L;
4670         int size,offset=0;
4671         
4672         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4673         
4674         if(ifx)
4675                 DEBUGpic14_emitcode ("; ifx is non-null","");
4676         else
4677                 DEBUGpic14_emitcode ("; ifx is null","");
4678         
4679         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4680         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4681         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4682         
4683         size = max(AOP_SIZE(left),AOP_SIZE(right));
4684         
4685         DEBUGpic14_AopType(__LINE__,left,right,result);
4686         
4687         /* if literal, literal on the right or 
4688         if the right is in a pointer register and left 
4689         is not */
4690         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4691                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4692                 operand *tmp = right ;
4693                 right = left;
4694                 left = tmp;
4695         }
4696         
4697         
4698         if(ifx && !AOP_SIZE(result)){
4699                 symbol *tlbl;
4700                 /* if they are both bit variables */
4701                 if (AOP_TYPE(left) == AOP_CRY &&
4702                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4703                         if(AOP_TYPE(right) == AOP_LIT){
4704                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4705                                 if(lit == 0L){
4706                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4707                                         pic14_emitcode("cpl","c");
4708                                 } else if(lit == 1L) {
4709                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4710                                 } else {
4711                                         pic14_emitcode("clr","c");
4712                                 }
4713                                 /* AOP_TYPE(right) == AOP_CRY */
4714                         } else {
4715                                 symbol *lbl = newiTempLabel(NULL);
4716                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4717                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4718                                 pic14_emitcode("cpl","c");
4719                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4720                         }
4721                         /* if true label then we jump if condition
4722                         supplied is true */
4723                         tlbl = newiTempLabel(NULL);
4724                         if ( IC_TRUE(ifx) ) {
4725                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4726                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4727                         } else {
4728                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4729                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4730                         }
4731                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4732                         
4733                         {
4734                                 /* left and right are both bit variables, result is carry */
4735                                 resolvedIfx rIfx;
4736                                 
4737                                 resolveIfx(&rIfx,ifx);
4738                                 
4739                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4740                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4741                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4742                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4743                                 genSkipz2(&rIfx,0);
4744                         }
4745                 } else {
4746                         
4747                         /* They're not both bit variables. Is the right a literal? */
4748                         if(AOP_TYPE(right) == AOP_LIT) {
4749                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4750                                 
4751                                 switch(size) {
4752                                         
4753                                 case 1:
4754                                         switch(lit & 0xff) {
4755                                         case 1:
4756                                                 if ( IC_TRUE(ifx) ) {
4757                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4758                                                         emitSKPNZ;
4759                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4760                                                 } else {
4761                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4762                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4763                                                 }
4764                                                 break;
4765                                         case 0xff:
4766                                                 if ( IC_TRUE(ifx) ) {
4767                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4768                                                         emitSKPNZ;
4769                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4770                                                 } else {
4771                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4772                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4773                                                 }
4774                                                 break;
4775                                         default:
4776                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4777                                                 if(lit)
4778                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4779                                                 genSkip(ifx,'z');
4780                                         }
4781                                         
4782                                         
4783                                         /* end of size == 1 */
4784                                         break;
4785                                         
4786                                         case 2:
4787                                                 genc16bit2lit(left,lit,offset);
4788                                                 genSkip(ifx,'z');
4789                                                 break;
4790                                                 /* end of size == 2 */
4791                                                 
4792                                         default:
4793                                                 /* size is 4 */
4794                                                 if(lit==0) {
4795                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4796                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4797                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4798                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4799                                                         
4800                                                 } else {
4801                                                         
4802                                                         /* search for patterns that can be optimized */
4803                                                         
4804                                                         genc16bit2lit(left,lit,0);
4805                                                         lit >>= 16;
4806                                                         if(lit) {
4807                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4808                                                                 //genSkip(ifx,'z');
4809                                                                 genc16bit2lit(left,lit,2);
4810                                                         } else {
4811                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4812                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4813                                                                 
4814                                                         }
4815                                                         
4816                                                 }
4817                                                 
4818                                                 genSkip(ifx,'z');
4819                                 }
4820                                 
4821                                 ifx->generated = 1;
4822                                 goto release ;
4823                                 
4824                                 
4825                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4826                                 /* we know the left is not a bit, but that the right is */
4827                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4828                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4829                                         popGet(AOP(right),offset));
4830                                 emitpcode(POC_XORLW,popGetLit(1));
4831                                 
4832                                 /* if the two are equal, then W will be 0 and the Z bit is set
4833                                 * we could test Z now, or go ahead and check the high order bytes if
4834                                 * the variable we're comparing is larger than a byte. */
4835                                 
4836                                 while(--size)
4837                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4838                                 
4839                                 if ( IC_TRUE(ifx) ) {
4840                                         emitSKPNZ;
4841                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4842                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4843                                 } else {
4844                                         emitSKPZ;
4845                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4846                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4847                                 }
4848                                 
4849                         } else {
4850                                 /* They're both variables that are larger than bits */
4851                                 int s = size;
4852                                 
4853                                 tlbl = newiTempLabel(NULL);
4854                                 
4855                                 while(size--) {
4856                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4857                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4858                                         
4859                                         if ( IC_TRUE(ifx) ) {
4860                                                 if(size) {
4861                                                         emitSKPZ;
4862                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4863                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4864                                                 } else {
4865                                                         emitSKPNZ;
4866                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4867                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4868                                                 }
4869                                         } else {
4870                                                 emitSKPZ;
4871                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4872                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4873                                         }
4874                                         offset++;
4875                                 }
4876                                 if(s>1 && IC_TRUE(ifx)) {
4877                                         emitpLabel(tlbl->key);
4878                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4879                                 }
4880                         }
4881                 }
4882                 /* mark the icode as generated */
4883                 ifx->generated = 1;
4884                 goto release ;
4885         }
4886   
4887   /* if they are both bit variables */
4888   if (AOP_TYPE(left) == AOP_CRY &&
4889           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4890           if(AOP_TYPE(right) == AOP_LIT){
4891                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4892                   if(lit == 0L){
4893                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4894                           pic14_emitcode("cpl","c");
4895                   } else if(lit == 1L) {
4896                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4897                   } else {
4898                           pic14_emitcode("clr","c");
4899                   }
4900                   /* AOP_TYPE(right) == AOP_CRY */
4901           } else {
4902                   symbol *lbl = newiTempLabel(NULL);
4903                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4904                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4905                   pic14_emitcode("cpl","c");
4906                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4907           }
4908           /* c = 1 if egal */
4909           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4910                   pic14_outBitC(result);
4911                   goto release ;
4912           }
4913           if (ifx) {
4914                   genIfxJump (ifx,"c");
4915                   goto release ;
4916           }
4917           /* if the result is used in an arithmetic operation
4918           then put the result in place */
4919           pic14_outBitC(result);
4920   } else {
4921           
4922           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4923           gencjne(left,right,result,ifx);
4924           /*
4925           if(ifx) 
4926           gencjne(left,right,newiTempLabel(NULL));
4927           else {
4928           if(IC_TRUE(ifx)->key)
4929           gencjne(left,right,IC_TRUE(ifx)->key);
4930           else
4931           gencjne(left,right,IC_FALSE(ifx)->key);
4932           ifx->generated = 1;
4933           goto release ;
4934           }
4935           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4936           aopPut(AOP(result),"a",0);
4937           goto release ;
4938           }
4939           
4940                 if (ifx) {
4941                 genIfxJump (ifx,"a");
4942                 goto release ;
4943                 }
4944           */
4945           /* if the result is used in an arithmetic operation
4946           then put the result in place */
4947           /*
4948           if (AOP_TYPE(result) != AOP_CRY) 
4949           pic14_outAcc(result);
4950           */
4951           /* leave the result in acc */
4952   }
4953   
4954 release:
4955   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4956   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4957   freeAsmop(result,NULL,ic,TRUE);
4958 }
4959
4960 /*-----------------------------------------------------------------*/
4961 /* ifxForOp - returns the icode containing the ifx for operand     */
4962 /*-----------------------------------------------------------------*/
4963 static iCode *ifxForOp ( operand *op, iCode *ic )
4964 {
4965         /* if true symbol then needs to be assigned */
4966         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4967         if (IS_TRUE_SYMOP(op))
4968                 return NULL ;
4969         
4970                 /* if this has register type condition and
4971                 the next instruction is ifx with the same operand
4972         and live to of the operand is upto the ifx only then */
4973         if (ic->next &&
4974                 ic->next->op == IFX &&
4975                 IC_COND(ic->next)->key == op->key &&
4976                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4977                 return ic->next;
4978         
4979         if (ic->next &&
4980                 ic->next->op == IFX &&
4981                 IC_COND(ic->next)->key == op->key) {
4982                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4983                 return ic->next;
4984         }
4985         
4986         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4987         if (ic->next &&
4988                 ic->next->op == IFX)
4989                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4990         
4991         if (ic->next &&
4992                 ic->next->op == IFX &&
4993                 IC_COND(ic->next)->key == op->key) {
4994                 DEBUGpic14_emitcode ("; "," key is okay");
4995                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4996                         OP_SYMBOL(op)->liveTo,
4997                         ic->next->seq);
4998         }
4999         
5000         
5001         return NULL;
5002 }
5003 /*-----------------------------------------------------------------*/
5004 /* genAndOp - for && operation                                     */
5005 /*-----------------------------------------------------------------*/
5006 static void genAndOp (iCode *ic)
5007 {
5008         operand *left,*right, *result;
5009         /*     symbol *tlbl; */
5010         
5011         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5012         /* note here that && operations that are in an
5013         if statement are taken away by backPatchLabels
5014         only those used in arthmetic operations remain */
5015         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5016         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5017         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5018         
5019         DEBUGpic14_AopType(__LINE__,left,right,result);
5020         
5021         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5022         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5023         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5024         
5025         /* if both are bit variables */
5026         /*     if (AOP_TYPE(left) == AOP_CRY && */
5027         /*         AOP_TYPE(right) == AOP_CRY ) { */
5028         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5029         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5030         /*         pic14_outBitC(result); */
5031         /*     } else { */
5032         /*         tlbl = newiTempLabel(NULL); */
5033         /*         pic14_toBoolean(left);     */
5034         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5035         /*         pic14_toBoolean(right); */
5036         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5037         /*         pic14_outBitAcc(result); */
5038         /*     } */
5039         
5040         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5041         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5042         freeAsmop(result,NULL,ic,TRUE);
5043 }
5044
5045
5046 /*-----------------------------------------------------------------*/
5047 /* genOrOp - for || operation                                      */
5048 /*-----------------------------------------------------------------*/
5049 /*
5050 tsd pic port -
5051 modified this code, but it doesn't appear to ever get called
5052 */
5053
5054 static void genOrOp (iCode *ic)
5055 {
5056         operand *left,*right, *result;
5057         symbol *tlbl;
5058         
5059         /* note here that || operations that are in an
5060         if statement are taken away by backPatchLabels
5061         only those used in arthmetic operations remain */
5062         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5063         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5064         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5065         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5066         
5067         DEBUGpic14_AopType(__LINE__,left,right,result);
5068         
5069         /* if both are bit variables */
5070         if (AOP_TYPE(left) == AOP_CRY &&
5071                 AOP_TYPE(right) == AOP_CRY ) {
5072                 pic14_emitcode("clrc","");
5073                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5074                         AOP(left)->aopu.aop_dir,
5075                         AOP(left)->aopu.aop_dir);
5076                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5077                         AOP(right)->aopu.aop_dir,
5078                         AOP(right)->aopu.aop_dir);
5079                 pic14_emitcode("setc","");
5080                 
5081         } else {
5082                 tlbl = newiTempLabel(NULL);
5083                 pic14_toBoolean(left);
5084                 emitSKPZ;
5085                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5086                 pic14_toBoolean(right);
5087                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5088                 
5089                 pic14_outBitAcc(result);
5090         }
5091         
5092         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5093         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5094         freeAsmop(result,NULL,ic,TRUE);            
5095 }
5096
5097 /*-----------------------------------------------------------------*/
5098 /* isLiteralBit - test if lit == 2^n                               */
5099 /*-----------------------------------------------------------------*/
5100 static int isLiteralBit(unsigned long lit)
5101 {
5102         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5103                 0x100L,0x200L,0x400L,0x800L,
5104                 0x1000L,0x2000L,0x4000L,0x8000L,
5105                 0x10000L,0x20000L,0x40000L,0x80000L,
5106                 0x100000L,0x200000L,0x400000L,0x800000L,
5107                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5108                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5109         int idx;
5110         
5111         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5112         for(idx = 0; idx < 32; idx++)
5113                 if(lit == pw[idx])
5114                         return idx+1;
5115                 return 0;
5116 }
5117
5118 /*-----------------------------------------------------------------*/
5119 /* continueIfTrue -                                                */
5120 /*-----------------------------------------------------------------*/
5121 static void continueIfTrue (iCode *ic)
5122 {
5123         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5124         if(IC_TRUE(ic))
5125                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5126         ic->generated = 1;
5127 }
5128
5129 /*-----------------------------------------------------------------*/
5130 /* jmpIfTrue -                                                     */
5131 /*-----------------------------------------------------------------*/
5132 static void jumpIfTrue (iCode *ic)
5133 {
5134         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5135         if(!IC_TRUE(ic))
5136                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5137         ic->generated = 1;
5138 }
5139
5140 /*-----------------------------------------------------------------*/
5141 /* jmpTrueOrFalse -                                                */
5142 /*-----------------------------------------------------------------*/
5143 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5144 {
5145         // ugly but optimized by peephole
5146         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5147         if(IC_TRUE(ic)){
5148                 symbol *nlbl = newiTempLabel(NULL);
5149                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5150                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5151                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5152                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5153         }
5154         else{
5155                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5156                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5157         }
5158         ic->generated = 1;
5159 }
5160
5161 /*-----------------------------------------------------------------*/
5162 /* genAnd  - code for and                                          */
5163 /*-----------------------------------------------------------------*/
5164 static void genAnd (iCode *ic, iCode *ifx)
5165 {
5166         operand *left, *right, *result;
5167         int size, offset=0;  
5168         unsigned long lit = 0L;
5169         int bytelit = 0;
5170         resolvedIfx rIfx;
5171         
5172         
5173         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5174         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5175         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5176         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5177         
5178         resolveIfx(&rIfx,ifx);
5179         
5180         /* if left is a literal & right is not then exchange them */
5181         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5182                 AOP_NEEDSACC(left)) {
5183                 operand *tmp = right ;
5184                 right = left;
5185                 left = tmp;
5186         }
5187         
5188         /* if result = right then exchange them */
5189         if(pic14_sameRegs(AOP(result),AOP(right))){
5190                 operand *tmp = right ;
5191                 right = left;
5192                 left = tmp;
5193         }
5194         
5195         /* if right is bit then exchange them */
5196         if (AOP_TYPE(right) == AOP_CRY &&
5197                 AOP_TYPE(left) != AOP_CRY){
5198                 operand *tmp = right ;
5199                 right = left;
5200                 left = tmp;
5201         }
5202         if(AOP_TYPE(right) == AOP_LIT)
5203                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5204         
5205         size = AOP_SIZE(result);
5206         
5207         DEBUGpic14_AopType(__LINE__,left,right,result);
5208         
5209         // if(bit & yy)
5210         // result = bit & yy;
5211         if (AOP_TYPE(left) == AOP_CRY){
5212                 // c = bit & literal;
5213                 if(AOP_TYPE(right) == AOP_LIT){
5214                         if(lit & 1) {
5215                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5216                                         // no change
5217                                         goto release;
5218                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5219                         } else {
5220                                 // bit(result) = 0;
5221                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5222                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5223                                         goto release;
5224                                 }
5225                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5226                                         jumpIfTrue(ifx);
5227                                         goto release;
5228                                 }
5229                                 pic14_emitcode("clr","c");
5230                         }
5231                 } else {
5232                         if (AOP_TYPE(right) == AOP_CRY){
5233                                 // c = bit & bit;
5234                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5235                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5236                         } else {
5237                                 // c = bit & val;
5238                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5239                                 // c = lsb
5240                                 pic14_emitcode("rrc","a");
5241                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5242                         }
5243                 }
5244                 // bit = c
5245                 // val = c
5246                 if(size)
5247                         pic14_outBitC(result);
5248                 // if(bit & ...)
5249                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5250                         genIfxJump(ifx, "c");           
5251                 goto release ;
5252         }
5253         
5254         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5255         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5256         if((AOP_TYPE(right) == AOP_LIT) &&
5257                 (AOP_TYPE(result) == AOP_CRY) &&
5258                 (AOP_TYPE(left) != AOP_CRY)){
5259                 int posbit = isLiteralBit(lit);
5260                 /* left &  2^n */
5261                 if(posbit){
5262                         posbit--;
5263                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5264                         // bit = left & 2^n
5265                         if(size)
5266                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5267                         // if(left &  2^n)
5268                         else{
5269                                 if(ifx){
5270                                         int offset = 0;
5271                                         while (posbit > 7) {
5272                                                 posbit -= 8;
5273                                                 offset++;
5274                                         }
5275                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5276                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5277                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5278                                         
5279                                         ifx->generated = 1;
5280                                 }
5281                                 goto release;
5282                         }
5283                 } else {
5284                         symbol *tlbl = newiTempLabel(NULL);
5285                         int sizel = AOP_SIZE(left);
5286                         if(size)
5287                                 pic14_emitcode("setb","c");
5288                         while(sizel--){
5289                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5290                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5291                                         // byte ==  2^n ?
5292                                         if((posbit = isLiteralBit(bytelit)) != 0)
5293                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5294                                         else{
5295                                                 if(bytelit != 0x0FFL)
5296                                                         pic14_emitcode("anl","a,%s",
5297                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5298                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5299                                         }
5300                                 }
5301                                 offset++;
5302                         }
5303                         // bit = left & literal
5304                         if(size){
5305                                 pic14_emitcode("clr","c");
5306                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5307                         }
5308                         // if(left & literal)
5309                         else{
5310                                 if(ifx)
5311                                         jmpTrueOrFalse(ifx, tlbl);
5312                                 goto release ;
5313                         }
5314                 }
5315                 pic14_outBitC(result);
5316                 goto release ;
5317         }
5318         
5319         /* if left is same as result */
5320         if(pic14_sameRegs(AOP(result),AOP(left))){
5321                 int know_W = -1;
5322                 for(;size--; offset++,lit>>=8) {
5323                         if(AOP_TYPE(right) == AOP_LIT){
5324                                 switch(lit & 0xff) {
5325                                 case 0x00:
5326                                         /*  and'ing with 0 has clears the result */
5327                                         pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5328                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5329                                         break;
5330                                 case 0xff:
5331                                         /* and'ing with 0xff is a nop when the result and left are the same */
5332                                         break;
5333                                         
5334                                 default:
5335                                         {
5336                                                 int p = my_powof2( (~lit) & 0xff );
5337                                                 if(p>=0) {
5338                                                         /* only one bit is set in the literal, so use a bcf instruction */
5339                                                         pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5340                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5341                                                         
5342                                                 } else {
5343                                                         pic14_emitcode("movlw","0x%x", (lit & 0xff));
5344                                                         pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5345                                                         if(know_W != (int)(lit&0xff))
5346                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5347                                                         know_W = lit &0xff;
5348                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5349                                                 }
5350                                         }    
5351                                 }
5352                         } else {
5353                                 if (AOP_TYPE(left) == AOP_ACC) {
5354                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5355                                 } else {        
5356                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5357                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5358                                         
5359                                 }
5360                         }
5361                 }
5362                 
5363         } else {
5364                 // left & result in different registers
5365                 if(AOP_TYPE(result) == AOP_CRY){
5366                         // result = bit
5367                         // if(size), result in bit
5368                         // if(!size && ifx), conditional oper: if(left & right)
5369                         symbol *tlbl = newiTempLabel(NULL);
5370                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5371                         if(size)
5372                                 pic14_emitcode("setb","c");
5373                         while(sizer--){
5374                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5375                                 pic14_emitcode("anl","a,%s",
5376                                         aopGet(AOP(left),offset,FALSE,FALSE));
5377                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5378                                 offset++;
5379                         }
5380                         if(size){
5381                                 CLRC;
5382                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5383                                 pic14_outBitC(result);
5384                         } else if(ifx)
5385                                 jmpTrueOrFalse(ifx, tlbl);
5386                 } else {
5387                         for(;(size--);offset++) {
5388                                 // normal case
5389                                 // result = left & right
5390                                 if(AOP_TYPE(right) == AOP_LIT){
5391                                         int t = (lit >> (offset*8)) & 0x0FFL;
5392                                         switch(t) { 
5393                                         case 0x00:
5394                                                 pic14_emitcode("clrf","%s",
5395                                                         aopGet(AOP(result),offset,FALSE,FALSE));
5396                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5397                                                 break;
5398                                         case 0xff:
5399                                                 if(AOP_TYPE(left) != AOP_ACC) {
5400                                                         pic14_emitcode("movf","%s,w",
5401                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5402                                                         pic14_emitcode("movwf","%s",
5403                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5404                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5405                                                 }
5406                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5407                                                 break;
5408                                         default:
5409                                                 if(AOP_TYPE(left) == AOP_ACC) {
5410                                                         emitpcode(POC_ANDLW, popGetLit(t));
5411                                                 } else {
5412                                                         pic14_emitcode("movlw","0x%x",t);
5413                                                         pic14_emitcode("andwf","%s,w",
5414                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5415                                                         pic14_emitcode("movwf","%s",
5416                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5417                                                         
5418                                                         emitpcode(POC_MOVLW, popGetLit(t));
5419                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5420                                                 }
5421                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5422                                         }
5423                                         continue;
5424                                 }
5425                                 
5426                                 if (AOP_TYPE(left) == AOP_ACC) {
5427                                         pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5428                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5429                                 } else {
5430                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5431                                         pic14_emitcode("andwf","%s,w",
5432                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5433                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5434                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5435                                 }
5436                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5437                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5438                         }
5439                 }
5440         }
5441         
5442 release :
5443         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5444         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5445         freeAsmop(result,NULL,ic,TRUE);     
5446 }
5447
5448 /*-----------------------------------------------------------------*/
5449 /* genOr  - code for or                                            */
5450 /*-----------------------------------------------------------------*/
5451 static void genOr (iCode *ic, iCode *ifx)
5452 {
5453         operand *left, *right, *result;
5454         int size, offset=0;
5455         unsigned long lit = 0L;
5456         
5457         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5458         
5459         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5460         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5461         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5462         
5463         DEBUGpic14_AopType(__LINE__,left,right,result);
5464         
5465         /* if left is a literal & right is not then exchange them */
5466         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5467                 AOP_NEEDSACC(left)) {
5468                 operand *tmp = right ;
5469                 right = left;
5470                 left = tmp;
5471         }
5472         
5473         /* if result = right then exchange them */
5474         if(pic14_sameRegs(AOP(result),AOP(right))){
5475                 operand *tmp = right ;
5476                 right = left;
5477                 left = tmp;
5478         }
5479         
5480         /* if right is bit then exchange them */
5481         if (AOP_TYPE(right) == AOP_CRY &&
5482                 AOP_TYPE(left) != AOP_CRY){
5483                 operand *tmp = right ;
5484                 right = left;
5485                 left = tmp;
5486         }
5487         
5488         DEBUGpic14_AopType(__LINE__,left,right,result);
5489         
5490         if(AOP_TYPE(right) == AOP_LIT)
5491                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5492         
5493         size = AOP_SIZE(result);
5494         
5495         // if(bit | yy)
5496         // xx = bit | yy;
5497         if (AOP_TYPE(left) == AOP_CRY){
5498                 if(AOP_TYPE(right) == AOP_LIT){
5499                         // c = bit & literal;
5500                         if(lit){
5501                                 // lit != 0 => result = 1
5502                                 if(AOP_TYPE(result) == AOP_CRY){
5503                                         if(size)
5504                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5505                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5506                                         //   AOP(result)->aopu.aop_dir,
5507                                         //   AOP(result)->aopu.aop_dir);
5508                                         else if(ifx)
5509                                                 continueIfTrue(ifx);
5510                                         goto release;
5511                                 }
5512                         } else {
5513                                 // lit == 0 => result = left
5514                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5515                                         goto release;
5516                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5517                         }
5518                 } else {
5519                         if (AOP_TYPE(right) == AOP_CRY){
5520                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5521                                         // c = bit | bit;
5522                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5523                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5524                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5525                                         
5526                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5527                                                 AOP(result)->aopu.aop_dir,
5528                                                 AOP(result)->aopu.aop_dir);
5529                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5530                                                 AOP(right)->aopu.aop_dir,
5531                                                 AOP(right)->aopu.aop_dir);
5532                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5533                                                 AOP(result)->aopu.aop_dir,
5534                                                 AOP(result)->aopu.aop_dir);
5535                                 } else {
5536                                         if( AOP_TYPE(result) == AOP_ACC) {
5537                                                 emitpcode(POC_MOVLW, popGetLit(0));
5538                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5539                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5540                                                 emitpcode(POC_MOVLW, popGetLit(1));
5541                                                 
5542                                         } else {
5543                                                 
5544                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5545                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5546                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5547                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5548                                                 
5549                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5550                                                         AOP(result)->aopu.aop_dir,
5551                                                         AOP(result)->aopu.aop_dir);
5552                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5553                                                         AOP(right)->aopu.aop_dir,
5554                                                         AOP(right)->aopu.aop_dir);
5555                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5556                                                         AOP(left)->aopu.aop_dir,
5557                                                         AOP(left)->aopu.aop_dir);
5558                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5559                                                         AOP(result)->aopu.aop_dir,
5560                                                         AOP(result)->aopu.aop_dir);
5561                                         }
5562                                 }
5563                         } else {
5564                                 // c = bit | val;
5565                                 symbol *tlbl = newiTempLabel(NULL);
5566                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5567                                 
5568                                 
5569                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5570                                 if( AOP_TYPE(right) == AOP_ACC) {
5571                                         emitpcode(POC_IORLW, popGetLit(0));
5572                                         emitSKPNZ;
5573                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5574                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5575                                 }
5576                                 
5577                                 
5578                                 
5579                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5580                                         pic14_emitcode(";XXX setb","c");
5581                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5582                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5583                                 pic14_toBoolean(right);
5584                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5585                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5586                                         jmpTrueOrFalse(ifx, tlbl);
5587                                         goto release;
5588                                 } else {
5589                                         CLRC;
5590                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5591                                 }
5592                         }
5593                 }
5594                 // bit = c
5595                 // val = c
5596                 if(size)
5597                         pic14_outBitC(result);
5598                 // if(bit | ...)
5599                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5600                         genIfxJump(ifx, "c");           
5601                 goto release ;
5602   }
5603   
5604   // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5605   // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5606   if((AOP_TYPE(right) == AOP_LIT) &&
5607           (AOP_TYPE(result) == AOP_CRY) &&
5608           (AOP_TYPE(left) != AOP_CRY)){
5609           if(lit){
5610                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5611                   // result = 1
5612                   if(size)
5613                           pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5614                   else 
5615                           continueIfTrue(ifx);
5616                   goto release;
5617           } else {
5618                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5619                   // lit = 0, result = boolean(left)
5620                   if(size)
5621                           pic14_emitcode(";XXX setb","c");
5622                   pic14_toBoolean(right);
5623                   if(size){
5624                           symbol *tlbl = newiTempLabel(NULL);
5625                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5626                           CLRC;
5627                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5628                   } else {
5629                           genIfxJump (ifx,"a");
5630                           goto release;
5631                   }
5632           }
5633           pic14_outBitC(result);
5634           goto release ;
5635   }
5636   
5637   /* if left is same as result */
5638   if(pic14_sameRegs(AOP(result),AOP(left))){
5639           int know_W = -1;
5640           for(;size--; offset++,lit>>=8) {
5641                   if(AOP_TYPE(right) == AOP_LIT){
5642                           if((lit & 0xff) == 0)
5643                                   /*  or'ing with 0 has no effect */
5644                                   continue;
5645                           else {
5646                                   int p = my_powof2(lit & 0xff);
5647                                   if(p>=0) {
5648                                           /* only one bit is set in the literal, so use a bsf instruction */
5649                                           emitpcode(POC_BSF,
5650                                                   newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5651                                   } else {
5652                                           if(know_W != (int)(lit & 0xff))
5653                                                   emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5654                                           know_W = lit & 0xff;
5655                                           emitpcode(POC_IORWF, popGet(AOP(left),offset));
5656                                   }
5657                                   
5658                           }
5659                   } else {
5660                           if (AOP_TYPE(left) == AOP_ACC) {
5661                                   emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5662                                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5663                           } else {        
5664                                   emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5665                                   emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5666                                   
5667                                   pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5668                                   pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5669                                   
5670                           }
5671                   }
5672           }
5673   } else {
5674           // left & result in different registers
5675           if(AOP_TYPE(result) == AOP_CRY){
5676                   // result = bit
5677                   // if(size), result in bit
5678                   // if(!size && ifx), conditional oper: if(left | right)
5679                   symbol *tlbl = newiTempLabel(NULL);
5680                   int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5681                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5682                   
5683                   
5684                   if(size)
5685                           pic14_emitcode(";XXX setb","c");
5686                   while(sizer--){
5687                           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5688                           pic14_emitcode(";XXX orl","a,%s",
5689                                   aopGet(AOP(left),offset,FALSE,FALSE));
5690                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5691                           offset++;
5692                   }
5693                   if(size){
5694                           CLRC;
5695                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5696                           pic14_outBitC(result);
5697                   } else if(ifx)
5698                           jmpTrueOrFalse(ifx, tlbl);
5699           } else for(;(size--);offset++){
5700                   // normal case
5701                   // result = left & right
5702                   if(AOP_TYPE(right) == AOP_LIT){
5703                           int t = (lit >> (offset*8)) & 0x0FFL;
5704                           switch(t) { 
5705                           case 0x00:
5706                                   if (AOP_TYPE(left) != AOP_ACC) {
5707                                           emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5708                                   }
5709                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5710                                   
5711                                   break;
5712                           default:
5713                                   if (AOP_TYPE(left) == AOP_ACC) {
5714                                           emitpcode(POC_IORLW,  popGetLit(t));
5715                                   } else {
5716                                           emitpcode(POC_MOVLW,  popGetLit(t));
5717                                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5718                                   }
5719                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5720                           }
5721                           continue;
5722                   }
5723                   
5724                   // faster than result <- left, anl result,right
5725                   // and better if result is SFR
5726                   if (AOP_TYPE(left) == AOP_ACC) {
5727                           emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5728                           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5729                   } else {
5730                           emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5731                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5732                           
5733                           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5734                           pic14_emitcode("iorwf","%s,w",
5735                                   aopGet(AOP(left),offset,FALSE,FALSE));
5736                   }
5737                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5738                   pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5739           }
5740   }
5741   
5742 release :
5743   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5744   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5745   freeAsmop(result,NULL,ic,TRUE);     
5746 }
5747
5748 /*-----------------------------------------------------------------*/
5749 /* genXor - code for xclusive or                                   */
5750 /*-----------------------------------------------------------------*/
5751 static void genXor (iCode *ic, iCode *ifx)
5752 {
5753         operand *left, *right, *result;
5754         int size, offset=0;
5755         unsigned long lit = 0L;
5756         
5757         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5758         
5759         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5760         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5761         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5762         
5763         /* if left is a literal & right is not ||
5764         if left needs acc & right does not */
5765         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5766                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5767                 operand *tmp = right ;
5768                 right = left;
5769                 left = tmp;
5770         }
5771         
5772         /* if result = right then exchange them */
5773         if(pic14_sameRegs(AOP(result),AOP(right))){
5774                 operand *tmp = right ;
5775                 right = left;
5776                 left = tmp;
5777         }
5778         
5779         /* if right is bit then exchange them */
5780         if (AOP_TYPE(right) == AOP_CRY &&
5781                 AOP_TYPE(left) != AOP_CRY){
5782                 operand *tmp = right ;
5783                 right = left;
5784                 left = tmp;
5785         }
5786         if(AOP_TYPE(right) == AOP_LIT)
5787                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5788         
5789         size = AOP_SIZE(result);
5790         
5791         // if(bit ^ yy)
5792         // xx = bit ^ yy;
5793         if (AOP_TYPE(left) == AOP_CRY){
5794                 if(AOP_TYPE(right) == AOP_LIT){
5795                         // c = bit & literal;
5796                         if(lit>>1){
5797                                 // lit>>1  != 0 => result = 1
5798                                 if(AOP_TYPE(result) == AOP_CRY){
5799                                         if(size)
5800                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5801                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5802                                         else if(ifx)
5803                                                 continueIfTrue(ifx);
5804                                         goto release;
5805                                 }
5806                                 pic14_emitcode("setb","c");
5807                         } else{
5808                                 // lit == (0 or 1)
5809                                 if(lit == 0){
5810                                         // lit == 0, result = left
5811                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5812                                                 goto release;
5813                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5814                                 } else{
5815                                         // lit == 1, result = not(left)
5816                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5817                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5818                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5819                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5820                                                 goto release;
5821                                         } else {
5822                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5823                                                 pic14_emitcode("cpl","c");
5824                                         }
5825                                 }
5826                         }
5827                         
5828                 } else {
5829                         // right != literal
5830                         symbol *tlbl = newiTempLabel(NULL);
5831                         if (AOP_TYPE(right) == AOP_CRY){
5832                                 // c = bit ^ bit;
5833                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5834                         }
5835                         else{
5836                                 int sizer = AOP_SIZE(right);
5837                                 // c = bit ^ val
5838                                 // if val>>1 != 0, result = 1
5839                                 pic14_emitcode("setb","c");
5840                                 while(sizer){
5841                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5842                                         if(sizer == 1)
5843                                                 // test the msb of the lsb
5844                                                 pic14_emitcode("anl","a,#0xfe");
5845                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5846                                         sizer--;
5847                                 }
5848                                 // val = (0,1)
5849                                 pic14_emitcode("rrc","a");
5850                         }
5851                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5852                         pic14_emitcode("cpl","c");
5853                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5854                 }
5855                 // bit = c
5856                 // val = c
5857                 if(size)
5858                         pic14_outBitC(result);
5859                 // if(bit | ...)
5860                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5861                         genIfxJump(ifx, "c");           
5862                 goto release ;
5863         }
5864         
5865         if(pic14_sameRegs(AOP(result),AOP(left))){
5866                 /* if left is same as result */
5867                 for(;size--; offset++) {
5868                         if(AOP_TYPE(right) == AOP_LIT){
5869                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5870                                 if(t == 0x00L)
5871                                         continue;
5872                                 else
5873                                         if (IS_AOP_PREG(left)) {
5874                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5875                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5876                                                 aopPut(AOP(result),"a",offset);
5877                                         } else {
5878                                                 emitpcode(POC_MOVLW, popGetLit(t));
5879                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5880                                                 pic14_emitcode("xrl","%s,%s",
5881                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5882                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5883                                         }
5884                         } else {
5885                                 if (AOP_TYPE(left) == AOP_ACC)
5886                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5887                                 else {
5888                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5889                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5890                                         /*
5891                                         if (IS_AOP_PREG(left)) {
5892                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5893                                         aopPut(AOP(result),"a",offset);
5894                                         } else
5895                                         pic14_emitcode("xrl","%s,a",
5896                                         aopGet(AOP(left),offset,FALSE,TRUE));
5897                                         */
5898                                 }
5899                         }
5900                 }
5901         } else {
5902                 // left & result in different registers
5903                 if(AOP_TYPE(result) == AOP_CRY){
5904                         // result = bit
5905                         // if(size), result in bit
5906                         // if(!size && ifx), conditional oper: if(left ^ right)
5907                         symbol *tlbl = newiTempLabel(NULL);
5908                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5909                         if(size)
5910                                 pic14_emitcode("setb","c");
5911                         while(sizer--){
5912                                 if((AOP_TYPE(right) == AOP_LIT) &&
5913                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5914                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5915                                 } else {
5916                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5917                                         pic14_emitcode("xrl","a,%s",
5918                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5919                                 }
5920                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5921                                 offset++;
5922                         }
5923                         if(size){
5924                                 CLRC;
5925                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5926                                 pic14_outBitC(result);
5927                         } else if(ifx)
5928                                 jmpTrueOrFalse(ifx, tlbl);
5929                 } else for(;(size--);offset++){
5930                         // normal case
5931                         // result = left & right
5932                         if(AOP_TYPE(right) == AOP_LIT){
5933                                 int t = (lit >> (offset*8)) & 0x0FFL;
5934                                 switch(t) { 
5935                                 case 0x00:
5936                                         if (AOP_TYPE(left) != AOP_ACC) {
5937                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5938                                         }
5939                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5940                                         pic14_emitcode("movf","%s,w",
5941                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5942                                         pic14_emitcode("movwf","%s",
5943                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5944                                         break;
5945                                 case 0xff:
5946                                         if (AOP_TYPE(left) == AOP_ACC) {
5947                                                 emitpcode(POC_XORLW, popGetLit(t));
5948                                         } else {
5949                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5950                                         }
5951                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5952                                         break;
5953                                 default:
5954                                         if (AOP_TYPE(left) == AOP_ACC) {
5955                                                 emitpcode(POC_XORLW, popGetLit(t));
5956                                         } else {
5957                                                 emitpcode(POC_MOVLW, popGetLit(t));
5958                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5959                                         }
5960                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5961                                         pic14_emitcode("movlw","0x%x",t);
5962                                         pic14_emitcode("xorwf","%s,w",
5963                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5964                                         pic14_emitcode("movwf","%s",
5965                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5966                                         
5967                                 }
5968                                 continue;
5969                         }
5970                         
5971                         // faster than result <- left, anl result,right
5972                         // and better if result is SFR
5973                         if (AOP_TYPE(left) == AOP_ACC) {
5974                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5975                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5976                         } else {
5977                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5978                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5979                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5980                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5981                         }
5982                         if ( AOP_TYPE(result) != AOP_ACC){
5983                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5984                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5985                         }
5986                 }
5987         }
5988         
5989 release :
5990         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5991         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5992         freeAsmop(result,NULL,ic,TRUE);     
5993 }
5994
5995 /*-----------------------------------------------------------------*/
5996 /* genInline - write the inline code out                           */
5997 /*-----------------------------------------------------------------*/
5998 static void genInline (iCode *ic)
5999 {
6000         char *buffer, *bp, *bp1;
6001         
6002         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6003         
6004         _G.inLine += (!options.asmpeep);
6005         
6006         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6007         strcpy(buffer,IC_INLINE(ic));
6008         
6009         /* emit each line as a code */
6010         while (*bp) {
6011                 if (*bp == '\n') {
6012                         *bp++ = '\0';
6013                         
6014                         if(*bp1)
6015                                 addpCode2pBlock(pb,AssembleLine(bp1));
6016                         bp1 = bp;
6017                 } else {
6018                         if (*bp == ':') {
6019                                 bp++;
6020                                 *bp = '\0';
6021                                 bp++;
6022                                 pic14_emitcode(bp1,"");
6023                                 bp1 = bp;
6024                         } else
6025                                 bp++;
6026                 }
6027         }
6028         if ((bp1 != bp) && *bp1)
6029                 addpCode2pBlock(pb,AssembleLine(bp1));
6030         
6031         Safe_free(buffer);
6032         
6033         _G.inLine -= (!options.asmpeep);
6034 }
6035
6036 /*-----------------------------------------------------------------*/
6037 /* genRRC - rotate right with carry                                */
6038 /*-----------------------------------------------------------------*/
6039 static void genRRC (iCode *ic)
6040 {
6041         operand *left , *result ;
6042         int size, offset = 0, same;
6043         
6044         /* rotate right with carry */
6045         left = IC_LEFT(ic);
6046         result=IC_RESULT(ic);
6047         aopOp (left,ic,FALSE);
6048         aopOp (result,ic,FALSE);
6049         
6050         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6051         
6052         same = pic14_sameRegs(AOP(result),AOP(left));
6053         
6054         size = AOP_SIZE(result);    
6055         
6056         /* get the lsb and put it into the carry */
6057         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6058         
6059         offset = 0 ;
6060         
6061         while(size--) {
6062                 
6063                 if(same) {
6064                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6065                 } else {
6066                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6067                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6068                 }
6069                 
6070                 offset++;
6071         }
6072         
6073         freeAsmop(left,NULL,ic,TRUE);
6074         freeAsmop(result,NULL,ic,TRUE);
6075 }
6076
6077 /*-----------------------------------------------------------------*/
6078 /* genRLC - generate code for rotate left with carry               */
6079 /*-----------------------------------------------------------------*/
6080 static void genRLC (iCode *ic)
6081 {    
6082         operand *left , *result ;
6083         int size, offset = 0;
6084         int same;
6085         
6086         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6087         /* rotate right with carry */
6088         left = IC_LEFT(ic);
6089         result=IC_RESULT(ic);
6090         aopOp (left,ic,FALSE);
6091         aopOp (result,ic,FALSE);
6092         
6093         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6094         
6095         same = pic14_sameRegs(AOP(result),AOP(left));
6096         
6097         /* move it to the result */
6098         size = AOP_SIZE(result);    
6099         
6100         /* get the msb and put it into the carry */
6101         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6102         
6103         offset = 0 ;
6104         
6105         while(size--) {
6106                 
6107                 if(same) {
6108                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6109                 } else {
6110                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6111                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6112                 }
6113                 
6114                 offset++;
6115         }
6116         
6117         
6118         freeAsmop(left,NULL,ic,TRUE);
6119         freeAsmop(result,NULL,ic,TRUE);
6120 }
6121
6122 /*-----------------------------------------------------------------*/
6123 /* genGetHbit - generates code get highest order bit               */
6124 /*-----------------------------------------------------------------*/
6125 static void genGetHbit (iCode *ic)
6126 {
6127         operand *left, *result;
6128         left = IC_LEFT(ic);
6129         result=IC_RESULT(ic);
6130         aopOp (left,ic,FALSE);
6131         aopOp (result,ic,FALSE);
6132         
6133         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6134         /* get the highest order byte into a */
6135         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6136         if(AOP_TYPE(result) == AOP_CRY){
6137                 pic14_emitcode("rlc","a");
6138                 pic14_outBitC(result);
6139         }
6140         else{
6141                 pic14_emitcode("rl","a");
6142                 pic14_emitcode("anl","a,#0x01");
6143                 pic14_outAcc(result);
6144         }
6145         
6146         
6147         freeAsmop(left,NULL,ic,TRUE);
6148         freeAsmop(result,NULL,ic,TRUE);
6149 }
6150
6151 /*-----------------------------------------------------------------*/
6152 /* AccRol - rotate left accumulator by known count                 */
6153 /*-----------------------------------------------------------------*/
6154 static void AccRol (int shCount)
6155 {
6156         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6157         shCount &= 0x0007;              // shCount : 0..7
6158         switch(shCount){
6159         case 0 :
6160                 break;
6161         case 1 :
6162                 pic14_emitcode("rl","a");
6163                 break;
6164         case 2 :
6165                 pic14_emitcode("rl","a");
6166                 pic14_emitcode("rl","a");
6167                 break;
6168         case 3 :
6169                 pic14_emitcode("swap","a");
6170                 pic14_emitcode("rr","a");
6171                 break;
6172         case 4 :
6173                 pic14_emitcode("swap","a");
6174                 break;
6175         case 5 :
6176                 pic14_emitcode("swap","a");
6177                 pic14_emitcode("rl","a");
6178                 break;
6179         case 6 :
6180                 pic14_emitcode("rr","a");
6181                 pic14_emitcode("rr","a");
6182                 break;
6183         case 7 :
6184                 pic14_emitcode("rr","a");
6185                 break;
6186         }
6187 }
6188
6189 /*-----------------------------------------------------------------*/
6190 /* AccLsh - left shift accumulator by known count                  */
6191 /*-----------------------------------------------------------------*/
6192 static void AccLsh (int shCount)
6193 {
6194         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6195         if(shCount != 0){
6196                 if(shCount == 1)
6197                         pic14_emitcode("add","a,acc");
6198                 else 
6199                         if(shCount == 2) {
6200                                 pic14_emitcode("add","a,acc");
6201                                 pic14_emitcode("add","a,acc");
6202                         } else {
6203                                 /* rotate left accumulator */
6204                                 AccRol(shCount);
6205                                 /* and kill the lower order bits */
6206                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6207                         }
6208         }
6209 }
6210
6211 /*-----------------------------------------------------------------*/
6212 /* AccRsh - right shift accumulator by known count                 */
6213 /*-----------------------------------------------------------------*/
6214 static void AccRsh (int shCount)
6215 {
6216         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6217         if(shCount != 0){
6218                 if(shCount == 1){
6219                         CLRC;
6220                         pic14_emitcode("rrc","a");
6221                 } else {
6222                         /* rotate right accumulator */
6223                         AccRol(8 - shCount);
6224                         /* and kill the higher order bits */
6225                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6226                 }
6227         }
6228 }
6229
6230 #if 0
6231 /*-----------------------------------------------------------------*/
6232 /* AccSRsh - signed right shift accumulator by known count                 */
6233 /*-----------------------------------------------------------------*/
6234 static void AccSRsh (int shCount)
6235 {
6236         symbol *tlbl ;
6237         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6238         if(shCount != 0){
6239                 if(shCount == 1){
6240                         pic14_emitcode("mov","c,acc.7");
6241                         pic14_emitcode("rrc","a");
6242                 } else if(shCount == 2){
6243                         pic14_emitcode("mov","c,acc.7");
6244                         pic14_emitcode("rrc","a");
6245                         pic14_emitcode("mov","c,acc.7");
6246                         pic14_emitcode("rrc","a");
6247                 } else {
6248                         tlbl = newiTempLabel(NULL);
6249                         /* rotate right accumulator */
6250                         AccRol(8 - shCount);
6251                         /* and kill the higher order bits */
6252                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6253                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6254                         pic14_emitcode("orl","a,#0x%02x",
6255                                 (unsigned char)~SRMask[shCount]);
6256                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6257                 }
6258         }
6259 }
6260 #endif
6261 /*-----------------------------------------------------------------*/
6262 /* shiftR1Left2Result - shift right one byte from left to result   */
6263 /*-----------------------------------------------------------------*/
6264 static void shiftR1Left2ResultSigned (operand *left, int offl,
6265                                                                           operand *result, int offr,
6266                                                                           int shCount)
6267 {
6268         int same;
6269         
6270         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6271         
6272         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6273         
6274         switch(shCount) {
6275         case 1:
6276                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6277                 if(same) 
6278                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6279                 else {
6280                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6281                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6282                 }
6283                 
6284                 break;
6285         case 2:
6286                 
6287                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6288                 if(same) 
6289                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6290                 else {
6291                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6292                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6293                 }
6294                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6295                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6296                 
6297                 break;
6298                 
6299         case 3:
6300                 if(same)
6301                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6302                 else {
6303                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6304                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6305                 }
6306                 
6307                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6308                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6309                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6310                 
6311                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6312                 emitpcode(POC_IORLW, popGetLit(0xe0));
6313                 
6314                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6315                 break;
6316                 
6317         case 4:
6318                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6319                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6320                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6321                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6322                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6323                 break;
6324         case 5:
6325                 if(same) {
6326                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6327                 } else {
6328                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6329                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6330                 }
6331                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6332                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6333                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6334                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6335                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6336                 break;
6337                 
6338         case 6:
6339                 if(same) {
6340                         emitpcode(POC_MOVLW, popGetLit(0x00));
6341                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6342                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6343                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6344                         emitpcode(POC_IORLW, popGetLit(0x01));
6345                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6346                 } else {
6347                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6348                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6349                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6350                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6351                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6352                 }
6353                 break;
6354                 
6355         case 7:
6356                 if(same) {
6357                         emitpcode(POC_MOVLW, popGetLit(0x00));
6358                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6359                         emitpcode(POC_MOVLW, popGetLit(0xff));
6360                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6361                 } else {
6362                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6363                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6364                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6365                 }
6366                 
6367         default:
6368                 break;
6369         }
6370 }
6371
6372 /*-----------------------------------------------------------------*/
6373 /* shiftR1Left2Result - shift right one byte from left to result   */
6374 /*-----------------------------------------------------------------*/
6375 static void shiftR1Left2Result (operand *left, int offl,
6376                                                                 operand *result, int offr,
6377                                                                 int shCount, int sign)
6378 {
6379         int same;
6380         
6381         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6382         
6383         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6384         
6385         /* Copy the msb into the carry if signed. */
6386         if(sign) {
6387                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6388                 return;
6389         }
6390         
6391         
6392         
6393         switch(shCount) {
6394         case 1:
6395                 emitCLRC;
6396                 if(same) 
6397                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6398                 else {
6399                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6400                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6401                 }
6402                 break;
6403         case 2:
6404                 emitCLRC;
6405                 if(same) {
6406                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6407                 } else {
6408                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6409                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6410                 }
6411                 emitCLRC;
6412                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6413                 
6414                 break;
6415         case 3:
6416                 if(same)
6417                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6418                 else {
6419                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6420                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6421                 }
6422                 
6423                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6424                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6425                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6426                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427                 break;
6428                 
6429         case 4:
6430                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6431                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6432                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6433                 break;
6434                 
6435         case 5:
6436                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6437                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6438                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6439                 emitCLRC;
6440                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6441                 
6442                 break;
6443         case 6:
6444                 
6445                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6446                 emitpcode(POC_ANDLW, popGetLit(0x80));
6447                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6448                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6449                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6450                 break;
6451                 
6452         case 7:
6453                 
6454                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6455                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6456                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6457                 
6458                 break;
6459                 
6460         default:
6461                 break;
6462         }
6463 }
6464
6465 /*-----------------------------------------------------------------*/
6466 /* shiftL1Left2Result - shift left one byte from left to result    */
6467 /*-----------------------------------------------------------------*/
6468 static void shiftL1Left2Result (operand *left, int offl,
6469                                                                 operand *result, int offr, int shCount)
6470 {
6471         int same;
6472         
6473         //    char *l;
6474         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6475         
6476         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6477         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6478         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6479         //    MOVA(l);
6480         /* shift left accumulator */
6481         //AccLsh(shCount); // don't comment out just yet...
6482         //    aopPut(AOP(result),"a",offr);
6483         
6484         switch(shCount) {
6485         case 1:
6486                 /* Shift left 1 bit position */
6487                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6488                 if(same) {
6489                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6490                 } else {
6491                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6492                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6493                 }
6494                 break;
6495         case 2:
6496                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6497                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6498                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6499                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6500                 break;
6501         case 3:
6502                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6503                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6504                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6505                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6506                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6507                 break;
6508         case 4:
6509                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6510                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6511                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6512                 break;
6513         case 5:
6514                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6515                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6516                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6517                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6518                 break;
6519         case 6:
6520                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6521                 emitpcode(POC_ANDLW, popGetLit(0x30));
6522                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6523                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6524                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6525                 break;
6526         case 7:
6527                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6528                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6529                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6530                 break;
6531                 
6532         default:
6533                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6534         }
6535         
6536 }
6537
6538 /*-----------------------------------------------------------------*/
6539 /* movLeft2Result - move byte from left to result                  */
6540 /*-----------------------------------------------------------------*/
6541 static void movLeft2Result (operand *left, int offl,
6542                                                         operand *result, int offr)
6543 {
6544         char *l;
6545         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6546         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6547                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6548                 
6549                 if (*l == '@' && (IS_AOP_PREG(result))) {
6550                         pic14_emitcode("mov","a,%s",l);
6551                         aopPut(AOP(result),"a",offr);
6552                 } else {
6553                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6554                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6555                 }
6556         }
6557 }
6558
6559 /*-----------------------------------------------------------------*/
6560 /* shiftL2Left2Result - shift left two bytes from left to result   */
6561 /*-----------------------------------------------------------------*/
6562 static void shiftL2Left2Result (operand *left, int offl,
6563                                                                 operand *result, int offr, int shCount)
6564 {
6565         
6566         
6567         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6568         
6569         if(pic14_sameRegs(AOP(result), AOP(left))) {
6570                 switch(shCount) {
6571                 case 0:
6572                         break;
6573                 case 1:
6574                 case 2:
6575                 case 3:
6576                         
6577                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6578                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6579                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6580                         
6581                         while(--shCount) {
6582                                 emitCLRC;
6583                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6584                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6585                         }
6586                         
6587                         break;
6588                 case 4:
6589                 case 5:
6590                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6591                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6592                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6593                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6594                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6595                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6596                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6597                         if(shCount >=5) {
6598                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6599                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6600                         }
6601                         break;
6602                 case 6:
6603                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6604                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6605                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6606                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6607                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6608                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6609                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6610                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6611                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6612                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6613                         break;
6614                 case 7:
6615                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6616                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6617                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6618                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6619                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6620                 }
6621                 
6622         } else {
6623                 switch(shCount) {
6624                 case 0:
6625                         break;
6626                 case 1:
6627                 case 2:
6628                 case 3:
6629                 /* note, use a mov/add for the shift since the mov has a
6630                         chance of getting optimized out */
6631                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6632                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6633                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6634                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6635                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6636                         
6637                         while(--shCount) {
6638                                 emitCLRC;
6639                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6640                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6641                         }
6642                         break;
6643                         
6644                 case 4:
6645                 case 5:
6646                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6647                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6648                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6649                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6650                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6651                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6652                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6653                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6654                         
6655                         
6656                         if(shCount == 5) {
6657                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6658                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6659                         }
6660                         break;
6661                 case 6:
6662                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6663                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6664                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6665                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6666                         
6667                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6668                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6669                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6670                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6671                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6672                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6673                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6674                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6675                         break;
6676                 case 7:
6677                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6678                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6679                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6680                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6681                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6682                 }
6683         }
6684         
6685 }
6686 /*-----------------------------------------------------------------*/
6687 /* shiftR2Left2Result - shift right two bytes from left to result  */
6688 /*-----------------------------------------------------------------*/
6689 static void shiftR2Left2Result (operand *left, int offl,
6690                                                                 operand *result, int offr,
6691                                                                 int shCount, int sign)
6692 {
6693         int same=0;
6694         
6695         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6696         same = pic14_sameRegs(AOP(result), AOP(left));
6697         
6698         if(same && ((offl + MSB16) == offr)){
6699                 same=1;
6700                 /* don't crash result[offr] */
6701                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6702                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6703         }
6704         /* else {
6705         movLeft2Result(left,offl, result, offr);
6706         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6707         }
6708         */
6709         /* a:x >> shCount (x = lsb(result))*/
6710         /*
6711         if(sign)
6712         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6713         else {
6714         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6715         */
6716         switch(shCount) {
6717         case 0:
6718                 break;
6719         case 1:
6720         case 2:
6721         case 3:
6722                 if(sign)
6723                         emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6724                 else
6725                         emitCLRC;
6726                 
6727                 if(same) {
6728                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6729                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6730                 } else {
6731                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6732                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6733                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6734                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6735                 }
6736                 
6737                 while(--shCount) {
6738                         if(sign)
6739                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6740                         else
6741                                 emitCLRC;
6742                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6743                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6744                 }
6745                 break;
6746         case 4:
6747         case 5:
6748                 if(same) {
6749                         
6750                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6751                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6752                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6753                         
6754                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6755                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6756                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6757                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6758                 } else {
6759                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6760                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6761                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6762                         
6763                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6764                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6765                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6766                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6767                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6768                 }
6769                 
6770                 if(shCount >=5) {
6771                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6772                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6773                 }
6774                 
6775                 if(sign) {
6776                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6777                         emitpcode(POC_BTFSC, 
6778                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6779                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6780                 }
6781                 
6782                 break;
6783                 
6784         case 6:
6785                 if(same) {
6786                         
6787                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6788                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6789                         
6790                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6791                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6792                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6793                         emitpcode(POC_ANDLW,popGetLit(0x03));
6794                         if(sign) {
6795                                 emitpcode(POC_BTFSC, 
6796                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6797                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6798                         }
6799                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6800                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6801                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6802                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6803                 } else {
6804                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6805                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6806                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6807                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6808                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6809                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6810                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6811                         emitpcode(POC_ANDLW,popGetLit(0x03));
6812                         if(sign) {
6813                                 emitpcode(POC_BTFSC, 
6814                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6815                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6816                         }
6817                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6818                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6819                         
6820                         
6821                 }
6822                 
6823                 break;
6824         case 7:
6825                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6826                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6827                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6828                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6829                 if(sign) {
6830                         emitSKPNC;
6831                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6832                 } else 
6833                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6834   }
6835 }
6836
6837
6838 /*-----------------------------------------------------------------*/
6839 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6840 /*-----------------------------------------------------------------*/
6841 static void shiftLLeftOrResult (operand *left, int offl,
6842                                                                 operand *result, int offr, int shCount)
6843 {
6844         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6845         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6846         /* shift left accumulator */
6847         AccLsh(shCount);
6848         /* or with result */
6849         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6850         /* back to result */
6851         aopPut(AOP(result),"a",offr);
6852 }
6853
6854 /*-----------------------------------------------------------------*/
6855 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6856 /*-----------------------------------------------------------------*/
6857 static void shiftRLeftOrResult (operand *left, int offl,
6858                                                                 operand *result, int offr, int shCount)
6859 {
6860         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6861         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6862         /* shift right accumulator */
6863         AccRsh(shCount);
6864         /* or with result */
6865         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6866         /* back to result */
6867         aopPut(AOP(result),"a",offr);
6868 }
6869
6870 /*-----------------------------------------------------------------*/
6871 /* genlshOne - left shift a one byte quantity by known count       */
6872 /*-----------------------------------------------------------------*/
6873 static void genlshOne (operand *result, operand *left, int shCount)
6874 {       
6875         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6876         shiftL1Left2Result(left, LSB, result, LSB, shCount);
6877 }
6878
6879 /*-----------------------------------------------------------------*/
6880 /* genlshTwo - left shift two bytes by known amount != 0           */
6881 /*-----------------------------------------------------------------*/
6882 static void genlshTwo (operand *result,operand *left, int shCount)
6883 {
6884         int size;
6885         
6886         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6887         size = pic14_getDataSize(result);
6888         
6889         /* if shCount >= 8 */
6890         if (shCount >= 8) {
6891                 shCount -= 8 ;
6892                 
6893                 if (size > 1){
6894                         if (shCount)
6895                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6896                         else 
6897                                 movLeft2Result(left, LSB, result, MSB16);
6898                 }
6899                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6900         }
6901         
6902         /*  1 <= shCount <= 7 */
6903         else {  
6904                 if(size == 1)
6905                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6906                 else 
6907                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6908         }
6909 }
6910
6911 /*-----------------------------------------------------------------*/
6912 /* shiftLLong - shift left one long from left to result            */
6913 /* offl = LSB or MSB16                                             */
6914 /*-----------------------------------------------------------------*/
6915 static void shiftLLong (operand *left, operand *result, int offr )
6916 {
6917         char *l;
6918         int size = AOP_SIZE(result);
6919         
6920         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6921         if(size >= LSB+offr){
6922                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6923                 MOVA(l);
6924                 pic14_emitcode("add","a,acc");
6925                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6926                         size >= MSB16+offr && offr != LSB )
6927                         pic14_emitcode("xch","a,%s",
6928                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6929                 else      
6930                         aopPut(AOP(result),"a",LSB+offr);
6931         }
6932         
6933         if(size >= MSB16+offr){
6934                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6935                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6936                         MOVA(l);
6937                 }
6938                 pic14_emitcode("rlc","a");
6939                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6940                         size >= MSB24+offr && offr != LSB)
6941                         pic14_emitcode("xch","a,%s",
6942                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6943                 else      
6944                         aopPut(AOP(result),"a",MSB16+offr);
6945         }
6946         
6947         if(size >= MSB24+offr){
6948                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6949                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6950                         MOVA(l);
6951                 }
6952                 pic14_emitcode("rlc","a");
6953                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6954                         size >= MSB32+offr && offr != LSB )
6955                         pic14_emitcode("xch","a,%s",
6956                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6957                 else      
6958                         aopPut(AOP(result),"a",MSB24+offr);
6959         }
6960         
6961         if(size > MSB32+offr){
6962                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6963                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6964                         MOVA(l);  
6965                 }
6966                 pic14_emitcode("rlc","a");
6967                 aopPut(AOP(result),"a",MSB32+offr);
6968         }
6969         if(offr != LSB)
6970                 aopPut(AOP(result),zero,LSB);       
6971 }
6972
6973 /*-----------------------------------------------------------------*/
6974 /* genlshFour - shift four byte by a known amount != 0             */
6975 /*-----------------------------------------------------------------*/
6976 static void genlshFour (operand *result, operand *left, int shCount)
6977 {
6978         int size;
6979         
6980         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6981         size = AOP_SIZE(result);
6982         
6983         /* if shifting more that 3 bytes */
6984         if (shCount >= 24 ) {
6985                 shCount -= 24;
6986                 if (shCount)
6987                 /* lowest order of left goes to the highest
6988                 order of the destination */
6989                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6990                 else
6991                         movLeft2Result(left, LSB, result, MSB32);
6992                 aopPut(AOP(result),zero,LSB);
6993                 aopPut(AOP(result),zero,MSB16);
6994                 aopPut(AOP(result),zero,MSB32);
6995                 return;
6996         }
6997         
6998         /* more than two bytes */
6999         else if ( shCount >= 16 ) {
7000                 /* lower order two bytes goes to higher order two bytes */
7001                 shCount -= 16;
7002                 /* if some more remaining */
7003                 if (shCount)
7004                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7005                 else {
7006                         movLeft2Result(left, MSB16, result, MSB32);
7007                         movLeft2Result(left, LSB, result, MSB24);
7008                 }
7009                 aopPut(AOP(result),zero,MSB16);
7010                 aopPut(AOP(result),zero,LSB);
7011                 return;
7012         }    
7013         
7014         /* if more than 1 byte */
7015         else if ( shCount >= 8 ) {
7016                 /* lower order three bytes goes to higher order  three bytes */
7017                 shCount -= 8;
7018                 if(size == 2){
7019                         if(shCount)
7020                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7021                         else
7022                                 movLeft2Result(left, LSB, result, MSB16);
7023                 }
7024                 else{   /* size = 4 */
7025                         if(shCount == 0){
7026                                 movLeft2Result(left, MSB24, result, MSB32);
7027                                 movLeft2Result(left, MSB16, result, MSB24);
7028                                 movLeft2Result(left, LSB, result, MSB16);
7029                                 aopPut(AOP(result),zero,LSB);
7030                         }
7031                         else if(shCount == 1)
7032                                 shiftLLong(left, result, MSB16);
7033                         else{
7034                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7035                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7036                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7037                                 aopPut(AOP(result),zero,LSB);
7038                         }
7039                 }
7040         }
7041         
7042         /* 1 <= shCount <= 7 */
7043         else if(shCount <= 2){
7044                 shiftLLong(left, result, LSB);
7045                 if(shCount == 2)
7046                         shiftLLong(result, result, LSB);
7047         }
7048         /* 3 <= shCount <= 7, optimize */
7049         else{
7050                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7051                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7052                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7053         }
7054 }
7055
7056 /*-----------------------------------------------------------------*/
7057 /* genLeftShiftLiteral - left shifting by known count              */
7058 /*-----------------------------------------------------------------*/
7059 static void genLeftShiftLiteral (operand *left,
7060                                                                  operand *right,
7061                                                                  operand *result,
7062                                                                  iCode *ic)
7063 {    
7064         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7065         int size;
7066         
7067         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7068         freeAsmop(right,NULL,ic,TRUE);
7069         
7070         aopOp(left,ic,FALSE);
7071         aopOp(result,ic,FALSE);
7072         
7073         size = getSize(operandType(result));
7074         
7075 #if VIEW_SIZE
7076         pic14_emitcode("; shift left ","result %d, left %d",size,
7077                 AOP_SIZE(left));
7078 #endif
7079         
7080         /* I suppose that the left size >= result size */
7081         if(shCount == 0){
7082                 while(size--){
7083                         movLeft2Result(left, size, result, size);
7084                 }
7085         }
7086         
7087         else if(shCount >= (size * 8))
7088                 while(size--)
7089                         aopPut(AOP(result),zero,size);
7090                 else{
7091                         switch (size) {
7092                         case 1:
7093                                 genlshOne (result,left,shCount);
7094                                 break;
7095                                 
7096                         case 2:
7097                         case 3:
7098                                 genlshTwo (result,left,shCount);
7099                                 break;
7100                                 
7101                         case 4:
7102                                 genlshFour (result,left,shCount);
7103                                 break;
7104                         }
7105                 }
7106                 freeAsmop(left,NULL,ic,TRUE);
7107                 freeAsmop(result,NULL,ic,TRUE);
7108 }
7109
7110 /*-----------------------------------------------------------------*
7111 * genMultiAsm - repeat assembly instruction for size of register.
7112 * if endian == 1, then the high byte (i.e base address + size of 
7113 * register) is used first else the low byte is used first;
7114 *-----------------------------------------------------------------*/
7115 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7116 {
7117         
7118         int offset = 0;
7119         
7120         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7121         
7122         if(!reg)
7123                 return;
7124         
7125         if(!endian) {
7126                 endian = 1;
7127         } else {
7128                 endian = -1;
7129                 offset = size-1;
7130         }
7131         
7132         while(size--) {
7133                 emitpcode(poc,    popGet(AOP(reg),offset));
7134                 offset += endian;
7135         }
7136         
7137 }
7138 /*-----------------------------------------------------------------*/
7139 /* genLeftShift - generates code for left shifting                 */
7140 /*-----------------------------------------------------------------*/
7141 static void genLeftShift (iCode *ic)
7142 {
7143         operand *left,*right, *result;
7144         int size, offset;
7145         char *l;
7146         symbol *tlbl , *tlbl1;
7147         pCodeOp *pctemp;
7148         
7149         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7150         
7151         right = IC_RIGHT(ic);
7152         left  = IC_LEFT(ic);
7153         result = IC_RESULT(ic);
7154         
7155         aopOp(right,ic,FALSE);
7156         
7157         /* if the shift count is known then do it 
7158         as efficiently as possible */
7159         if (AOP_TYPE(right) == AOP_LIT) {
7160                 genLeftShiftLiteral (left,right,result,ic);
7161                 return ;
7162         }
7163         
7164         /* shift count is unknown then we have to form 
7165         a loop get the loop count in B : Note: we take
7166         only the lower order byte since shifting
7167         more that 32 bits make no sense anyway, ( the
7168         largest size of an object can be only 32 bits ) */  
7169         
7170         
7171         aopOp(left,ic,FALSE);
7172         aopOp(result,ic,FALSE);
7173         
7174         /* now move the left to the result if they are not the
7175         same */
7176         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7177                 AOP_SIZE(result) > 1) {
7178                 
7179                 size = AOP_SIZE(result);
7180                 offset=0;
7181                 while (size--) {
7182                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7183                         if (*l == '@' && (IS_AOP_PREG(result))) {
7184                                 
7185                                 pic14_emitcode("mov","a,%s",l);
7186                                 aopPut(AOP(result),"a",offset);
7187                         } else {
7188                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7189                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7190                                 //aopPut(AOP(result),l,offset);
7191                         }
7192                         offset++;
7193                 }
7194         }
7195         
7196         size = AOP_SIZE(result);
7197         
7198         /* if it is only one byte then */
7199         if (size == 1) {
7200                 if(optimized_for_speed) {
7201                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7202                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7203                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7204                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7205                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7206                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7207                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7208                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7209                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7210                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7211                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7212                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7213                 } else {
7214                         
7215                         tlbl = newiTempLabel(NULL);
7216                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7217                                 emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7218                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7219                         }
7220                         
7221                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7222                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7223                         emitpLabel(tlbl->key);
7224                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7225                         emitpcode(POC_ADDLW,  popGetLit(1));
7226                         emitSKPC;
7227                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7228                 }
7229                 goto release ;
7230         }
7231         
7232         if (pic14_sameRegs(AOP(left),AOP(result))) {
7233                 
7234                 tlbl = newiTempLabel(NULL);
7235                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7236                 genMultiAsm(POC_RRF, result, size,1);
7237                 emitpLabel(tlbl->key);
7238                 genMultiAsm(POC_RLF, result, size,0);
7239                 emitpcode(POC_ADDLW,  popGetLit(1));
7240                 emitSKPC;
7241                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7242                 goto release;
7243         }
7244         
7245         //tlbl = newiTempLabel(NULL);
7246         //offset = 0 ;   
7247         //tlbl1 = newiTempLabel(NULL);
7248         
7249         //reAdjustPreg(AOP(result));    
7250         
7251         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7252         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7253         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7254         //MOVA(l);
7255         //pic14_emitcode("add","a,acc");         
7256         //aopPut(AOP(result),"a",offset++);
7257         //while (--size) {
7258         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7259         //  MOVA(l);
7260         //  pic14_emitcode("rlc","a");         
7261         //  aopPut(AOP(result),"a",offset++);
7262         //}
7263         //reAdjustPreg(AOP(result));
7264         
7265         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7266         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7267         
7268         
7269         tlbl = newiTempLabel(NULL);
7270         tlbl1= newiTempLabel(NULL);
7271         
7272         size = AOP_SIZE(result);
7273         offset = 1;
7274         
7275         pctemp = popGetTempReg();  /* grab a temporary working register. */
7276         
7277         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7278         
7279         /* offset should be 0, 1 or 3 */
7280         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7281         emitSKPNZ;
7282         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7283         
7284         emitpcode(POC_MOVWF, pctemp);
7285         
7286         
7287         emitpLabel(tlbl->key);
7288         
7289         emitCLRC;
7290         emitpcode(POC_RLF,  popGet(AOP(result),0));
7291         while(--size)
7292                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7293         
7294         emitpcode(POC_DECFSZ,  pctemp);
7295         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7296         emitpLabel(tlbl1->key);
7297         
7298         popReleaseTempReg(pctemp);
7299         
7300         
7301 release:
7302         freeAsmop (right,NULL,ic,TRUE);
7303         freeAsmop(left,NULL,ic,TRUE);
7304         freeAsmop(result,NULL,ic,TRUE);
7305 }
7306
7307 /*-----------------------------------------------------------------*/
7308 /* genrshOne - right shift a one byte quantity by known count      */
7309 /*-----------------------------------------------------------------*/
7310 static void genrshOne (operand *result, operand *left,
7311                                            int shCount, int sign)
7312 {
7313         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7314         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7315 }
7316
7317 /*-----------------------------------------------------------------*/
7318 /* genrshTwo - right shift two bytes by known amount != 0          */
7319 /*-----------------------------------------------------------------*/
7320 static void genrshTwo (operand *result,operand *left,
7321                                            int shCount, int sign)
7322 {
7323         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7324         /* if shCount >= 8 */
7325         if (shCount >= 8) {
7326                 shCount -= 8 ;
7327                 if (shCount)
7328                         shiftR1Left2Result(left, MSB16, result, LSB,
7329                         shCount, sign);
7330                 else
7331                         movLeft2Result(left, MSB16, result, LSB);
7332                 
7333                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7334                 
7335                 if(sign) {
7336                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7337                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7338                 }
7339         }
7340         
7341         /*  1 <= shCount <= 7 */
7342         else
7343                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7344 }
7345
7346 /*-----------------------------------------------------------------*/
7347 /* shiftRLong - shift right one long from left to result           */
7348 /* offl = LSB or MSB16                                             */
7349 /*-----------------------------------------------------------------*/
7350 static void shiftRLong (operand *left, int offl,
7351                                                 operand *result, int sign)
7352 {
7353         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7354         if(!sign)
7355                 pic14_emitcode("clr","c");
7356         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7357         if(sign)
7358                 pic14_emitcode("mov","c,acc.7");
7359         pic14_emitcode("rrc","a");
7360         aopPut(AOP(result),"a",MSB32-offl);
7361         if(offl == MSB16)
7362                 /* add sign of "a" */
7363                 addSign(result, MSB32, sign);
7364         
7365         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7366         pic14_emitcode("rrc","a");
7367         aopPut(AOP(result),"a",MSB24-offl);
7368         
7369         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7370         pic14_emitcode("rrc","a");
7371         aopPut(AOP(result),"a",MSB16-offl);
7372         
7373         if(offl == LSB){
7374                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7375                 pic14_emitcode("rrc","a");
7376                 aopPut(AOP(result),"a",LSB);
7377         }
7378 }
7379
7380 /*-----------------------------------------------------------------*/
7381 /* genrshFour - shift four byte by a known amount != 0             */
7382 /*-----------------------------------------------------------------*/
7383 static void genrshFour (operand *result, operand *left,
7384                                                 int shCount, int sign)
7385 {
7386         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7387         /* if shifting more that 3 bytes */
7388         if(shCount >= 24 ) {
7389                 shCount -= 24;
7390                 if(shCount)
7391                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7392                 else
7393                         movLeft2Result(left, MSB32, result, LSB);
7394                 
7395                 addSign(result, MSB16, sign);
7396         }
7397         else if(shCount >= 16){
7398                 shCount -= 16;
7399                 if(shCount)
7400                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7401                 else{
7402                         movLeft2Result(left, MSB24, result, LSB);
7403                         movLeft2Result(left, MSB32, result, MSB16);
7404                 }
7405                 addSign(result, MSB24, sign);
7406         }
7407         else if(shCount >= 8){
7408                 shCount -= 8;
7409                 if(shCount == 1)
7410                         shiftRLong(left, MSB16, result, sign);
7411                 else if(shCount == 0){
7412                         movLeft2Result(left, MSB16, result, LSB);
7413                         movLeft2Result(left, MSB24, result, MSB16);
7414                         movLeft2Result(left, MSB32, result, MSB24);
7415                         addSign(result, MSB32, sign);
7416                 }
7417                 else{
7418                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7419                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7420                         /* the last shift is signed */
7421                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7422                         addSign(result, MSB32, sign);
7423                 }
7424         }
7425         else{   /* 1 <= shCount <= 7 */
7426                 if(shCount <= 2){
7427                         shiftRLong(left, LSB, result, sign);
7428                         if(shCount == 2)
7429                                 shiftRLong(result, LSB, result, sign);
7430                 }
7431                 else{
7432                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7433                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7434                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7435                 }
7436         }
7437 }
7438
7439 /*-----------------------------------------------------------------*/
7440 /* genRightShiftLiteral - right shifting by known count            */
7441 /*-----------------------------------------------------------------*/
7442 static void genRightShiftLiteral (operand *left,
7443                                                                   operand *right,
7444                                                                   operand *result,
7445                                                                   iCode *ic,
7446                                                                   int sign)
7447 {    
7448         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7449         int lsize,res_size;
7450         
7451         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7452         freeAsmop(right,NULL,ic,TRUE);
7453         
7454         aopOp(left,ic,FALSE);
7455         aopOp(result,ic,FALSE);
7456         
7457 #if VIEW_SIZE
7458         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7459                 AOP_SIZE(left));
7460 #endif
7461         
7462         lsize = pic14_getDataSize(left);
7463         res_size = pic14_getDataSize(result);
7464         /* test the LEFT size !!! */
7465         
7466         /* I suppose that the left size >= result size */
7467         if(shCount == 0){
7468                 while(res_size--)
7469                         movLeft2Result(left, lsize, result, res_size);
7470         }
7471         
7472         else if(shCount >= (lsize * 8)){
7473                 
7474                 if(res_size == 1) {
7475                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7476                         if(sign) {
7477                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7478                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7479                         }
7480                 } else {
7481                         
7482                         if(sign) {
7483                                 emitpcode(POC_MOVLW, popGetLit(0));
7484                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7485                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7486                                 while(res_size--)
7487                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7488                                 
7489                         } else {
7490                                 
7491                                 while(res_size--)
7492                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7493                         }
7494                 }
7495         } else {
7496                 
7497                 switch (res_size) {
7498                 case 1:
7499                         genrshOne (result,left,shCount,sign);
7500                         break;
7501                         
7502                 case 2:
7503                         genrshTwo (result,left,shCount,sign);
7504                         break;
7505                         
7506                 case 4:
7507                         genrshFour (result,left,shCount,sign);
7508                         break;
7509                 default :
7510                         break;
7511                 }
7512                 
7513         }
7514         
7515         freeAsmop(left,NULL,ic,TRUE);
7516         freeAsmop(result,NULL,ic,TRUE);
7517 }
7518
7519 /*-----------------------------------------------------------------*/
7520 /* genSignedRightShift - right shift of signed number              */
7521 /*-----------------------------------------------------------------*/
7522 static void genSignedRightShift (iCode *ic)
7523 {
7524         operand *right, *left, *result;
7525         int size, offset;
7526         //  char *l;
7527         symbol *tlbl, *tlbl1 ;
7528         pCodeOp *pctemp;
7529         
7530         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7531         
7532         /* we do it the hard way put the shift count in b
7533         and loop thru preserving the sign */
7534         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7535         
7536         right = IC_RIGHT(ic);
7537         left  = IC_LEFT(ic);
7538         result = IC_RESULT(ic);
7539         
7540         aopOp(right,ic,FALSE);  
7541         aopOp(left,ic,FALSE);
7542         aopOp(result,ic,FALSE);
7543         
7544         
7545         if ( AOP_TYPE(right) == AOP_LIT) {
7546                 genRightShiftLiteral (left,right,result,ic,1);
7547                 return ;
7548         }
7549         /* shift count is unknown then we have to form 
7550         a loop get the loop count in B : Note: we take
7551         only the lower order byte since shifting
7552         more that 32 bits make no sense anyway, ( the
7553         largest size of an object can be only 32 bits ) */  
7554         
7555         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7556         //pic14_emitcode("inc","b");
7557         //freeAsmop (right,NULL,ic,TRUE);
7558         //aopOp(left,ic,FALSE);
7559         //aopOp(result,ic,FALSE);
7560         
7561         /* now move the left to the result if they are not the
7562         same */
7563         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7564                 AOP_SIZE(result) > 1) {
7565                 
7566                 size = AOP_SIZE(result);
7567                 offset=0;
7568                 while (size--) { 
7569                 /*
7570                 l = aopGet(AOP(left),offset,FALSE,TRUE);
7571                 if (*l == '@' && IS_AOP_PREG(result)) {
7572                 
7573                   pic14_emitcode("mov","a,%s",l);
7574                   aopPut(AOP(result),"a",offset);
7575                   } else
7576                   aopPut(AOP(result),l,offset);
7577                         */
7578                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7579                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7580                         
7581                         offset++;
7582                 }
7583         }
7584         
7585         /* mov the highest order bit to OVR */    
7586         tlbl = newiTempLabel(NULL);
7587         tlbl1= newiTempLabel(NULL);
7588         
7589         size = AOP_SIZE(result);
7590         offset = size - 1;
7591         
7592         pctemp = popGetTempReg();  /* grab a temporary working register. */
7593         
7594         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7595         
7596         /* offset should be 0, 1 or 3 */
7597         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7598         emitSKPNZ;
7599         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7600         
7601         emitpcode(POC_MOVWF, pctemp);
7602         
7603         
7604         emitpLabel(tlbl->key);
7605         
7606         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7607         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7608         
7609         while(--size) {
7610                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7611         }
7612         
7613         emitpcode(POC_DECFSZ,  pctemp);
7614         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7615         emitpLabel(tlbl1->key);
7616         
7617         popReleaseTempReg(pctemp);
7618 #if 0
7619         size = AOP_SIZE(result);
7620         offset = size - 1;
7621         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7622         pic14_emitcode("rlc","a");
7623         pic14_emitcode("mov","ov,c");
7624         /* if it is only one byte then */
7625         if (size == 1) {
7626                 l = aopGet(AOP(left),0,FALSE,FALSE);
7627                 MOVA(l);
7628                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7629                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7630                 pic14_emitcode("mov","c,ov");
7631                 pic14_emitcode("rrc","a");
7632                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7633                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7634                 aopPut(AOP(result),"a",0);
7635                 goto release ;
7636         }
7637         
7638         reAdjustPreg(AOP(result));
7639         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7640         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7641         pic14_emitcode("mov","c,ov");
7642         while (size--) {
7643                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7644                 MOVA(l);
7645                 pic14_emitcode("rrc","a");         
7646                 aopPut(AOP(result),"a",offset--);
7647         }
7648         reAdjustPreg(AOP(result));
7649         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7650         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7651         
7652 release:
7653 #endif
7654         
7655         freeAsmop(left,NULL,ic,TRUE);
7656         freeAsmop(result,NULL,ic,TRUE);
7657         freeAsmop(right,NULL,ic,TRUE);
7658 }
7659
7660 /*-----------------------------------------------------------------*/
7661 /* genRightShift - generate code for right shifting                */
7662 /*-----------------------------------------------------------------*/
7663 static void genRightShift (iCode *ic)
7664 {
7665         operand *right, *left, *result;
7666         sym_link *retype ;
7667         int size, offset;
7668         char *l;
7669         symbol *tlbl, *tlbl1 ;
7670         
7671         /* if signed then we do it the hard way preserve the
7672         sign bit moving it inwards */
7673         retype = getSpec(operandType(IC_RESULT(ic)));
7674         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7675         
7676         if (!SPEC_USIGN(retype)) {
7677                 genSignedRightShift (ic);
7678                 return ;
7679         }
7680         
7681         /* signed & unsigned types are treated the same : i.e. the
7682         signed is NOT propagated inwards : quoting from the
7683         ANSI - standard : "for E1 >> E2, is equivalent to division
7684         by 2**E2 if unsigned or if it has a non-negative value,
7685         otherwise the result is implementation defined ", MY definition
7686         is that the sign does not get propagated */
7687         
7688         right = IC_RIGHT(ic);
7689         left  = IC_LEFT(ic);
7690         result = IC_RESULT(ic);
7691         
7692         aopOp(right,ic,FALSE);
7693         
7694         /* if the shift count is known then do it 
7695         as efficiently as possible */
7696         if (AOP_TYPE(right) == AOP_LIT) {
7697                 genRightShiftLiteral (left,right,result,ic, 0);
7698                 return ;
7699         }
7700         
7701         /* shift count is unknown then we have to form 
7702         a loop get the loop count in B : Note: we take
7703         only the lower order byte since shifting
7704         more that 32 bits make no sense anyway, ( the
7705         largest size of an object can be only 32 bits ) */  
7706         
7707         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7708         pic14_emitcode("inc","b");
7709         aopOp(left,ic,FALSE);
7710         aopOp(result,ic,FALSE);
7711         
7712         /* now move the left to the result if they are not the
7713         same */
7714         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7715                 AOP_SIZE(result) > 1) {
7716                 
7717                 size = AOP_SIZE(result);
7718                 offset=0;
7719                 while (size--) {
7720                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7721                         if (*l == '@' && IS_AOP_PREG(result)) {
7722                                 
7723                                 pic14_emitcode("mov","a,%s",l);
7724                                 aopPut(AOP(result),"a",offset);
7725                         } else
7726                                 aopPut(AOP(result),l,offset);
7727                         offset++;
7728                 }
7729         }
7730         
7731         tlbl = newiTempLabel(NULL);
7732         tlbl1= newiTempLabel(NULL);
7733         size = AOP_SIZE(result);
7734         offset = size - 1;
7735         
7736         /* if it is only one byte then */
7737         if (size == 1) {
7738                 
7739                 tlbl = newiTempLabel(NULL);
7740                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7741                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7742                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7743                 }
7744                 
7745                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7746                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7747                 emitpLabel(tlbl->key);
7748                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7749                 emitpcode(POC_ADDLW,  popGetLit(1));
7750                 emitSKPC;
7751                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7752                 
7753                 goto release ;
7754         }
7755         
7756         reAdjustPreg(AOP(result));
7757         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7758         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7759         CLRC;
7760         while (size--) {
7761                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7762                 MOVA(l);
7763                 pic14_emitcode("rrc","a");         
7764                 aopPut(AOP(result),"a",offset--);
7765         }
7766         reAdjustPreg(AOP(result));
7767         
7768         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7769         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7770         
7771 release:
7772         freeAsmop(left,NULL,ic,TRUE);
7773         freeAsmop (right,NULL,ic,TRUE);
7774         freeAsmop(result,NULL,ic,TRUE);
7775 }
7776
7777 /*-----------------------------------------------------------------*/
7778 /* genUnpackBits - generates code for unpacking bits               */
7779 /*-----------------------------------------------------------------*/
7780 static void genUnpackBits (operand *result, char *rname, int ptype)
7781 {    
7782         int shCnt ;
7783         int rlen = 0 ;
7784         sym_link *etype;
7785         int offset = 0 ;
7786         
7787         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7788         etype = getSpec(operandType(result));
7789         
7790         /* read the first byte  */
7791         switch (ptype) {
7792                 
7793         case POINTER:
7794         case IPOINTER:
7795                 pic14_emitcode("mov","a,@%s",rname);
7796                 break;
7797                 
7798         case PPOINTER:
7799                 pic14_emitcode("movx","a,@%s",rname);
7800                 break;
7801                 
7802         case FPOINTER:
7803                 pic14_emitcode("movx","a,@dptr");
7804                 break;
7805                 
7806         case CPOINTER:
7807                 pic14_emitcode("clr","a");
7808                 pic14_emitcode("movc","a","@a+dptr");
7809                 break;
7810                 
7811         case GPOINTER:
7812                 pic14_emitcode("lcall","__gptrget");
7813                 break;
7814         }
7815         
7816         /* if we have bitdisplacement then it fits   */
7817         /* into this byte completely or if length is */
7818         /* less than a byte                          */
7819         if ((shCnt = SPEC_BSTR(etype)) || 
7820                 (SPEC_BLEN(etype) <= 8))  {
7821                 
7822                 /* shift right acc */
7823                 AccRsh(shCnt);
7824                 
7825                 pic14_emitcode("anl","a,#0x%02x",
7826                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7827                 aopPut(AOP(result),"a",offset);
7828                 return ;
7829         }
7830         
7831         /* bit field did not fit in a byte  */
7832         rlen = SPEC_BLEN(etype) - 8;
7833         aopPut(AOP(result),"a",offset++);
7834         
7835         while (1)  {
7836                 
7837                 switch (ptype) {
7838                 case POINTER:
7839                 case IPOINTER:
7840                         pic14_emitcode("inc","%s",rname);
7841                         pic14_emitcode("mov","a,@%s",rname);
7842                         break;
7843                         
7844                 case PPOINTER:
7845                         pic14_emitcode("inc","%s",rname);
7846                         pic14_emitcode("movx","a,@%s",rname);
7847                         break;
7848                         
7849                 case FPOINTER:
7850                         pic14_emitcode("inc","dptr");
7851                         pic14_emitcode("movx","a,@dptr");
7852                         break;
7853                         
7854                 case CPOINTER:
7855                         pic14_emitcode("clr","a");
7856                         pic14_emitcode("inc","dptr");
7857                         pic14_emitcode("movc","a","@a+dptr");
7858                         break;
7859                         
7860                 case GPOINTER:
7861                         pic14_emitcode("inc","dptr");
7862                         pic14_emitcode("lcall","__gptrget");
7863                         break;
7864                 }
7865                 
7866                 rlen -= 8;            
7867                 /* if we are done */
7868                 if ( rlen <= 0 )
7869                         break ;
7870                 
7871                 aopPut(AOP(result),"a",offset++);
7872                 
7873         }
7874         
7875         if (rlen) {
7876                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7877                 aopPut(AOP(result),"a",offset);        
7878         }
7879         
7880         return ;
7881 }
7882
7883 #if 0
7884 /*-----------------------------------------------------------------*/
7885 /* genDataPointerGet - generates code when ptr offset is known     */
7886 /*-----------------------------------------------------------------*/
7887 static void genDataPointerGet (operand *left, 
7888                                                            operand *result, 
7889                                                            iCode *ic)
7890 {
7891         int size , offset = 0;
7892         
7893         
7894         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7895         
7896         
7897         /* optimization - most of the time, left and result are the same
7898         * address, but different types. for the pic code, we could omit
7899         * the following
7900         */
7901         
7902         aopOp(result,ic,TRUE);
7903         
7904         DEBUGpic14_AopType(__LINE__,left,NULL,result);
7905         
7906         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7907         
7908         size = AOP_SIZE(result);
7909         
7910         while (size--) {
7911                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7912                 offset++;
7913         }
7914         
7915         freeAsmop(left,NULL,ic,TRUE);
7916         freeAsmop(result,NULL,ic,TRUE);
7917 }
7918 #endif
7919 /*-----------------------------------------------------------------*/
7920 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7921 /*-----------------------------------------------------------------*/
7922 static void genNearPointerGet (operand *left, 
7923                                                            operand *result, 
7924                                                            iCode *ic)
7925 {
7926         asmop *aop = NULL;
7927         //regs *preg = NULL ;
7928         char *rname ;
7929         sym_link *rtype, *retype;
7930         sym_link *ltype = operandType(left);    
7931         //char buffer[80];
7932         
7933         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7934         
7935         rtype = operandType(result);
7936         retype= getSpec(rtype);
7937         
7938         aopOp(left,ic,FALSE);
7939         
7940         /* if left is rematerialisable and
7941         result is not bit variable type and
7942         the left is pointer to data space i.e
7943         lower 128 bytes of space */
7944         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7945                 !IS_BITVAR(retype)         &&
7946                 DCL_TYPE(ltype) == POINTER) {
7947                 //genDataPointerGet (left,result,ic);
7948                 return ;
7949         }
7950         
7951         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7952         
7953         /* if the value is already in a pointer register
7954         then don't need anything more */
7955         if (!AOP_INPREG(AOP(left))) {
7956                 /* otherwise get a free pointer register */
7957                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7958                 /*
7959                 aop = newAsmop(0);
7960                 preg = getFreePtr(ic,&aop,FALSE);
7961                 pic14_emitcode("mov","%s,%s",
7962                 preg->name,
7963                 aopGet(AOP(left),0,FALSE,TRUE));
7964                 rname = preg->name ;
7965                 */
7966                 rname ="BAD";
7967         } else
7968                 rname = aopGet(AOP(left),0,FALSE,FALSE);
7969         
7970         aopOp (result,ic,FALSE);
7971         
7972         /* if bitfield then unpack the bits */
7973         if (IS_BITFIELD(retype)) 
7974                 genUnpackBits (result,rname,POINTER);
7975         else {
7976                 /* we have can just get the values */
7977                 int size = AOP_SIZE(result);
7978                 int offset = 0 ;  
7979                 
7980                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7981                 
7982                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7983                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7984                 while(size--) {
7985                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7986                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7987                         if(size)
7988                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7989                 }
7990                 /*
7991                 while (size--) {
7992                 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7993                 
7994                   pic14_emitcode("mov","a,@%s",rname);
7995                   aopPut(AOP(result),"a",offset);
7996                   } else {
7997                   sprintf(buffer,"@%s",rname);
7998                   aopPut(AOP(result),buffer,offset);
7999                   }
8000                   offset++ ;
8001                   if (size)
8002                   pic14_emitcode("inc","%s",rname);
8003                   }
8004                 */
8005         }
8006         
8007         /* now some housekeeping stuff */
8008         if (aop) {
8009                 /* we had to allocate for this iCode */
8010                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8011                 freeAsmop(NULL,aop,ic,TRUE);
8012         } else { 
8013         /* we did not allocate which means left
8014         already in a pointer register, then
8015         if size > 0 && this could be used again
8016         we have to point it back to where it 
8017                 belongs */
8018                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8019                 if (AOP_SIZE(result) > 1 &&
8020                         !OP_SYMBOL(left)->remat &&
8021                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8022                         ic->depth )) {
8023                         int size = AOP_SIZE(result) - 1;
8024                         while (size--)
8025                                 pic14_emitcode("dec","%s",rname);
8026                 }
8027         }
8028         
8029         /* done */
8030         freeAsmop(left,NULL,ic,TRUE);
8031         freeAsmop(result,NULL,ic,TRUE);
8032         
8033 }
8034
8035 /*-----------------------------------------------------------------*/
8036 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8037 /*-----------------------------------------------------------------*/
8038 static void genPagedPointerGet (operand *left, 
8039                                                                 operand *result, 
8040                                                                 iCode *ic)
8041 {
8042         asmop *aop = NULL;
8043         regs *preg = NULL ;
8044         char *rname ;
8045         sym_link *rtype, *retype;    
8046         
8047         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8048         
8049         rtype = operandType(result);
8050         retype= getSpec(rtype);
8051         
8052         aopOp(left,ic,FALSE);
8053         
8054         /* if the value is already in a pointer register
8055         then don't need anything more */
8056         if (!AOP_INPREG(AOP(left))) {
8057                 /* otherwise get a free pointer register */
8058                 aop = newAsmop(0);
8059                 preg = getFreePtr(ic,&aop,FALSE);
8060                 pic14_emitcode("mov","%s,%s",
8061                         preg->name,
8062                         aopGet(AOP(left),0,FALSE,TRUE));
8063                 rname = preg->name ;
8064         } else
8065                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8066         
8067         freeAsmop(left,NULL,ic,TRUE);
8068         aopOp (result,ic,FALSE);
8069         
8070         /* if bitfield then unpack the bits */
8071         if (IS_BITFIELD(retype)) 
8072                 genUnpackBits (result,rname,PPOINTER);
8073         else {
8074                 /* we have can just get the values */
8075                 int size = AOP_SIZE(result);
8076                 int offset = 0 ;  
8077                 
8078                 while (size--) {
8079                         
8080                         pic14_emitcode("movx","a,@%s",rname);
8081                         aopPut(AOP(result),"a",offset);
8082                         
8083                         offset++ ;
8084                         
8085                         if (size)
8086                                 pic14_emitcode("inc","%s",rname);
8087                 }
8088         }
8089         
8090         /* now some housekeeping stuff */
8091         if (aop) {
8092                 /* we had to allocate for this iCode */
8093                 freeAsmop(NULL,aop,ic,TRUE);
8094         } else { 
8095         /* we did not allocate which means left
8096         already in a pointer register, then
8097         if size > 0 && this could be used again
8098         we have to point it back to where it 
8099                 belongs */
8100                 if (AOP_SIZE(result) > 1 &&
8101                         !OP_SYMBOL(left)->remat &&
8102                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8103                         ic->depth )) {
8104                         int size = AOP_SIZE(result) - 1;
8105                         while (size--)
8106                                 pic14_emitcode("dec","%s",rname);
8107                 }
8108         }
8109         
8110         /* done */
8111         freeAsmop(result,NULL,ic,TRUE);
8112         
8113         
8114 }
8115
8116 /*-----------------------------------------------------------------*/
8117 /* genFarPointerGet - gget value from far space                    */
8118 /*-----------------------------------------------------------------*/
8119 static void genFarPointerGet (operand *left,
8120                                                           operand *result, iCode *ic)
8121 {
8122         int size, offset ;
8123         sym_link *retype = getSpec(operandType(result));
8124         
8125         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8126         
8127         aopOp(left,ic,FALSE);
8128         
8129         /* if the operand is already in dptr 
8130         then we do nothing else we move the value to dptr */
8131         if (AOP_TYPE(left) != AOP_STR) {
8132                 /* if this is remateriazable */
8133                 if (AOP_TYPE(left) == AOP_IMMD)
8134                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8135                 else { /* we need to get it byte by byte */
8136                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8137                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8138                         if (options.model == MODEL_FLAT24)
8139                         {
8140                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8141                         }
8142                 }
8143         }
8144         /* so dptr know contains the address */
8145         freeAsmop(left,NULL,ic,TRUE);
8146         aopOp(result,ic,FALSE);
8147         
8148         /* if bit then unpack */
8149         if (IS_BITFIELD(retype)) 
8150                 genUnpackBits(result,"dptr",FPOINTER);
8151         else {
8152                 size = AOP_SIZE(result);
8153                 offset = 0 ;
8154                 
8155                 while (size--) {
8156                         pic14_emitcode("movx","a,@dptr");
8157                         aopPut(AOP(result),"a",offset++);
8158                         if (size)
8159                                 pic14_emitcode("inc","dptr");
8160                 }
8161         }
8162         
8163         freeAsmop(result,NULL,ic,TRUE);
8164 }
8165 #if 0
8166 /*-----------------------------------------------------------------*/
8167 /* genCodePointerGet - get value from code space                  */
8168 /*-----------------------------------------------------------------*/
8169 static void genCodePointerGet (operand *left,
8170                                                            operand *result, iCode *ic)
8171 {
8172         int size, offset ;
8173         sym_link *retype = getSpec(operandType(result));
8174         
8175         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8176         
8177         aopOp(left,ic,FALSE);
8178         
8179         /* if the operand is already in dptr 
8180         then we do nothing else we move the value to dptr */
8181         if (AOP_TYPE(left) != AOP_STR) {
8182                 /* if this is remateriazable */
8183                 if (AOP_TYPE(left) == AOP_IMMD)
8184                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8185                 else { /* we need to get it byte by byte */
8186                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8187                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8188                         if (options.model == MODEL_FLAT24)
8189                         {
8190                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8191                         }
8192                 }
8193         }
8194         /* so dptr know contains the address */
8195         freeAsmop(left,NULL,ic,TRUE);
8196         aopOp(result,ic,FALSE);
8197         
8198         /* if bit then unpack */
8199         if (IS_BITFIELD(retype)) 
8200                 genUnpackBits(result,"dptr",CPOINTER);
8201         else {
8202                 size = AOP_SIZE(result);
8203                 offset = 0 ;
8204                 
8205                 while (size--) {
8206                         pic14_emitcode("clr","a");
8207                         pic14_emitcode("movc","a,@a+dptr");
8208                         aopPut(AOP(result),"a",offset++);
8209                         if (size)
8210                                 pic14_emitcode("inc","dptr");
8211                 }
8212         }
8213         
8214         freeAsmop(result,NULL,ic,TRUE);
8215 }
8216 #endif
8217 /*-----------------------------------------------------------------*/
8218 /* genGenPointerGet - gget value from generic pointer space        */
8219 /*-----------------------------------------------------------------*/
8220 static void genGenPointerGet (operand *left,
8221                                                           operand *result, iCode *ic)
8222 {
8223         int size, offset ;
8224         sym_link *retype = getSpec(operandType(result));
8225         
8226         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8227         aopOp(left,ic,FALSE);
8228         aopOp(result,ic,FALSE);
8229         
8230         
8231         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8232         
8233         /* if the operand is already in dptr 
8234         then we do nothing else we move the value to dptr */
8235         //  if (AOP_TYPE(left) != AOP_STR) {
8236         /* if this is remateriazable */
8237         if (AOP_TYPE(left) == AOP_IMMD) {
8238                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8239                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8240         }
8241         else { /* we need to get it byte by byte */
8242                 
8243                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8244                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8245                 
8246                 size = AOP_SIZE(result);
8247                 offset = 0 ;
8248                 
8249                 while(size--) {
8250                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8251                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8252                         if(size)
8253                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8254                 }
8255                 goto release;
8256         }
8257         //}
8258         /* so dptr know contains the address */
8259         
8260         /* if bit then unpack */
8261         //if (IS_BITFIELD(retype)) 
8262         //  genUnpackBits(result,"dptr",GPOINTER);
8263         
8264 release:
8265         freeAsmop(left,NULL,ic,TRUE);
8266         freeAsmop(result,NULL,ic,TRUE);
8267         
8268 }
8269
8270 /*-----------------------------------------------------------------*/
8271 /* genConstPointerGet - get value from const generic pointer space */
8272 /*-----------------------------------------------------------------*/
8273 static void genConstPointerGet (operand *left,
8274                                                                 operand *result, iCode *ic)
8275 {
8276         //sym_link *retype = getSpec(operandType(result));
8277         symbol *albl = newiTempLabel(NULL);
8278         symbol *blbl = newiTempLabel(NULL);
8279         PIC_OPCODE poc;
8280         pCodeOp *pcop;
8281         
8282         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8283         aopOp(left,ic,FALSE);
8284         aopOp(result,ic,FALSE);
8285         
8286         
8287         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8288         
8289         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8290         
8291         emitpcode(POC_CALL,popGetLabel(albl->key));
8292         pcop = popGetLabel(blbl->key);
8293         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8294         emitpcode(POC_GOTO,pcop);
8295         emitpLabel(albl->key);
8296         
8297         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8298         
8299         emitpcode(poc,popGet(AOP(left),1));
8300         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8301         emitpcode(poc,popGet(AOP(left),0));
8302         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8303         
8304         emitpLabel(blbl->key);
8305         
8306         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8307         
8308         
8309         freeAsmop(left,NULL,ic,TRUE);
8310         freeAsmop(result,NULL,ic,TRUE);
8311         
8312 }
8313 /*-----------------------------------------------------------------*/
8314 /* genPointerGet - generate code for pointer get                   */
8315 /*-----------------------------------------------------------------*/
8316 static void genPointerGet (iCode *ic)
8317 {
8318         operand *left, *result ;
8319         sym_link *type, *etype;
8320         int p_type;
8321         
8322         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8323         
8324         left = IC_LEFT(ic);
8325         result = IC_RESULT(ic) ;
8326         
8327         /* depending on the type of pointer we need to
8328         move it to the correct pointer register */
8329         type = operandType(left);
8330         etype = getSpec(type);
8331         
8332         if (IS_PTR_CONST(type))
8333                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8334         
8335         /* if left is of type of pointer then it is simple */
8336         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8337                 p_type = DCL_TYPE(type);
8338         else {
8339                 /* we have to go by the storage class */
8340                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8341                 
8342                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8343                 
8344                 if (SPEC_OCLS(etype)->codesp ) {
8345                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8346                         //p_type = CPOINTER ; 
8347                 }
8348                 else
8349                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8350                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8351                         /*p_type = FPOINTER ;*/ 
8352                         else
8353                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8354                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8355                                 /*        p_type = PPOINTER; */
8356                                 else
8357                                         if (SPEC_OCLS(etype) == idata )
8358                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8359                                         /*      p_type = IPOINTER; */
8360                                         else
8361                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8362                                         /*      p_type = POINTER ; */
8363         }
8364         
8365         /* now that we have the pointer type we assign
8366         the pointer values */
8367         switch (p_type) {
8368                 
8369         case POINTER: 
8370         case IPOINTER:
8371                 genNearPointerGet (left,result,ic);
8372                 break;
8373                 
8374         case PPOINTER:
8375                 genPagedPointerGet(left,result,ic);
8376                 break;
8377                 
8378         case FPOINTER:
8379                 genFarPointerGet (left,result,ic);
8380                 break;
8381                 
8382         case CPOINTER:
8383                 genConstPointerGet (left,result,ic);
8384                 //pic14_emitcodePointerGet (left,result,ic);
8385                 break;
8386                 
8387         case GPOINTER:
8388                 if (IS_PTR_CONST(type))
8389                         genConstPointerGet (left,result,ic);
8390                 else
8391                         genGenPointerGet (left,result,ic);
8392                 break;
8393         }
8394         
8395 }
8396
8397 /*-----------------------------------------------------------------*/
8398 /* genPackBits - generates code for packed bit storage             */
8399 /*-----------------------------------------------------------------*/
8400 static void genPackBits (sym_link    *etype ,
8401                                                  operand *right ,
8402                                                  char *rname, int p_type)
8403 {
8404         int shCount = 0 ;
8405         int offset = 0  ;
8406         int rLen = 0 ;
8407         int blen, bstr ;   
8408         char *l ;
8409         
8410         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8411         blen = SPEC_BLEN(etype);
8412         bstr = SPEC_BSTR(etype);
8413         
8414         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8415         MOVA(l);   
8416         
8417         /* if the bit lenth is less than or    */
8418         /* it exactly fits a byte then         */
8419         if (SPEC_BLEN(etype) <= 8 )  {
8420                 shCount = SPEC_BSTR(etype) ;
8421                 
8422                 /* shift left acc */
8423                 AccLsh(shCount);
8424                 
8425                 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8426                         
8427                         
8428                         switch (p_type) {
8429                         case POINTER:
8430                                 pic14_emitcode ("mov","b,a");
8431                                 pic14_emitcode("mov","a,@%s",rname);
8432                                 break;
8433                                 
8434                         case FPOINTER:
8435                                 pic14_emitcode ("mov","b,a");
8436                                 pic14_emitcode("movx","a,@dptr");
8437                                 break;
8438                                 
8439                         case GPOINTER:
8440                                 pic14_emitcode ("push","b");
8441                                 pic14_emitcode ("push","acc");
8442                                 pic14_emitcode ("lcall","__gptrget");
8443                                 pic14_emitcode ("pop","b");
8444                                 break;
8445                         }
8446                         
8447                         pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8448                                 ((unsigned char)(0xFF << (blen+bstr)) | 
8449                                 (unsigned char)(0xFF >> (8-bstr)) ) );
8450                         pic14_emitcode ("orl","a,b");
8451                         if (p_type == GPOINTER)
8452                                 pic14_emitcode("pop","b");
8453                 }
8454         }
8455         
8456         switch (p_type) {
8457         case POINTER:
8458                 pic14_emitcode("mov","@%s,a",rname);
8459                 break;
8460                 
8461         case FPOINTER:
8462                 pic14_emitcode("movx","@dptr,a");
8463                 break;
8464                 
8465         case GPOINTER:
8466                 DEBUGpic14_emitcode(";lcall","__gptrput");
8467                 break;
8468         }
8469         
8470         /* if we r done */
8471         if ( SPEC_BLEN(etype) <= 8 )
8472                 return ;
8473         
8474         pic14_emitcode("inc","%s",rname);
8475         rLen = SPEC_BLEN(etype) ;     
8476         
8477         /* now generate for lengths greater than one byte */
8478         while (1) {
8479                 
8480                 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8481                 
8482                 rLen -= 8 ;
8483                 if (rLen <= 0 )
8484                         break ;
8485                 
8486                 switch (p_type) {
8487                 case POINTER:
8488                         if (*l == '@') {
8489                                 MOVA(l);
8490                                 pic14_emitcode("mov","@%s,a",rname);
8491                         } else
8492                                 pic14_emitcode("mov","@%s,%s",rname,l);
8493                         break;
8494                         
8495                 case FPOINTER:
8496                         MOVA(l);
8497                         pic14_emitcode("movx","@dptr,a");
8498                         break;
8499                         
8500                 case GPOINTER:
8501                         MOVA(l);
8502                         DEBUGpic14_emitcode(";lcall","__gptrput");
8503                         break;  
8504                 }   
8505                 pic14_emitcode ("inc","%s",rname);
8506         }
8507         
8508         MOVA(l);
8509         
8510         /* last last was not complete */
8511         if (rLen)   {
8512                 /* save the byte & read byte */
8513                 switch (p_type) {
8514                 case POINTER:
8515                         pic14_emitcode ("mov","b,a");
8516                         pic14_emitcode("mov","a,@%s",rname);
8517                         break;
8518                         
8519                 case FPOINTER:
8520                         pic14_emitcode ("mov","b,a");
8521                         pic14_emitcode("movx","a,@dptr");
8522                         break;
8523                         
8524                 case GPOINTER:
8525                         pic14_emitcode ("push","b");
8526                         pic14_emitcode ("push","acc");
8527                         pic14_emitcode ("lcall","__gptrget");
8528                         pic14_emitcode ("pop","b");
8529                         break;
8530                 }
8531                 
8532                 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8533                 pic14_emitcode ("orl","a,b");
8534         }
8535         
8536         if (p_type == GPOINTER)
8537                 pic14_emitcode("pop","b");
8538         
8539         switch (p_type) {
8540                 
8541         case POINTER:
8542                 pic14_emitcode("mov","@%s,a",rname);
8543                 break;
8544                 
8545         case FPOINTER:
8546                 pic14_emitcode("movx","@dptr,a");
8547                 break;
8548                 
8549         case GPOINTER:
8550                 DEBUGpic14_emitcode(";lcall","__gptrput");
8551                 break;      
8552         }
8553 }
8554 /*-----------------------------------------------------------------*/
8555 /* genDataPointerSet - remat pointer to data space                 */
8556 /*-----------------------------------------------------------------*/
8557 static void genDataPointerSet(operand *right,
8558                                                           operand *result,
8559                                                           iCode *ic)
8560 {
8561         int size, offset = 0 ;
8562         char *l, buffer[256];
8563         
8564         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8565         aopOp(right,ic,FALSE);
8566         
8567         l = aopGet(AOP(result),0,FALSE,TRUE);
8568         size = AOP_SIZE(right);
8569         /*
8570         if ( AOP_TYPE(result) == AOP_PCODE) {
8571         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8572         AOP(result)->aopu.pcop->name,
8573         PCOI(AOP(result)->aopu.pcop)->offset);
8574         }
8575         */
8576         
8577         // tsd, was l+1 - the underline `_' prefix was being stripped
8578         while (size--) {
8579                 if (offset) {
8580                         sprintf(buffer,"(%s + %d)",l,offset);
8581                         fprintf(stderr,"oops  %s\n",buffer);
8582                 } else
8583                         sprintf(buffer,"%s",l);
8584                 
8585                 if (AOP_TYPE(right) == AOP_LIT) {
8586                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8587                         lit = lit >> (8*offset);
8588                         if(lit&0xff) {
8589                                 pic14_emitcode("movlw","%d",lit);
8590                                 pic14_emitcode("movwf","%s",buffer);
8591                                 
8592                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8593                                 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8594                                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8595                                 
8596                         } else {
8597                                 pic14_emitcode("clrf","%s",buffer);
8598                                 //emitpcode(POC_CLRF, popRegFromString(buffer));
8599                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
8600                         }
8601                 }else {
8602                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8603                         pic14_emitcode("movwf","%s",buffer);
8604                         
8605                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8606                         //emitpcode(POC_MOVWF, popRegFromString(buffer));
8607                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
8608                         
8609                 }
8610                 
8611                 offset++;
8612         }
8613         
8614         freeAsmop(right,NULL,ic,TRUE);
8615         freeAsmop(result,NULL,ic,TRUE);
8616 }
8617
8618 /*-----------------------------------------------------------------*/
8619 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8620 /*-----------------------------------------------------------------*/
8621 static void genNearPointerSet (operand *right,
8622                                                            operand *result, 
8623                                                            iCode *ic)
8624 {
8625         asmop *aop = NULL;
8626         char *l;
8627         sym_link *retype;
8628         sym_link *ptype = operandType(result);
8629         
8630         
8631         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8632         retype= getSpec(operandType(right));
8633         
8634         aopOp(result,ic,FALSE);
8635         
8636         
8637         /* if the result is rematerializable &
8638         in data space & not a bit variable */
8639         //if (AOP_TYPE(result) == AOP_IMMD &&
8640         if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8641                 DCL_TYPE(ptype) == POINTER   &&
8642                 !IS_BITFIELD(retype)) {
8643                 genDataPointerSet (right,result,ic);
8644                 freeAsmop(result,NULL,ic,TRUE);
8645                 return;
8646         }
8647         
8648         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8649         aopOp(right,ic,FALSE);
8650         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8651         
8652         /* if the value is already in a pointer register
8653         then don't need anything more */
8654         if (!AOP_INPREG(AOP(result))) {
8655                 /* otherwise get a free pointer register */
8656                 //aop = newAsmop(0);
8657                 //preg = getFreePtr(ic,&aop,FALSE);
8658                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8659                 //pic14_emitcode("mov","%s,%s",
8660                 //         preg->name,
8661                 //         aopGet(AOP(result),0,FALSE,TRUE));
8662                 //rname = preg->name ;
8663                 //pic14_emitcode("movwf","fsr");
8664                 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8665                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8666                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8667                 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8668                 goto release;
8669                 
8670         }// else
8671         //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8672         
8673         
8674         /* if bitfield then unpack the bits */
8675         if (IS_BITFIELD(retype)) {
8676                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8677                         "The programmer is obviously confused");
8678                 //genPackBits (retype,right,rname,POINTER);
8679                 exit(1);
8680         }
8681         else {
8682                 /* we have can just get the values */
8683                 int size = AOP_SIZE(right);
8684                 int offset = 0 ;    
8685                 
8686                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8687                 while (size--) {
8688                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8689                         if (*l == '@' ) {
8690                                 //MOVA(l);
8691                                 //pic14_emitcode("mov","@%s,a",rname);
8692                                 pic14_emitcode("movf","indf,w ;1");
8693                         } else {
8694                                 
8695                                 if (AOP_TYPE(right) == AOP_LIT) {
8696                                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8697                                         if(lit) {
8698                                                 pic14_emitcode("movlw","%s",l);
8699                                                 pic14_emitcode("movwf","indf ;2");
8700                                         } else 
8701                                                 pic14_emitcode("clrf","indf");
8702                                 }else {
8703                                         pic14_emitcode("movf","%s,w",l);
8704                                         pic14_emitcode("movwf","indf ;2");
8705                                 }
8706                                 //pic14_emitcode("mov","@%s,%s",rname,l);
8707                         }
8708                         if (size)
8709                                 pic14_emitcode("incf","fsr,f ;3");
8710                         //pic14_emitcode("inc","%s",rname);
8711                         offset++;
8712                 }
8713         }
8714         
8715         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8716         /* now some housekeeping stuff */
8717         if (aop) {
8718                 /* we had to allocate for this iCode */
8719                 freeAsmop(NULL,aop,ic,TRUE);
8720         } else { 
8721         /* we did not allocate which means left
8722         already in a pointer register, then
8723         if size > 0 && this could be used again
8724         we have to point it back to where it 
8725                 belongs */
8726                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8727                 if (AOP_SIZE(right) > 1 &&
8728                         !OP_SYMBOL(result)->remat &&
8729                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8730                         ic->depth )) {
8731                         int size = AOP_SIZE(right) - 1;
8732                         while (size--)
8733                                 pic14_emitcode("decf","fsr,f");
8734                         //pic14_emitcode("dec","%s",rname);
8735                 }
8736         }
8737         
8738         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8739         /* done */
8740 release:
8741         freeAsmop(right,NULL,ic,TRUE);
8742         freeAsmop(result,NULL,ic,TRUE);
8743 }
8744
8745 /*-----------------------------------------------------------------*/
8746 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8747 /*-----------------------------------------------------------------*/
8748 static void genPagedPointerSet (operand *right,
8749                                                                 operand *result, 
8750                                                                 iCode *ic)
8751 {
8752         asmop *aop = NULL;
8753         regs *preg = NULL ;
8754         char *rname , *l;
8755         sym_link *retype;
8756         
8757         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8758         
8759         retype= getSpec(operandType(right));
8760         
8761         aopOp(result,ic,FALSE);
8762         
8763         /* if the value is already in a pointer register
8764         then don't need anything more */
8765         if (!AOP_INPREG(AOP(result))) {
8766                 /* otherwise get a free pointer register */
8767                 aop = newAsmop(0);
8768                 preg = getFreePtr(ic,&aop,FALSE);
8769                 pic14_emitcode("mov","%s,%s",
8770                         preg->name,
8771                         aopGet(AOP(result),0,FALSE,TRUE));
8772                 rname = preg->name ;
8773         } else
8774                 rname = aopGet(AOP(result),0,FALSE,FALSE);
8775         
8776         freeAsmop(result,NULL,ic,TRUE);
8777         aopOp (right,ic,FALSE);
8778         
8779         /* if bitfield then unpack the bits */
8780         if (IS_BITFIELD(retype)) 
8781                 genPackBits (retype,right,rname,PPOINTER);
8782         else {
8783                 /* we have can just get the values */
8784                 int size = AOP_SIZE(right);
8785                 int offset = 0 ;  
8786                 
8787                 while (size--) {
8788                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8789                         
8790                         MOVA(l);
8791                         pic14_emitcode("movx","@%s,a",rname);
8792                         
8793                         if (size)
8794                                 pic14_emitcode("inc","%s",rname);
8795                         
8796                         offset++;
8797                 }
8798         }
8799         
8800         /* now some housekeeping stuff */
8801         if (aop) {
8802                 /* we had to allocate for this iCode */
8803                 freeAsmop(NULL,aop,ic,TRUE);
8804         } else { 
8805         /* we did not allocate which means left
8806         already in a pointer register, then
8807         if size > 0 && this could be used again
8808         we have to point it back to where it 
8809                 belongs */
8810                 if (AOP_SIZE(right) > 1 &&
8811                         !OP_SYMBOL(result)->remat &&
8812                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8813                         ic->depth )) {
8814                         int size = AOP_SIZE(right) - 1;
8815                         while (size--)
8816                                 pic14_emitcode("dec","%s",rname);
8817                 }
8818         }
8819         
8820         /* done */
8821         freeAsmop(right,NULL,ic,TRUE);
8822         
8823         
8824 }
8825
8826 /*-----------------------------------------------------------------*/
8827 /* genFarPointerSet - set value from far space                     */
8828 /*-----------------------------------------------------------------*/
8829 static void genFarPointerSet (operand *right,
8830                                                           operand *result, iCode *ic)
8831 {
8832         int size, offset ;
8833         sym_link *retype = getSpec(operandType(right));
8834         
8835         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8836         aopOp(result,ic,FALSE);
8837         
8838         /* if the operand is already in dptr 
8839         then we do nothing else we move the value to dptr */
8840         if (AOP_TYPE(result) != AOP_STR) {
8841                 /* if this is remateriazable */
8842                 if (AOP_TYPE(result) == AOP_IMMD)
8843                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8844                 else { /* we need to get it byte by byte */
8845                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8846                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8847                         if (options.model == MODEL_FLAT24)
8848                         {
8849                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8850                         }
8851                 }
8852         }
8853         /* so dptr know contains the address */
8854         freeAsmop(result,NULL,ic,TRUE);
8855         aopOp(right,ic,FALSE);
8856         
8857         /* if bit then unpack */
8858         if (IS_BITFIELD(retype)) 
8859                 genPackBits(retype,right,"dptr",FPOINTER);
8860         else {
8861                 size = AOP_SIZE(right);
8862                 offset = 0 ;
8863                 
8864                 while (size--) {
8865                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8866                         MOVA(l);
8867                         pic14_emitcode("movx","@dptr,a");
8868                         if (size)
8869                                 pic14_emitcode("inc","dptr");
8870                 }
8871         }
8872         
8873         freeAsmop(right,NULL,ic,TRUE);
8874 }
8875
8876 /*-----------------------------------------------------------------*/
8877 /* genGenPointerSet - set value from generic pointer space         */
8878 /*-----------------------------------------------------------------*/
8879 static void genGenPointerSet (operand *right,
8880                                                           operand *result, iCode *ic)
8881 {
8882         int size, offset ;
8883         sym_link *retype = getSpec(operandType(right));
8884         
8885         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8886         
8887         aopOp(result,ic,FALSE);
8888         aopOp(right,ic,FALSE);
8889         size = AOP_SIZE(right);
8890         
8891         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8892         
8893         /* if the operand is already in dptr 
8894         then we do nothing else we move the value to dptr */
8895         if (AOP_TYPE(result) != AOP_STR) {
8896                 /* if this is remateriazable */
8897                 if (AOP_TYPE(result) == AOP_IMMD) {
8898                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8899                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8900                 }
8901                 else { /* we need to get it byte by byte */
8902                         //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8903                         size = AOP_SIZE(right);
8904                         offset = 0 ;
8905                         
8906                         /* hack hack! see if this the FSR. If so don't load W */
8907                         if(AOP_TYPE(right) != AOP_ACC) {
8908                                 
8909                                 
8910                                 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8911                                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8912                                 
8913                                 if(AOP_SIZE(result) > 1) {
8914                                         emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8915                                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8916                                         emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8917                                         
8918                                 }
8919                                 
8920                                 //if(size==2)
8921                                 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8922                                 //if(size==4) {
8923                                 //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8924                                 //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8925                                 //}
8926                                 
8927                                 while(size--) {
8928                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8929                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8930                                         
8931                                         if(size)
8932                                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8933                                 }
8934                                 
8935                                 
8936                                 goto release;
8937                         } 
8938                         
8939                         if(aopIdx(AOP(result),0) != 4) {
8940                                 
8941                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8942                                 goto release;
8943                         }
8944                         
8945                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8946                         goto release;
8947                         
8948                 }
8949         }
8950         /* so dptr know contains the address */
8951         
8952         
8953         /* if bit then unpack */
8954         if (IS_BITFIELD(retype)) 
8955                 genPackBits(retype,right,"dptr",GPOINTER);
8956         else {
8957                 size = AOP_SIZE(right);
8958                 offset = 0 ;
8959                 
8960                 DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8961                 
8962                 while (size--) {
8963                         
8964                         emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8965                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8966                         
8967                         if (AOP_TYPE(right) == AOP_LIT) 
8968                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8969                         else
8970                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8971                         
8972                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8973                         
8974                         offset++;
8975                 }
8976         }
8977         
8978 release:
8979         freeAsmop(right,NULL,ic,TRUE);
8980         freeAsmop(result,NULL,ic,TRUE);
8981 }
8982
8983 /*-----------------------------------------------------------------*/
8984 /* genPointerSet - stores the value into a pointer location        */
8985 /*-----------------------------------------------------------------*/
8986 static void genPointerSet (iCode *ic)
8987 {    
8988         operand *right, *result ;
8989         sym_link *type, *etype;
8990         int p_type;
8991         
8992         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8993         
8994         right = IC_RIGHT(ic);
8995         result = IC_RESULT(ic) ;
8996         
8997         /* depending on the type of pointer we need to
8998         move it to the correct pointer register */
8999         type = operandType(result);
9000         etype = getSpec(type);
9001         /* if left is of type of pointer then it is simple */
9002         if (IS_PTR(type) && !IS_FUNC(type->next)) {
9003                 p_type = DCL_TYPE(type);
9004         }
9005         else {
9006                 /* we have to go by the storage class */
9007                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9008                 
9009                 /*  if (SPEC_OCLS(etype)->codesp ) { */
9010                 /*      p_type = CPOINTER ;  */
9011                 /*  } */
9012                 /*  else */
9013                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9014                 /*    p_type = FPOINTER ; */
9015                 /*      else */
9016                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9017                 /*        p_type = PPOINTER ; */
9018                 /*    else */
9019                 /*        if (SPEC_OCLS(etype) == idata ) */
9020                 /*      p_type = IPOINTER ; */
9021                 /*        else */
9022                 /*      p_type = POINTER ; */
9023         }
9024         
9025         /* now that we have the pointer type we assign
9026         the pointer values */
9027         switch (p_type) {
9028                 
9029         case POINTER:
9030         case IPOINTER:
9031                 genNearPointerSet (right,result,ic);
9032                 break;
9033                 
9034         case PPOINTER:
9035                 genPagedPointerSet (right,result,ic);
9036                 break;
9037                 
9038         case FPOINTER:
9039                 genFarPointerSet (right,result,ic);
9040                 break;
9041                 
9042         case GPOINTER:
9043                 genGenPointerSet (right,result,ic);
9044                 break;
9045                 
9046         default:
9047                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9048                         "genPointerSet: illegal pointer type");
9049         }
9050 }
9051
9052 /*-----------------------------------------------------------------*/
9053 /* genIfx - generate code for Ifx statement                        */
9054 /*-----------------------------------------------------------------*/
9055 static void genIfx (iCode *ic, iCode *popIc)
9056 {
9057         operand *cond = IC_COND(ic);
9058         int isbit =0;
9059         
9060         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9061         
9062         aopOp(cond,ic,FALSE);
9063         
9064         /* get the value into acc */
9065         if (AOP_TYPE(cond) != AOP_CRY)
9066                 pic14_toBoolean(cond);
9067         else
9068                 isbit = 1;
9069         /* the result is now in the accumulator */
9070         freeAsmop(cond,NULL,ic,TRUE);
9071         
9072         /* if there was something to be popped then do it */
9073         if (popIc)
9074                 genIpop(popIc);
9075         
9076         /* if the condition is  a bit variable */
9077         if (isbit && IS_ITEMP(cond) && 
9078                 SPIL_LOC(cond)) {
9079                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9080                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9081         }
9082         else {
9083                 if (isbit && !IS_ITEMP(cond))
9084                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9085                 else
9086                         genIfxJump(ic,"a");
9087         }
9088         ic->generated = 1;
9089         
9090 }
9091
9092 /*-----------------------------------------------------------------*/
9093 /* genAddrOf - generates code for address of                       */
9094 /*-----------------------------------------------------------------*/
9095 static void genAddrOf (iCode *ic)
9096 {
9097         operand *right, *result, *left;
9098         int size, offset ;
9099         
9100         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9101         
9102         
9103         //aopOp(IC_RESULT(ic),ic,FALSE);
9104         
9105         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9106         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9107         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9108         
9109         DEBUGpic14_AopType(__LINE__,left,right,result);
9110         
9111         size = AOP_SIZE(IC_RESULT(ic));
9112         offset = 0;
9113         
9114         while (size--) {
9115                 /* fixing bug #863624, reported from (errolv) */
9116                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9117                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9118                 
9119 #if 0
9120                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9121                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9122 #endif
9123                 offset++;
9124         }
9125         
9126         freeAsmop(left,NULL,ic,FALSE);
9127         freeAsmop(result,NULL,ic,TRUE);
9128         
9129 }
9130
9131 #if 0
9132 /*-----------------------------------------------------------------*/
9133 /* genFarFarAssign - assignment when both are in far space         */
9134 /*-----------------------------------------------------------------*/
9135 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9136 {
9137         int size = AOP_SIZE(right);
9138         int offset = 0;
9139         char *l ;
9140         /* first push the right side on to the stack */
9141         while (size--) {
9142                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9143                 MOVA(l);
9144                 pic14_emitcode ("push","acc");
9145         }
9146         
9147         freeAsmop(right,NULL,ic,FALSE);
9148         /* now assign DPTR to result */
9149         aopOp(result,ic,FALSE);
9150         size = AOP_SIZE(result);
9151         while (size--) {
9152                 pic14_emitcode ("pop","acc");
9153                 aopPut(AOP(result),"a",--offset);
9154         }
9155         freeAsmop(result,NULL,ic,FALSE);
9156         
9157 }
9158 #endif
9159
9160 /*-----------------------------------------------------------------*/
9161 /* genAssign - generate code for assignment                        */
9162 /*-----------------------------------------------------------------*/
9163 static void genAssign (iCode *ic)
9164 {
9165         operand *result, *right;
9166         int size, offset,know_W;
9167         unsigned long lit = 0L;
9168         
9169         result = IC_RESULT(ic);
9170         right  = IC_RIGHT(ic) ;
9171         
9172         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9173         
9174         /* if they are the same */
9175         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9176                 return ;
9177         
9178         aopOp(right,ic,FALSE);
9179         aopOp(result,ic,TRUE);
9180         
9181         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9182         
9183         /* if they are the same registers */
9184         if (pic14_sameRegs(AOP(right),AOP(result)))
9185                 goto release;
9186         
9187         /* if the result is a bit */
9188         if (AOP_TYPE(result) == AOP_CRY) {
9189                 
9190         /* if the right size is a literal then
9191                 we know what the value is */
9192                 if (AOP_TYPE(right) == AOP_LIT) {
9193                         
9194                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9195                                 popGet(AOP(result),0));
9196                         
9197                         if (((int) operandLitValue(right))) 
9198                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9199                                 AOP(result)->aopu.aop_dir,
9200                                 AOP(result)->aopu.aop_dir);
9201                         else
9202                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9203                                 AOP(result)->aopu.aop_dir,
9204                                 AOP(result)->aopu.aop_dir);
9205                         goto release;
9206                 }
9207                 
9208                 /* the right is also a bit variable */
9209                 if (AOP_TYPE(right) == AOP_CRY) {
9210                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9211                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9212                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9213                         
9214                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9215                                 AOP(result)->aopu.aop_dir,
9216                                 AOP(result)->aopu.aop_dir);
9217                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9218                                 AOP(right)->aopu.aop_dir,
9219                                 AOP(right)->aopu.aop_dir);
9220                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9221                                 AOP(result)->aopu.aop_dir,
9222                                 AOP(result)->aopu.aop_dir);
9223                         goto release ;
9224                 }
9225                 
9226                 /* we need to or */
9227                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9228                 pic14_toBoolean(right);
9229                 emitSKPZ;
9230                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9231                 //aopPut(AOP(result),"a",0);
9232                 goto release ;
9233         }
9234         
9235         /* bit variables done */
9236         /* general case */
9237         size = AOP_SIZE(result);
9238         offset = 0 ;
9239         if(AOP_TYPE(right) == AOP_LIT)
9240                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9241         
9242         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9243                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9244                 if(aopIdx(AOP(result),0) == 4) {
9245                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9246                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9247                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9248                         goto release;
9249                 } else
9250                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9251         }
9252         
9253         know_W=-1;
9254         while (size--) {
9255                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9256                 if(AOP_TYPE(right) == AOP_LIT) {
9257                         if(lit&0xff) {
9258                                 if(know_W != (int)(lit&0xff))
9259                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9260                                 know_W = lit&0xff;
9261                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9262                         } else
9263                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9264                         
9265                         lit >>= 8;
9266                         
9267                 } else if (AOP_TYPE(right) == AOP_CRY) {
9268                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9269                         if(offset == 0) {
9270                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9271                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9272                         }
9273                 } else {
9274                         mov2w (AOP(right), offset);
9275                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9276                 }
9277                 
9278                 offset++;
9279         }
9280         
9281         
9282 release:
9283         freeAsmop (right,NULL,ic,FALSE);
9284         freeAsmop (result,NULL,ic,TRUE);
9285 }   
9286
9287 /*-----------------------------------------------------------------*/
9288 /* genJumpTab - genrates code for jump table                       */
9289 /*-----------------------------------------------------------------*/
9290 static void genJumpTab (iCode *ic)
9291 {
9292         symbol *jtab;
9293         char *l;
9294         
9295         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9296         
9297         aopOp(IC_JTCOND(ic),ic,FALSE);
9298         /* get the condition into accumulator */
9299         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9300         MOVA(l);
9301         /* multiply by three */
9302         pic14_emitcode("add","a,acc");
9303         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9304         
9305         jtab = newiTempLabel(NULL);
9306         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9307         pic14_emitcode("jmp","@a+dptr");
9308         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9309         
9310         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9311         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9312         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9313         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9314         emitSKPNC;
9315         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9316         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9317         emitpLabel(jtab->key);
9318         
9319         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9320         
9321         /* now generate the jump labels */
9322         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9323         jtab = setNextItem(IC_JTLABELS(ic))) {
9324                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9325                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9326                 
9327         }
9328         
9329 }
9330
9331 /*-----------------------------------------------------------------*/
9332 /* genMixedOperation - gen code for operators between mixed types  */
9333 /*-----------------------------------------------------------------*/
9334 /*
9335 TSD - Written for the PIC port - but this unfortunately is buggy.
9336 This routine is good in that it is able to efficiently promote 
9337 types to different (larger) sizes. Unfortunately, the temporary
9338 variables that are optimized out by this routine are sometimes
9339 used in other places. So until I know how to really parse the 
9340 iCode tree, I'm going to not be using this routine :(.
9341 */
9342 static int genMixedOperation (iCode *ic)
9343 {
9344 #if 0
9345         operand *result = IC_RESULT(ic);
9346         sym_link *ctype = operandType(IC_LEFT(ic));
9347         operand *right = IC_RIGHT(ic);
9348         int ret = 0;
9349         int big,small;
9350         int offset;
9351         
9352         iCode *nextic;
9353         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9354         
9355         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9356         
9357         nextic = ic->next;
9358         if(!nextic)
9359                 return 0;
9360         
9361         nextright = IC_RIGHT(nextic);
9362         nextleft  = IC_LEFT(nextic);
9363         nextresult = IC_RESULT(nextic);
9364         
9365         aopOp(right,ic,FALSE);
9366         aopOp(result,ic,FALSE);
9367         aopOp(nextright,  nextic, FALSE);
9368         aopOp(nextleft,   nextic, FALSE);
9369         aopOp(nextresult, nextic, FALSE);
9370         
9371         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9372                 
9373                 operand *t = right;
9374                 right = nextright;
9375                 nextright = t; 
9376                 
9377                 pic14_emitcode(";remove right +","");
9378                 
9379         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9380         /*
9381         operand *t = right;
9382         right = nextleft;
9383         nextleft = t; 
9384                 */
9385                 pic14_emitcode(";remove left +","");
9386         } else
9387                 return 0;
9388         
9389         big = AOP_SIZE(nextleft);
9390         small = AOP_SIZE(nextright);
9391         
9392         switch(nextic->op) {
9393                 
9394         case '+':
9395                 pic14_emitcode(";optimize a +","");
9396                 /* if unsigned or not an integral type */
9397                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9398                         pic14_emitcode(";add a bit to something","");
9399                 } else {
9400                         
9401                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9402                         
9403                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9404                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9405                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9406                         } else
9407                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9408                         
9409                         offset = 0;
9410                         while(--big) {
9411                                 
9412                                 offset++;
9413                                 
9414                                 if(--small) {
9415                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9416                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9417                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9418                                         }
9419                                         
9420                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9421                                         emitSKPNC;
9422                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9423                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9424                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9425                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9426                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9427                                         
9428                                 } else {
9429                                         pic14_emitcode("rlf","known_zero,w");
9430                                         
9431                                         /*
9432                                         if right is signed
9433                                         btfsc  right,7
9434                                         addlw ff
9435                                         */
9436                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9437                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9438                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9439                                         } else {
9440                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9441                                         }
9442                                 }
9443                         }
9444                         ret = 1;
9445                 }
9446         }
9447         ret = 1;
9448         
9449 release:
9450         freeAsmop(right,NULL,ic,TRUE);
9451         freeAsmop(result,NULL,ic,TRUE);
9452         freeAsmop(nextright,NULL,ic,TRUE);
9453         freeAsmop(nextleft,NULL,ic,TRUE);
9454         if(ret)
9455                 nextic->generated = 1;
9456         
9457         return ret;
9458 #else
9459         return 0;
9460 #endif
9461 }
9462 /*-----------------------------------------------------------------*/
9463 /* genCast - gen code for casting                                  */
9464 /*-----------------------------------------------------------------*/
9465 static void genCast (iCode *ic)
9466 {
9467         operand *result = IC_RESULT(ic);
9468         sym_link *ctype = operandType(IC_LEFT(ic));
9469         sym_link *rtype = operandType(IC_RIGHT(ic));
9470         operand *right = IC_RIGHT(ic);
9471         int size, offset ;
9472         
9473         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9474         /* if they are equivalent then do nothing */
9475         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9476                 return ;
9477         
9478         aopOp(right,ic,FALSE) ;
9479         aopOp(result,ic,FALSE);
9480         
9481         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9482         
9483         /* if the result is a bit */
9484         if (AOP_TYPE(result) == AOP_CRY) {
9485         /* if the right size is a literal then
9486                 we know what the value is */
9487                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9488                 if (AOP_TYPE(right) == AOP_LIT) {
9489                         
9490                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9491                                 popGet(AOP(result),0));
9492                         
9493                         if (((int) operandLitValue(right))) 
9494                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9495                                 AOP(result)->aopu.aop_dir,
9496                                 AOP(result)->aopu.aop_dir);
9497                         else
9498                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9499                                 AOP(result)->aopu.aop_dir,
9500                                 AOP(result)->aopu.aop_dir);
9501                         
9502                         goto release;
9503                 }
9504                 
9505                 /* the right is also a bit variable */
9506                 if (AOP_TYPE(right) == AOP_CRY) {
9507                         
9508                         emitCLRC;
9509                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9510                         
9511                         pic14_emitcode("clrc","");
9512                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9513                                 AOP(right)->aopu.aop_dir,
9514                                 AOP(right)->aopu.aop_dir);
9515                         aopPut(AOP(result),"c",0);
9516                         goto release ;
9517                 }
9518                 
9519                 /* we need to or */
9520                 if (AOP_TYPE(right) == AOP_REG) {
9521                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9522                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9523                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9524                 }
9525                 pic14_toBoolean(right);
9526                 aopPut(AOP(result),"a",0);
9527                 goto release ;
9528         }
9529         
9530         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9531                 int offset = 1;
9532                 size = AOP_SIZE(result);
9533                 
9534                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9535                 
9536                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9537                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9538                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9539                 
9540                 while (size--)
9541                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9542                 
9543                 goto release;
9544         }
9545         
9546         /* if they are the same size : or less */
9547         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9548                 
9549                 /* if they are in the same place */
9550                 if (pic14_sameRegs(AOP(right),AOP(result)))
9551                         goto release;
9552                 
9553                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9554                 if (IS_PTR_CONST(rtype))
9555                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9556                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9557                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9558                 
9559                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9560                         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9561                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9562                         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9563                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9564                         if(AOP_SIZE(result) <2)
9565                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9566                         
9567                 } else {
9568                         
9569                         /* if they in different places then copy */
9570                         size = AOP_SIZE(result);
9571                         offset = 0 ;
9572                         while (size--) {
9573                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9574                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9575                                 
9576                                 //aopPut(AOP(result),
9577                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9578                                 // offset);
9579                                 
9580                                 offset++;
9581                         }
9582                 }
9583                 goto release;
9584         }
9585         
9586         
9587         /* if the result is of type pointer */
9588         if (IS_PTR(ctype)) {
9589                 
9590                 int p_type;
9591                 sym_link *type = operandType(right);
9592                 sym_link *etype = getSpec(type);
9593                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9594                 
9595                 /* pointer to generic pointer */
9596                 if (IS_GENPTR(ctype)) {
9597                         char *l = zero;
9598                         
9599                         if (IS_PTR(type)) 
9600                                 p_type = DCL_TYPE(type);
9601                         else {
9602                                 /* we have to go by the storage class */
9603                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9604                                 
9605                                 /*    if (SPEC_OCLS(etype)->codesp )  */
9606                                 /*        p_type = CPOINTER ;  */
9607                                 /*    else */
9608                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9609                                 /*      p_type = FPOINTER ; */
9610                                 /*        else */
9611                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9612                                 /*          p_type = PPOINTER; */
9613                                 /*      else */
9614                                 /*          if (SPEC_OCLS(etype) == idata ) */
9615                                 /*        p_type = IPOINTER ; */
9616                                 /*          else */
9617                                 /*        p_type = POINTER ; */
9618                         }
9619                         
9620                         /* the first two bytes are known */
9621                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9622                         size = GPTRSIZE - 1; 
9623                         offset = 0 ;
9624                         while (size--) {
9625                                 if(offset < AOP_SIZE(right)) {
9626                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9627                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9628                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9629                                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9630                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9631                                         } else { 
9632                                                 aopPut(AOP(result),
9633                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9634                                                         offset);
9635                                         }
9636                                 } else 
9637                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9638                                 offset++;
9639                         }
9640                         /* the last byte depending on type */
9641                         switch (p_type) {
9642                         case IPOINTER:
9643                         case POINTER:
9644                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9645                                 break;
9646                         case FPOINTER:
9647                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9648                                 l = one;
9649                                 break;
9650                         case CPOINTER:
9651                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9652                                 l = "#0x02";
9653                                 break;        
9654                         case PPOINTER:
9655                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9656                                 l = "#0x03";
9657                                 break;
9658                                 
9659                         default:
9660                                 /* this should never happen */
9661                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9662                                         "got unknown pointer type");
9663                                 exit(1);
9664                         }
9665                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9666                         goto release ;
9667                 }
9668                 
9669                 /* just copy the pointers */
9670                 size = AOP_SIZE(result);
9671                 offset = 0 ;
9672                 while (size--) {
9673                         aopPut(AOP(result),
9674                                 aopGet(AOP(right),offset,FALSE,FALSE),
9675                                 offset);
9676                         offset++;
9677                 }
9678                 goto release ;
9679         }
9680         
9681         
9682         
9683         /* so we now know that the size of destination is greater
9684         than the size of the source.
9685         Now, if the next iCode is an operator then we might be
9686         able to optimize the operation without performing a cast.
9687         */
9688         if(genMixedOperation(ic))
9689                 goto release;
9690         
9691         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9692         
9693         /* we move to result for the size of source */
9694         size = AOP_SIZE(right);
9695         offset = 0 ;
9696         while (size--) {
9697                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9698                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9699                 offset++;
9700         }
9701         
9702         /* now depending on the sign of the destination */
9703         size = AOP_SIZE(result) - AOP_SIZE(right);
9704         /* if unsigned or not an integral type */
9705         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9706                 while (size--)
9707                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9708         } else {
9709                 /* we need to extend the sign :{ */
9710                 
9711                 if(size == 1) {
9712                         /* Save one instruction of casting char to int */
9713                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9714                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9715                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9716                 } else {
9717                         emitpcodeNULLop(POC_CLRW);
9718                         
9719                         if(offset)
9720                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9721                         else
9722                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9723                         
9724                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9725                         
9726                         while (size--)
9727                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9728                 }
9729         }
9730         
9731 release:
9732         freeAsmop(right,NULL,ic,TRUE);
9733         freeAsmop(result,NULL,ic,TRUE);
9734         
9735 }
9736
9737 /*-----------------------------------------------------------------*/
9738 /* genDjnz - generate decrement & jump if not zero instrucion      */
9739 /*-----------------------------------------------------------------*/
9740 static int genDjnz (iCode *ic, iCode *ifx)
9741 {
9742         symbol *lbl, *lbl1;
9743         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9744         
9745         if (!ifx)
9746                 return 0;
9747         
9748                 /* if the if condition has a false label
9749         then we cannot save */
9750         if (IC_FALSE(ifx))
9751                 return 0;
9752         
9753                 /* if the minus is not of the form 
9754         a = a - 1 */
9755         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9756                 !IS_OP_LITERAL(IC_RIGHT(ic)))
9757                 return 0;
9758         
9759         if (operandLitValue(IC_RIGHT(ic)) != 1)
9760                 return 0;
9761         
9762                 /* if the size of this greater than one then no
9763         saving */
9764         if (getSize(operandType(IC_RESULT(ic))) > 1)
9765                 return 0;
9766         
9767         /* otherwise we can save BIG */
9768         lbl = newiTempLabel(NULL);
9769         lbl1= newiTempLabel(NULL);
9770         
9771         aopOp(IC_RESULT(ic),ic,FALSE);
9772         
9773         if (IS_AOP_PREG(IC_RESULT(ic))) {
9774                 pic14_emitcode("dec","%s",
9775                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9776                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9777                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9778         } else {  
9779                 
9780                 
9781                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9782                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9783                 
9784                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9785                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9786                 
9787         }
9788         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9789         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9790         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9791         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9792         
9793         
9794         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9795         ifx->generated = 1;
9796         return 1;
9797 }
9798
9799 /*-----------------------------------------------------------------*/
9800 /* genReceive - generate code for a receive iCode                  */
9801 /*-----------------------------------------------------------------*/
9802 static void genReceive (iCode *ic)
9803 {
9804         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9805         
9806         if (isOperandInFarSpace(IC_RESULT(ic)) &&
9807                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9808                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9809                 
9810                 int size = getSize(operandType(IC_RESULT(ic)));
9811                 int offset =  fReturnSizePic - size;
9812                 while (size--) {
9813                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9814                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
9815                         offset++;
9816                 }
9817                 aopOp(IC_RESULT(ic),ic,FALSE);
9818                 size = AOP_SIZE(IC_RESULT(ic));
9819                 offset = 0;
9820                 while (size--) {
9821                         pic14_emitcode ("pop","acc");
9822                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9823                 }
9824                 
9825         } else {
9826                 _G.accInUse++;
9827                 aopOp(IC_RESULT(ic),ic,FALSE);
9828                 _G.accInUse--;
9829                 assignResultValue(IC_RESULT(ic));
9830         }
9831         
9832         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9833 }
9834
9835 /*-----------------------------------------------------------------*/
9836 /* genDummyRead - generate code for dummy read of volatiles        */
9837 /*-----------------------------------------------------------------*/
9838 static void
9839 genDummyRead (iCode * ic)
9840 {
9841         pic14_emitcode ("; genDummyRead","");
9842         pic14_emitcode ("; not implemented","");
9843         
9844         ic = ic;
9845 }
9846
9847 /*-----------------------------------------------------------------*/
9848 /* genpic14Code - generate code for pic14 based controllers        */
9849 /*-----------------------------------------------------------------*/
9850 /*
9851 * At this point, ralloc.c has gone through the iCode and attempted
9852 * to optimize in a way suitable for a PIC. Now we've got to generate
9853 * PIC instructions that correspond to the iCode.
9854 *
9855 * Once the instructions are generated, we'll pass through both the
9856 * peep hole optimizer and the pCode optimizer.
9857 *-----------------------------------------------------------------*/
9858
9859 void genpic14Code (iCode *lic)
9860 {
9861         iCode *ic;
9862         int cln = 0;
9863         
9864         lineHead = lineCurr = NULL;
9865         
9866         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9867         addpBlock(pb);
9868         
9869         /* if debug information required */
9870         if (options.debug && currFunc) { 
9871                 if (currFunc) {
9872                         debugFile->writeFunction (currFunc, lic);
9873                 }
9874         }
9875         
9876         
9877         for (ic = lic ; ic ; ic = ic->next ) {
9878                 
9879                 DEBUGpic14_emitcode(";ic","");
9880                 if ( cln != ic->lineno ) {
9881                         if ( options.debug ) {
9882                                 debugFile->writeCLine (ic);
9883                         }
9884                         /*
9885                         pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9886                         pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9887                         printCLine(ic->filename, ic->lineno));
9888                         */
9889                         if (!options.noCcodeInAsm) {
9890                                 addpCode2pBlock(pb,
9891                                         newpCodeCSource(ic->lineno, 
9892                                         ic->filename, 
9893                                         printCLine(ic->filename, ic->lineno)));
9894                         }
9895                         
9896                         cln = ic->lineno ;
9897                 }
9898                 
9899                 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9900                 
9901                 /* if the result is marked as
9902                 spilt and rematerializable or code for
9903                 this has already been generated then
9904                 do nothing */
9905                 if (resultRemat(ic) || ic->generated ) 
9906                         continue ;
9907                 
9908                 /* depending on the operation */
9909                 switch (ic->op) {
9910                 case '!' :
9911                         genNot(ic);
9912                         break;
9913                         
9914                 case '~' :
9915                         genCpl(ic);
9916                         break;
9917                         
9918                 case UNARYMINUS:
9919                         genUminus (ic);
9920                         break;
9921                         
9922                 case IPUSH:
9923                         genIpush (ic);
9924                         break;
9925                         
9926                 case IPOP:
9927                 /* IPOP happens only when trying to restore a 
9928                 spilt live range, if there is an ifx statement
9929                 following this pop then the if statement might
9930                 be using some of the registers being popped which
9931                 would destory the contents of the register so
9932                 we need to check for this condition and handle it */
9933                         if (ic->next            && 
9934                                 ic->next->op == IFX &&
9935                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9936                                 genIfx (ic->next,ic);
9937                         else
9938                                 genIpop (ic);
9939                         break; 
9940                         
9941                 case CALL:
9942                         genCall (ic);
9943                         break;
9944                         
9945                 case PCALL:
9946                         genPcall (ic);
9947                         break;
9948                         
9949                 case FUNCTION:
9950                         genFunction (ic);
9951                         break;
9952                         
9953                 case ENDFUNCTION:
9954                         genEndFunction (ic);
9955                         break;
9956                         
9957                 case RETURN:
9958                         genRet (ic);
9959                         break;
9960                         
9961                 case LABEL:
9962                         genLabel (ic);
9963                         break;
9964                         
9965                 case GOTO:
9966                         genGoto (ic);
9967                         break;
9968                         
9969                 case '+' :
9970                         genPlus (ic) ;
9971                         break;
9972                         
9973                 case '-' :
9974                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9975                                 genMinus (ic);
9976                         break;
9977                         
9978                 case '*' :
9979                         genMult (ic);
9980                         break;
9981                         
9982                 case '/' :
9983                         genDiv (ic) ;
9984                         break;
9985                         
9986                 case '%' :
9987                         genMod (ic);
9988                         break;
9989                         
9990                 case '>' :
9991                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
9992                         break;
9993                         
9994                 case '<' :
9995                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9996                         break;
9997                         
9998                 case LE_OP:
9999                 case GE_OP:
10000                 case NE_OP:
10001                         
10002                 /* note these two are xlated by algebraic equivalence
10003                         during parsing SDCC.y */
10004                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10005                                 "got '>=' or '<=' shouldn't have come here");
10006                         break;  
10007                         
10008                 case EQ_OP:
10009                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10010                         break;      
10011                         
10012                 case AND_OP:
10013                         genAndOp (ic);
10014                         break;
10015                         
10016                 case OR_OP:
10017                         genOrOp (ic);
10018                         break;
10019                         
10020                 case '^' :
10021                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10022                         break;
10023                         
10024                 case '|' :
10025                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10026                         break;
10027                         
10028                 case BITWISEAND:
10029                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10030                         break;
10031                         
10032                 case INLINEASM:
10033                         genInline (ic);
10034                         break;
10035                         
10036                 case RRC:
10037                         genRRC (ic);
10038                         break;
10039                         
10040                 case RLC:
10041                         genRLC (ic);
10042                         break;
10043                         
10044                 case GETHBIT:
10045                         genGetHbit (ic);
10046                         break;
10047                         
10048                 case LEFT_OP:
10049                         genLeftShift (ic);
10050                         break;
10051                         
10052                 case RIGHT_OP:
10053                         genRightShift (ic);
10054                         break;
10055                         
10056                 case GET_VALUE_AT_ADDRESS:
10057                         genPointerGet(ic);
10058                         break;
10059                         
10060                 case '=' :
10061                         if (POINTER_SET(ic))
10062                                 genPointerSet(ic);
10063                         else
10064                                 genAssign(ic);
10065                         break;
10066                         
10067                 case IFX:
10068                         genIfx (ic,NULL);
10069                         break;
10070                         
10071                 case ADDRESS_OF:
10072                         genAddrOf (ic);
10073                         break;
10074                         
10075                 case JUMPTABLE:
10076                         genJumpTab (ic);
10077                         break;
10078                         
10079                 case CAST:
10080                         genCast (ic);
10081                         break;
10082                         
10083                 case RECEIVE:
10084                         genReceive(ic);
10085                         break;
10086                         
10087                 case SEND:
10088                         addSet(&_G.sendSet,ic);
10089                         break;
10090                         
10091                 case DUMMY_READ_VOLATILE:
10092                         genDummyRead (ic);
10093                         break;
10094                         
10095                 default :
10096                         ic = ic;
10097                 }
10098         }
10099
10100         
10101         /* now we are ready to call the
10102         peep hole optimizer */
10103         if (!options.nopeep) {
10104                 peepHole (&lineHead);
10105         }
10106         /* now do the actual printing */
10107         printLine (lineHead,codeOutFile);
10108         
10109 #ifdef PCODE_DEBUG
10110         DFPRINTF((stderr,"printing pBlock\n\n"));
10111         printpBlock(stdout,pb);
10112 #endif
10113         
10114         return;
10115 }