changed comment.
[fw/sdcc] / src / pic / gen.c
1 /*-------------------------------------------------------------------------
2   gen.c - source file for code generation for pic
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
8   
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of the GNU General Public License as published by the
11   Free Software Foundation; either version 2, or (at your option) any
12   later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22   
23   In other words, you are welcome to use, share and improve this program.
24   You are forbidden to forbid anyone else to use, share and improve
25   what you give them.   Help stamp out software-hoarding!
26   
27   Notes:
28   000123 mlh  Moved aopLiteral to SDCCglue.c to help the split
29       Made everything static
30 -------------------------------------------------------------------------*/
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "SDCCglobl.h"
37 #include "newalloc.h"
38
39 #include "common.h"
40 #include "SDCCpeeph.h"
41 #include "ralloc.h"
42 #include "pcode.h"
43 #include "gen.h"
44
45
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
51
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
55
56 /* max_key keeps track of the largest label number used in 
57 a function. This is then used to adjust the label offset
58 for the next function.
59 */
60 static int max_key=0;
61 static int GpsuedoStkPtr=0;
62
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
67
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
69
70 /* this is the down and dirty file with all kinds of 
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
74
75 static char *zero = "#0x00";
76 static char *one  = "#0x01";
77 static char *spname = "sp";
78
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
83
84 static char *accUse[] = {"a","b"};
85
86 //static short rbank = -1;
87
88 static struct {
89         short r0Pushed;
90         short r1Pushed;
91         short accInUse;
92         short inLine;
93         short debugLine;
94         short nRegsSaved;
95         set *sendSet;
96 } _G;
97
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
100 */
101 typedef struct resolvedIfx {
102         symbol *lbl;       /* pointer to a label */
103         int condition;   /* true or false ifx */
104                                          int generated;   /* set true when the code associated with the ifx
105                                          * is generated */
106 } resolvedIfx;
107
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
112
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
115
116 static unsigned char   SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char   SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
120
121 static  pBlock *pb;
122
123 /*-----------------------------------------------------------------*/
124 /*      my_powof2(n) - If `n' is an integaer power of 2, then the          */
125 /*                                 exponent of 2 is returned, otherwise -1 is      */
126 /*                                 returned.                                                                       */
127 /* note that this is similar to the function `powof2' in SDCCsymt  */
128 /* if(n == 2^y)                                                                                                    */
129 /*       return y;                                                                                                         */
130 /* return -1;                                                                                                      */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
133 {
134         if(num) {
135                 if( (num & (num-1)) == 0) {
136                         int nshifts = -1;
137                         while(num) {
138                                 num>>=1;
139                                 nshifts++;
140                         }
141                         return nshifts;
142                 }
143         }
144         
145         return -1;
146 }
147
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
149 {
150         
151         DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
152                 line_no,
153                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154                 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
156                 ((left)   ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
158                 ((right)  ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159                 ((result) ? AOP_SIZE(result) : 0));
160         
161 }
162
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
164 {
165         
166         DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
167                 line_no,
168                 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169                 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170                 ((left)   ? AopType(AOP_TYPE(left)) : "-"),
171                 ((left)   ? (SPEC_USIGN(operandType(left))       ? 'u' : 's') : '-'),
172                 ((right)  ? AopType(AOP_TYPE(right)) : "-"),
173                 ((right)  ? (SPEC_USIGN(operandType(right))  ? 'u' : 's') : '-'));
174         
175 }
176
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
178 {
179         va_list ap;
180         char lb[INITIAL_INLINEASM];  
181         char *lbp = lb;
182         
183         if(!debug_verbose)
184                 return;
185         
186         va_start(ap,fmt);   
187         
188         if (inst && *inst) {
189                 if (fmt && *fmt)
190                         sprintf(lb,"%s\t",inst);
191                 else
192                         sprintf(lb,"%s",inst);
193                 vsprintf(lb+(strlen(lb)),fmt,ap);
194         }  else
195                 vsprintf(lb,fmt,ap);
196         
197         while (isspace(*lbp)) lbp++;
198         
199         if (lbp && *lbp) 
200                 lineCurr = (lineCurr ?
201                 connectLine(lineCurr,newLineNode(lb)) :
202         (lineHead = newLineNode(lb)));
203         lineCurr->isInline = _G.inLine;
204         lineCurr->isDebug  = _G.debugLine;
205         
206         addpCode2pBlock(pb,newpCodeCharP(lb));
207         
208         va_end(ap);
209 }
210
211
212 void emitpLabel(int key)
213 {
214         addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
215 }
216
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
218 {
219         if(pcop)
220                 addpCode2pBlock(pb,newpCode(poc,pcop));
221         else
222                 DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
223 }
224
225 void emitpcodeNULLop(PIC_OPCODE poc)
226 {
227         
228         addpCode2pBlock(pb,newpCode(poc,NULL));
229         
230 }
231
232
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple    */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
237 {
238         va_list ap;
239         char lb[INITIAL_INLINEASM];  
240         char *lbp = lb;
241         
242         va_start(ap,fmt);   
243         
244         if (inst && *inst) {
245                 if (fmt && *fmt)
246                         sprintf(lb,"%s\t",inst);
247                 else
248                         sprintf(lb,"%s",inst);
249                 vsprintf(lb+(strlen(lb)),fmt,ap);
250         }  else
251                 vsprintf(lb,fmt,ap);
252         
253         while (isspace(*lbp)) lbp++;
254         
255         if (lbp && *lbp) 
256                 lineCurr = (lineCurr ?
257                 connectLine(lineCurr,newLineNode(lb)) :
258         (lineHead = newLineNode(lb)));
259         lineCurr->isInline = _G.inLine;
260         lineCurr->isDebug  = _G.debugLine;
261         
262         if(debug_verbose)
263                 addpCode2pBlock(pb,newpCodeCharP(lb));
264         
265         va_end(ap);
266 }
267
268 /*-----------------------------------------------------------------*/
269 /* pic14_emitDebuggerSymbol - associate the current code location  */
270 /*       with a debugger symbol                                                                            */
271 /*-----------------------------------------------------------------*/
272 void
273 pic14_emitDebuggerSymbol (char * debugSym)
274 {
275         _G.debugLine = 1;
276         pic14_emitcode ("", ";%s ==.", debugSym);
277         _G.debugLine = 0;
278 }
279
280
281 /*-----------------------------------------------------------------*/
282 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
283 /*-----------------------------------------------------------------*/
284 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
285 {
286         bool r0iu = FALSE , r1iu = FALSE;
287         bool r0ou = FALSE , r1ou = FALSE;
288         
289         /* the logic: if r0 & r1 used in the instruction
290         then we are in trouble otherwise */
291         
292         /* first check if r0 & r1 are used by this
293         instruction, in which case we are in trouble */
294         if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
295                 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
296         {
297                 goto endOfWorld;          
298         }
299         
300         r0ou = bitVectBitValue(ic->rMask,R0_IDX);
301         r1ou = bitVectBitValue(ic->rMask,R1_IDX);
302         
303         /* if no usage of r0 then return it */
304         if (!r0iu && !r0ou) {
305                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
306                 (*aopp)->type = AOP_R0;
307                 
308                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
309         }
310         
311         /* if no usage of r1 then return it */
312         if (!r1iu && !r1ou) {
313                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
314                 (*aopp)->type = AOP_R1;
315                 
316                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
317         }    
318         
319         /* now we know they both have usage */
320         /* if r0 not used in this instruction */
321         if (!r0iu) {
322                 /* push it if not already pushed */
323                 if (!_G.r0Pushed) {
324                         //pic14_emitcode ("push","%s",
325                         //                pic14_regWithIdx(R0_IDX)->dname);
326                         _G.r0Pushed++ ;
327                 }
328                 
329                 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
330                 (*aopp)->type = AOP_R0;
331                 
332                 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
333         }
334         
335         /* if r1 not used then */
336         
337         if (!r1iu) {
338                 /* push it if not already pushed */
339                 if (!_G.r1Pushed) {
340                         //pic14_emitcode ("push","%s",
341                         //                pic14_regWithIdx(R1_IDX)->dname);
342                         _G.r1Pushed++ ;
343                 }
344                 
345                 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
346                 (*aopp)->type = AOP_R1;
347                 return pic14_regWithIdx(R1_IDX);
348         }
349         
350 endOfWorld :
351         /* I said end of world but not quite end of world yet */
352         /* if this is a result then we can push it on the stack*/
353         if (result) {
354                 (*aopp)->type = AOP_STK;        
355                 return NULL;
356         }
357         
358         /* other wise this is true end of the world */
359         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
360                 "getFreePtr should never reach here");
361         exit(0);
362 }
363
364 /*-----------------------------------------------------------------*/
365 /* newAsmop - creates a new asmOp                                                                  */
366 /*-----------------------------------------------------------------*/
367 asmop *newAsmop (short type)
368 {
369         asmop *aop;
370         
371         aop = Safe_calloc(1,sizeof(asmop));
372         aop->type = type;
373         return aop;
374 }
375
376 static void genSetDPTR(int n)
377 {
378         if (!n)
379         {
380                 pic14_emitcode(";", "Select standard DPTR");
381                 pic14_emitcode("mov", "dps, #0x00");
382         }
383         else
384         {
385                 pic14_emitcode(";", "Select alternate DPTR");
386                 pic14_emitcode("mov", "dps, #0x01");
387         }
388 }
389
390 /*-----------------------------------------------------------------*/
391 /* resolveIfx - converts an iCode ifx into a form more useful for  */
392 /*                              generating code                                                                    */
393 /*-----------------------------------------------------------------*/
394 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
395 {
396         if(!resIfx) 
397                 return;
398         
399         //  DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
400         
401         resIfx->condition = 1;  /* assume that the ifx is true */
402         resIfx->generated = 0;  /* indicate that the ifx has not been used */
403         
404         if(!ifx) {
405                 resIfx->lbl = newiTempLabel(NULL);      /* oops, there is no ifx. so create a label */
406                                                                                         /*
407                                                                                         DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
408                                                                                         __FUNCTION__,__LINE__,resIfx->lbl->key);
409                 */
410         } else {
411                 if(IC_TRUE(ifx)) {
412                         resIfx->lbl = IC_TRUE(ifx);
413                 } else {
414                         resIfx->lbl = IC_FALSE(ifx);
415                         resIfx->condition = 0;
416                 }
417                 /*
418                 if(IC_TRUE(ifx)) 
419                 DEBUGpic14_emitcode("; ***","ifx true is non-null");
420                 if(IC_FALSE(ifx)) 
421                 DEBUGpic14_emitcode("; ***","ifx false is non-null");
422                 */
423         }
424         
425         //  DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
426         
427 }
428 /*-----------------------------------------------------------------*/
429 /* pointerCode - returns the code for a pointer type                       */
430 /*-----------------------------------------------------------------*/
431 static int pointerCode (sym_link *etype)
432 {
433         
434         return PTR_TYPE(SPEC_OCLS(etype));
435         
436 }
437
438 /*-----------------------------------------------------------------*/
439 /* aopForSym - for a true symbol                                                                   */
440 /*-----------------------------------------------------------------*/
441 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
442 {
443         asmop *aop;
444         memmap *space= SPEC_OCLS(sym->etype);
445         
446         DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
447         /* if already has one */
448         if (sym->aop)
449                 return sym->aop;
450         
451         /* assign depending on the storage class */
452         /* if it is on the stack or indirectly addressable */
453         /* space we need to assign either r0 or r1 to it         */    
454         if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
455                 sym->aop = aop = newAsmop(0);
456                 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
457                 aop->size = getSize(sym->type);
458                 
459                 /* now assign the address of the variable to 
460                 the pointer register */
461                 if (aop->type != AOP_STK) {
462                         
463                         if (sym->onStack) {
464                                 if ( _G.accInUse )
465                                         pic14_emitcode("push","acc");
466                                 
467                                 pic14_emitcode("mov","a,_bp");
468                                 pic14_emitcode("add","a,#0x%02x",
469                                         ((sym->stack < 0) ?
470                                         ((char)(sym->stack - _G.nRegsSaved )) :
471                                 ((char)sym->stack)) & 0xff);
472                                 pic14_emitcode("mov","%s,a",
473                                         aop->aopu.aop_ptr->name);
474                                 
475                                 if ( _G.accInUse )
476                                         pic14_emitcode("pop","acc");
477                         } else
478                                 pic14_emitcode("mov","%s,#%s",
479                                 aop->aopu.aop_ptr->name,
480                                 sym->rname);
481                         aop->paged = space->paged;
482                 } else
483                         aop->aopu.aop_stk = sym->stack;
484                 return aop;
485         }
486         
487         if (sym->onStack && options.stack10bit)
488         {
489         /* It's on the 10 bit stack, which is located in
490         * far data space.
491                 */
492                 
493                 //DEBUGpic14_emitcode(";","%d",__LINE__);
494                 
495                 if ( _G.accInUse )
496                         pic14_emitcode("push","acc");
497                 
498                 pic14_emitcode("mov","a,_bp");
499                 pic14_emitcode("add","a,#0x%02x",
500                         ((sym->stack < 0) ?
501                         ((char)(sym->stack - _G.nRegsSaved )) :
502                 ((char)sym->stack)) & 0xff);
503                 
504                 genSetDPTR(1);
505                 pic14_emitcode ("mov","dpx1,#0x40");
506                 pic14_emitcode ("mov","dph1,#0x00");
507                 pic14_emitcode ("mov","dpl1, a");
508                 genSetDPTR(0);
509                 
510                 if ( _G.accInUse )
511                         pic14_emitcode("pop","acc");
512                 
513                 sym->aop = aop = newAsmop(AOP_DPTR2);
514                 aop->size = getSize(sym->type); 
515                 return aop;
516         }
517         
518         //DEBUGpic14_emitcode(";","%d",__LINE__);
519         /* if in bit space */
520         if (IN_BITSPACE(space)) {
521                 sym->aop = aop = newAsmop (AOP_CRY);
522                 aop->aopu.aop_dir = sym->rname ;
523                 aop->size = getSize(sym->type);
524                 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
525                 return aop;
526         }
527         /* if it is in direct space */
528         if (IN_DIRSPACE(space)) {
529                 sym->aop = aop = newAsmop (AOP_DIR);
530                 aop->aopu.aop_dir = sym->rname ;
531                 aop->size = getSize(sym->type);
532                 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
533                 return aop;
534         }
535         
536         /* special case for a function */
537         if (IS_FUNC(sym->type)) {   
538                 
539                 sym->aop = aop = newAsmop(AOP_PCODE);
540                 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
541                 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542                 PCOI(aop->aopu.pcop)->_function = 1;
543                 PCOI(aop->aopu.pcop)->index = 0;
544                 aop->size = FPTRSIZE; 
545                 /*
546                 sym->aop = aop = newAsmop(AOP_IMMD);    
547                 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548                 strcpy(aop->aopu.aop_immd,sym->rname);
549                 aop->size = FPTRSIZE; 
550                 */
551                 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552                 return aop;
553         }
554         
555         
556         /* only remaining is far space */
557         /* in which case DPTR gets the address */
558         sym->aop = aop = newAsmop(AOP_PCODE);
559         
560         aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
561         PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
562         PCOI(aop->aopu.pcop)->index = 0;
563         
564         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
565                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
566         
567         allocDirReg (IC_LEFT(ic));
568         
569         aop->size = FPTRSIZE; 
570         /*
571         DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
572         sym->aop = aop = newAsmop(AOP_DPTR);
573         pic14_emitcode ("mov","dptr,#%s", sym->rname);
574         aop->size = getSize(sym->type);
575         
576           DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
577         */
578         
579         /* if it is in code space */
580         if (IN_CODESPACE(space))
581                 aop->code = 1;
582         
583         return aop;       
584 }
585
586 /*-----------------------------------------------------------------*/
587 /* aopForRemat - rematerialzes an object                                                   */
588 /*-----------------------------------------------------------------*/
589 static asmop *aopForRemat (operand *op) // x symbol *sym)
590 {
591         symbol *sym = OP_SYMBOL(op);
592         iCode *ic = NULL;
593         asmop *aop = newAsmop(AOP_PCODE);
594         int val = 0;
595         int offset = 0;
596         
597         ic = sym->rematiCode;
598         
599         DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
600         if(IS_OP_POINTER(op)) {
601                 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
602         }
603         for (;;) {
604                 if (ic->op == '+') {
605                         val += (int) operandLitValue(IC_RIGHT(ic));
606                 } else if (ic->op == '-') {
607                         val -= (int) operandLitValue(IC_RIGHT(ic));
608                 } else
609                         break;
610                 
611                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
612         }
613         
614         offset = OP_SYMBOL(IC_LEFT(ic))->offset;
615         aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
616         PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
617         PCOI(aop->aopu.pcop)->index = val;
618         
619         DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
620                 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
621                 val, IS_PTR_CONST(operandType(op)));
622         
623         //      DEBUGpic14_emitcode(";","aop type  %s",AopType(AOP_TYPE(IC_LEFT(ic))));
624         
625         allocDirReg (IC_LEFT(ic));
626         
627         return aop;              
628 }
629
630 int aopIdx (asmop *aop, int offset)
631 {
632         if(!aop)
633                 return -1;
634         
635         if(aop->type !=  AOP_REG)
636                 return -2;
637         
638         return aop->aopu.aop_reg[offset]->rIdx;
639         
640 }
641 /*-----------------------------------------------------------------*/
642 /* regsInCommon - two operands have some registers in common       */
643 /*-----------------------------------------------------------------*/
644 static bool regsInCommon (operand *op1, operand *op2)
645 {
646         symbol *sym1, *sym2;
647         int i;
648         
649         /* if they have registers in common */
650         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
651                 return FALSE ;
652         
653         sym1 = OP_SYMBOL(op1);
654         sym2 = OP_SYMBOL(op2);
655         
656         if (sym1->nRegs == 0 || sym2->nRegs == 0)
657                 return FALSE ;
658         
659         for (i = 0 ; i < sym1->nRegs ; i++) {
660                 int j;
661                 if (!sym1->regs[i])
662                         continue ;
663                 
664                 for (j = 0 ; j < sym2->nRegs ;j++ ) {
665                         if (!sym2->regs[j])
666                                 continue ;
667                         
668                         if (sym2->regs[j] == sym1->regs[i])
669                                 return TRUE ;
670                 }
671         }
672         
673         return FALSE ;
674 }
675
676 /*-----------------------------------------------------------------*/
677 /* operandsEqu - equivalent                                                                        */
678 /*-----------------------------------------------------------------*/
679 static bool operandsEqu ( operand *op1, operand *op2)
680 {
681         symbol *sym1, *sym2;
682         
683         /* if they not symbols */
684         if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
685                 return FALSE;
686         
687         sym1 = OP_SYMBOL(op1);
688         sym2 = OP_SYMBOL(op2);
689         
690         /* if both are itemps & one is spilt
691         and the other is not then false */
692         if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
693                 sym1->isspilt != sym2->isspilt )
694                 return FALSE ;
695         
696         /* if they are the same */
697         if (sym1 == sym2)
698                 return TRUE ;
699         
700         if (sym1->rname[0] && sym2->rname[0]
701                 && strcmp (sym1->rname, sym2->rname) == 0)
702                 return TRUE;
703         
704         
705         /* if left is a tmp & right is not */
706         if (IS_ITEMP(op1)  && 
707                 !IS_ITEMP(op2) &&
708                 sym1->isspilt  &&
709                 (sym1->usl.spillLoc == sym2))
710                 return TRUE;
711         
712         if (IS_ITEMP(op2)  && 
713                 !IS_ITEMP(op1) &&
714                 sym2->isspilt  &&
715                 sym1->level > 0 &&
716                 (sym2->usl.spillLoc == sym1))
717                 return TRUE ;
718         
719         return FALSE ;
720 }
721
722 /*-----------------------------------------------------------------*/
723 /* pic14_sameRegs - two asmops have the same registers                                   */
724 /*-----------------------------------------------------------------*/
725 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
726 {
727         int i;
728         
729         if (aop1 == aop2)
730                 return TRUE ;
731         
732         if (aop1->type != AOP_REG ||
733                 aop2->type != AOP_REG )
734                 return FALSE ;
735         
736         if (aop1->size != aop2->size )
737                 return FALSE ;
738         
739         for (i = 0 ; i < aop1->size ; i++ )
740                 if (aop1->aopu.aop_reg[i] !=
741                         aop2->aopu.aop_reg[i] )
742                         return FALSE ;
743                 
744                 return TRUE ;
745 }
746
747 /*-----------------------------------------------------------------*/
748 /* aopOp - allocates an asmop for an operand  :                                    */
749 /*-----------------------------------------------------------------*/
750 void aopOp (operand *op, iCode *ic, bool result)
751 {
752         asmop *aop;
753         symbol *sym;
754         int i;
755         
756         if (!op)
757                 return ;
758         
759         //      DEBUGpic14_emitcode(";","%d",__LINE__);
760         /* if this a literal */
761         if (IS_OP_LITERAL(op)) {
762                 op->aop = aop = newAsmop(AOP_LIT);
763                 aop->aopu.aop_lit = op->operand.valOperand;
764                 aop->size = getSize(operandType(op));
765                 return;
766         }
767         
768         {
769                 sym_link *type = operandType(op);
770                 if(IS_PTR_CONST(type))
771                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
772         }
773         
774         /* if already has a asmop then continue */
775         if (op->aop)
776                 return ;
777         
778         /* if the underlying symbol has a aop */
779         if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
780                 DEBUGpic14_emitcode(";","%d",__LINE__);
781                 op->aop = OP_SYMBOL(op)->aop;
782                 return;
783         }
784         
785         /* if this is a true symbol */
786         if (IS_TRUE_SYMOP(op)) {          
787                 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
788                 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
789                 return ;
790         }
791         
792         /* this is a temporary : this has
793         only four choices :
794         a) register
795         b) spillocation
796         c) rematerialize 
797         d) conditional   
798         e) can be a return use only */
799         
800         sym = OP_SYMBOL(op);
801         
802         
803         /* if the type is a conditional */
804         if (sym->regType == REG_CND) {
805                 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
806                 aop->size = 0;
807                 return;
808         }
809         
810         /* if it is spilt then two situations
811         a) is rematerialize 
812         b) has a spill location */
813         if (sym->isspilt || sym->nRegs == 0) {
814                 
815                 DEBUGpic14_emitcode(";","%d",__LINE__);
816                 /* rematerialize it NOW */
817                 if (sym->remat) {
818                         
819                         sym->aop = op->aop = aop = aopForRemat (op);
820                         aop->size = getSize(sym->type);
821                         //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
822                         return;
823                 }
824                 
825                 if (sym->accuse) {
826                         int i;
827                         aop = op->aop = sym->aop = newAsmop(AOP_ACC);
828                         aop->size = getSize(sym->type);
829                         for ( i = 0 ; i < 2 ; i++ )
830                                 aop->aopu.aop_str[i] = accUse[i];
831                         DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
832                         return;  
833                 }
834                 
835                 if (sym->ruonly ) {
836                         if(sym->isptr) {        // && sym->uptr 
837                                 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
838                                 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
839                                 
840                                 //PCOI(aop->aopu.pcop)->_const = 0;
841                                 //PCOI(aop->aopu.pcop)->index = 0;
842                                 /*
843                                 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
844                                 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
845                                 */
846                                 //allocDirReg (IC_LEFT(ic));
847                                 
848                                 aop->size = getSize(sym->type);
849                                 DEBUGpic14_emitcode(";","%d",__LINE__);
850                                 return;
851                                 
852                         } else {
853                                 
854                                 unsigned i;
855                                 
856                                 aop = op->aop = sym->aop = newAsmop(AOP_STR);
857                                 aop->size = getSize(sym->type);
858                                 for ( i = 0 ; i < fReturnSizePic ; i++ )
859                                         aop->aopu.aop_str[i] = fReturn[i];
860                                 
861                                 DEBUGpic14_emitcode(";","%d",__LINE__);
862                                 return;
863                         }
864                 }
865                 
866                 /* else spill location  */
867                 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
868                         /* force a new aop if sizes differ */
869                         sym->usl.spillLoc->aop = NULL;
870                 }
871                 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
872                         __FUNCTION__,__LINE__,
873                         sym->usl.spillLoc->rname,
874                         sym->rname, sym->usl.spillLoc->offset);
875                 
876                 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
877                 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
878                 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
879                         getSize(sym->type), 
880                         sym->usl.spillLoc->offset);
881                 aop->size = getSize(sym->type);
882                 
883                 return;
884         }
885         
886         {
887                 sym_link *type = operandType(op);
888                 if(IS_PTR_CONST(type)) 
889                         DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
890         }
891         
892         /* must be in a register */
893         DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
894         sym->aop = op->aop = aop = newAsmop(AOP_REG);
895         aop->size = sym->nRegs;
896         for ( i = 0 ; i < sym->nRegs ;i++)
897                 aop->aopu.aop_reg[i] = sym->regs[i];
898 }
899
900 /*-----------------------------------------------------------------*/
901 /* freeAsmop - free up the asmop given to an operand                       */
902 /*----------------------------------------------------------------*/
903 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
904 {       
905         asmop *aop ;
906         
907         if (!op)
908                 aop = aaop;
909         else 
910                 aop = op->aop;
911         
912         if (!aop)
913                 return ;
914         
915         if (aop->freed)
916                 goto dealloc; 
917         
918         aop->freed = 1;
919         
920         /* depending on the asmop type only three cases need work AOP_RO
921         , AOP_R1 && AOP_STK */
922 #if 0
923         switch (aop->type) {
924         case AOP_R0 :
925                 if (_G.r0Pushed ) {
926                         if (pop) {
927                                 pic14_emitcode ("pop","ar0");     
928                                 _G.r0Pushed--;
929                         }
930                 }
931                 bitVectUnSetBit(ic->rUsed,R0_IDX);
932                 break;
933                 
934         case AOP_R1 :
935                 if (_G.r1Pushed ) {
936                         if (pop) {
937                                 pic14_emitcode ("pop","ar1");
938                                 _G.r1Pushed--;
939                         }
940                 }
941                 bitVectUnSetBit(ic->rUsed,R1_IDX);                      
942                 break;
943                 
944         case AOP_STK :
945                 {
946                         int sz = aop->size;      
947                         int stk = aop->aopu.aop_stk + aop->size;
948                         bitVectUnSetBit(ic->rUsed,R0_IDX);
949                         bitVectUnSetBit(ic->rUsed,R1_IDX);                
950                         
951                         getFreePtr(ic,&aop,FALSE);
952                         
953                         if (options.stack10bit)
954                         {
955                                 /* I'm not sure what to do here yet... */
956                                 /* #STUB */
957                                 fprintf(stderr, 
958                                         "*** Warning: probably generating bad code for "
959                                         "10 bit stack mode.\n");
960                         }
961                         
962                         if (stk) {
963                                 pic14_emitcode ("mov","a,_bp");
964                                 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
965                                 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
966                         } else {
967                                 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
968                         }
969                         
970                         while (sz--) {
971                                 pic14_emitcode("pop","acc");
972                                 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
973                                 if (!sz) break;
974                                 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
975                         }
976                         op->aop = aop;
977                         freeAsmop(op,NULL,ic,TRUE);
978                         if (_G.r0Pushed) {
979                                 pic14_emitcode("pop","ar0");
980                                 _G.r0Pushed--;
981                         }
982                         
983                         if (_G.r1Pushed) {
984                                 pic14_emitcode("pop","ar1");
985                                 _G.r1Pushed--;
986                         }         
987                 }
988         }
989 #endif
990         
991 dealloc:
992         /* all other cases just dealloc */
993         if (op ) {
994                 op->aop = NULL;
995                 if (IS_SYMOP(op)) {
996                         OP_SYMBOL(op)->aop = NULL;      
997                         /* if the symbol has a spill */
998                         if (SPIL_LOC(op))
999                                 SPIL_LOC(op)->aop = NULL;
1000                 }
1001         }
1002 }
1003
1004 /*-----------------------------------------------------------------*/
1005 /* aopGet - for fetching value of the aop                                                  */
1006 /*-----------------------------------------------------------------*/
1007 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1008 {
1009         char *s = buffer ;
1010         char *rs;
1011         
1012         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1013         /* offset is greater than
1014         size then zero */
1015         if (offset > (aop->size - 1) &&
1016                 aop->type != AOP_LIT)
1017                 return zero;
1018         
1019         /* depending on type */
1020         switch (aop->type) {
1021                 
1022         case AOP_R0:
1023         case AOP_R1:
1024                 DEBUGpic14_emitcode(";","%d",__LINE__);
1025                 /* if we need to increment it */           
1026                 while (offset > aop->coff) {            
1027                         pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);    
1028                         aop->coff++;
1029                 }
1030                 
1031                 while (offset < aop->coff) {
1032                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1033                         aop->coff--;
1034                 }
1035                 
1036                 aop->coff = offset ;
1037                 if (aop->paged) {
1038                         pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1039                         return (dname ? "acc" : "a");
1040                 }               
1041                 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1042                 rs = Safe_calloc(1,strlen(s)+1);
1043                 strcpy(rs,s);   
1044                 return rs;
1045                 
1046         case AOP_DPTR:
1047         case AOP_DPTR2:
1048                 DEBUGpic14_emitcode(";","%d",__LINE__);
1049                 if (aop->type == AOP_DPTR2)
1050                 {
1051                         genSetDPTR(1);
1052                 }
1053                 
1054                 while (offset > aop->coff) {
1055                         pic14_emitcode ("inc","dptr");
1056                         aop->coff++;
1057                 }
1058                 
1059                 while (offset < aop->coff) {            
1060                         pic14_emitcode("lcall","__decdptr");
1061                         aop->coff--;
1062                 }
1063                 
1064                 aop->coff = offset;
1065                 if (aop->code) {
1066                         pic14_emitcode("clr","a");
1067                         pic14_emitcode("movc","a,@a+dptr");
1068                 }
1069                 else {
1070                         pic14_emitcode("movx","a,@dptr");
1071                 }
1072                 
1073                 if (aop->type == AOP_DPTR2)
1074                 {
1075                         genSetDPTR(0);
1076                 }
1077                 
1078                 return (dname ? "acc" : "a");
1079                 
1080                 
1081         case AOP_IMMD:
1082                 if (bit16) 
1083                         sprintf (s,"%s",aop->aopu.aop_immd);
1084                 else
1085                         if (offset) 
1086                                 sprintf(s,"(%s >> %d)",
1087                                 aop->aopu.aop_immd,
1088                                 offset*8);
1089                         else
1090                                 sprintf(s,"%s",
1091                                 aop->aopu.aop_immd);
1092                         DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1093                         rs = Safe_calloc(1,strlen(s)+1);
1094                         strcpy(rs,s);   
1095                         return rs;
1096                         
1097         case AOP_DIR:
1098                 if (offset) {
1099                         sprintf(s,"(%s + %d)",
1100                                 aop->aopu.aop_dir,
1101                                 offset);
1102                         DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1103                 } else
1104                         sprintf(s,"%s",aop->aopu.aop_dir);
1105                 rs = Safe_calloc(1,strlen(s)+1);
1106                 strcpy(rs,s);   
1107                 return rs;
1108                 
1109         case AOP_REG:
1110                 //if (dname) 
1111                 //        return aop->aopu.aop_reg[offset]->dname;
1112                 //else
1113                 return aop->aopu.aop_reg[offset]->name;
1114                 
1115         case AOP_CRY:
1116                 //pic14_emitcode(";","%d",__LINE__);
1117                 return aop->aopu.aop_dir;
1118                 
1119         case AOP_ACC:
1120                 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1121                 return "AOP_accumulator_bug";
1122                 
1123         case AOP_LIT:
1124                 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1125                 rs = Safe_calloc(1,strlen(s)+1);
1126                 strcpy(rs,s);   
1127                 return rs;
1128                 
1129         case AOP_STR:
1130                 aop->coff = offset ;
1131                 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1132                         dname)
1133                         return "acc";
1134                 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1135                 
1136                 return aop->aopu.aop_str[offset];
1137                 
1138         case AOP_PCODE:
1139                 {
1140                         pCodeOp *pcop = aop->aopu.pcop;
1141                         DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1142                         if(pcop->name) {
1143                                 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1144                                 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1145                                 sprintf(s,"%s", pcop->name);
1146                         } else
1147                                 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1148                         
1149                 }
1150                 rs = Safe_calloc(1,strlen(s)+1);
1151                 strcpy(rs,s);   
1152                 return rs;
1153                 
1154   }
1155   
1156   werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1157           "aopget got unsupported aop->type");
1158   exit(0);
1159 }
1160
1161
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp                                  */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGetTempReg(void)
1166 {
1167         
1168         pCodeOp *pcop;
1169         
1170         pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1171         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1172                 PCOR(pcop)->r->wasUsed=1;
1173                 PCOR(pcop)->r->isFree=0;
1174         }
1175         
1176         return pcop;
1177 }
1178
1179 /*-----------------------------------------------------------------*/
1180 /* popGetTempReg - create a new temporary pCodeOp                                  */
1181 /*-----------------------------------------------------------------*/
1182 void popReleaseTempReg(pCodeOp *pcop)
1183 {
1184         
1185         if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1186                 PCOR(pcop)->r->isFree = 1;
1187         
1188 }
1189 /*-----------------------------------------------------------------*/
1190 /* popGetLabel - create a new pCodeOp of type PO_LABEL                     */
1191 /*-----------------------------------------------------------------*/
1192 pCodeOp *popGetLabel(unsigned int key)
1193 {
1194         
1195         DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1196         
1197         if(key>(unsigned int)max_key)
1198                 max_key = key;
1199         
1200         return newpCodeOpLabel(NULL,key+100+labelOffset);
1201 }
1202
1203 /*-------------------------------------------------------------------*/
1204 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1205 /*-------------------------------------------------------------------*/
1206 pCodeOp *popGetHighLabel(unsigned int key)
1207 {
1208         pCodeOp *pcop;
1209         pcop = popGetLabel(key);
1210         PCOLAB(pcop)->offset = 1;
1211         return pcop;
1212 }
1213
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion                      */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1218 {
1219         
1220         return newpCodeOpLit(lit);
1221 }
1222
1223 /*-----------------------------------------------------------------*/
1224 /* popGetImmd - asm operator to pcode immediate conversion                 */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1227 {
1228         
1229         return newpCodeOpImmd(name, offset,index, 0, is_func);
1230 }
1231
1232
1233 /*-----------------------------------------------------------------*/
1234 /* popGet - asm operator to pcode operator conversion                      */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetWithString(char *str, int isExtern)
1237 {
1238         pCodeOp *pcop;
1239         
1240         
1241         if(!str) {
1242                 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1243                 exit (1);
1244         }
1245         
1246         pcop = newpCodeOp(str,PO_STR);
1247         PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1248         
1249         return pcop;
1250 }
1251
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString -                                                                                      */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1256 {
1257         
1258         pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259         pcop->type = PO_DIR;
1260         
1261         DEBUGpic14_emitcode(";","%d",__LINE__);
1262         
1263         if(!str)
1264                 str = "BAD_STRING";
1265         
1266         pcop->name = Safe_calloc(1,strlen(str)+1);
1267         strcpy(pcop->name,str);
1268         
1269         //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1270         
1271         PCOR(pcop)->r = dirregWithName(pcop->name);
1272         if(PCOR(pcop)->r == NULL) {
1273                 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274                 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275                 DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1276         } else {
1277                 DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1278         }
1279         PCOR(pcop)->instance = offset;
1280         
1281         return pcop;
1282 }
1283
1284 /*-----------------------------------------------------------------*/
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popRegFromIdx(int rIdx)
1287 {
1288         pCodeOp *pcop;
1289         
1290         DEBUGpic14_emitcode ("; ***","%s,%d  , rIdx=0x%x",
1291                 __FUNCTION__,__LINE__,rIdx);
1292         
1293         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1294         
1295         PCOR(pcop)->rIdx = rIdx;
1296         PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1297         PCOR(pcop)->r->isFree = 0;
1298         PCOR(pcop)->r->wasUsed = 1;
1299         
1300         pcop->type = PCOR(pcop)->r->pc_type;
1301         
1302         
1303         return pcop;
1304 }
1305
1306 /*-----------------------------------------------------------------*/
1307 /* popGet - asm operator to pcode operator conversion                      */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1310 {
1311         //char *s = buffer ;
1312         //char *rs;
1313         
1314         pCodeOp *pcop;
1315         
1316         //DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1317         /* offset is greater than
1318         size then zero */
1319         
1320         if (offset > (aop->size - 1) &&
1321                 aop->type != AOP_LIT)
1322                 return NULL;  //zero;
1323         
1324         /* depending on type */
1325         switch (aop->type) {
1326                 
1327         case AOP_R0:
1328         case AOP_R1:
1329         case AOP_DPTR:
1330         case AOP_DPTR2:
1331         case AOP_ACC:
1332                 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1333                 return NULL;
1334                 
1335         case AOP_IMMD:
1336                 DEBUGpic14_emitcode(";","%d",__LINE__);
1337                 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1338                 
1339         case AOP_DIR:
1340                 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1341 #if 0
1342                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1343                 pcop->type = PO_DIR;
1344                 
1345                 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1346                 strcpy(pcop->name,aop->aopu.aop_dir);   
1347                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1348                 if(PCOR(pcop)->r == NULL) {
1349                         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1350                         PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1351                         DEBUGpic14_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1352                 } else {
1353                         DEBUGpic14_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
1354                 }
1355                 PCOR(pcop)->instance = offset;
1356                 
1357                 return pcop;
1358 #endif
1359                 
1360         case AOP_REG:
1361                 {
1362                         int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1363                         
1364                         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365                         PCOR(pcop)->rIdx = rIdx;
1366                         PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1367                         PCOR(pcop)->r->wasUsed=1;
1368                         PCOR(pcop)->r->isFree=0;
1369                         
1370                         PCOR(pcop)->instance = offset;
1371                         pcop->type = PCOR(pcop)->r->pc_type;
1372                         //rs = aop->aopu.aop_reg[offset]->name;
1373                         DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1374                         return pcop;
1375                 }
1376                 
1377         case AOP_CRY:
1378                 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1379                 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1380                 //if(PCOR(pcop)->r == NULL)
1381                 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1382                 return pcop;
1383                 
1384         case AOP_LIT:
1385                 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1386                 
1387         case AOP_STR:
1388                 DEBUGpic14_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
1389                 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1390                 /*
1391                 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1392                 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1393                 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1394                 pcop->type = PCOR(pcop)->r->pc_type;
1395                 pcop->name = PCOR(pcop)->r->name;
1396                 
1397                   return pcop;
1398                 */
1399                 
1400         case AOP_PCODE:
1401                 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1402                         __LINE__, 
1403                         ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1404                 pcop = pCodeOpCopy(aop->aopu.pcop);
1405                 PCOI(pcop)->offset = offset;
1406                 return pcop;
1407         }
1408         
1409         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1410                 "popGet got unsupported aop->type");
1411         exit(0);
1412 }
1413 /*-----------------------------------------------------------------*/
1414 /* aopPut - puts a string for a aop                                                        */
1415 /*-----------------------------------------------------------------*/
1416 void aopPut (asmop *aop, char *s, int offset)
1417 {
1418         char *d = buffer ;
1419         symbol *lbl ;
1420         
1421         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1422         
1423         if (aop->size && offset > ( aop->size - 1)) {
1424                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1425                         "aopPut got offset > aop->size");
1426                 exit(0);
1427         }
1428         
1429         /* will assign value to value */
1430         /* depending on where it is ofcourse */
1431         switch (aop->type) {
1432         case AOP_DIR:
1433                 if (offset) {
1434                         sprintf(d,"(%s + %d)",
1435                                 aop->aopu.aop_dir,offset);
1436                         fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1437                         
1438                 } else
1439                         sprintf(d,"%s",aop->aopu.aop_dir);
1440                 
1441                 if (strcmp(d,s)) {
1442                         DEBUGpic14_emitcode(";","%d",__LINE__);
1443                         if(strcmp(s,"W"))
1444                                 pic14_emitcode("movf","%s,w",s);
1445                         pic14_emitcode("movwf","%s",d);
1446                         
1447                         if(strcmp(s,"W")) {
1448                                 pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
1449                                 if(offset >= aop->size) {
1450                                         emitpcode(POC_CLRF,popGet(aop,offset));
1451                                         break;
1452                                 } else
1453                                         emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1454                         }
1455                         
1456                         emitpcode(POC_MOVWF,popGet(aop,offset));
1457                         
1458                         
1459                 }
1460                 break;
1461                 
1462         case AOP_REG:
1463                 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1464                         //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1465                         /*
1466                         if (*s == '@'             ||
1467                         strcmp(s,"r0") == 0 ||
1468                         strcmp(s,"r1") == 0 ||
1469                         strcmp(s,"r2") == 0 ||
1470                         strcmp(s,"r3") == 0 ||
1471                         strcmp(s,"r4") == 0 ||
1472                         strcmp(s,"r5") == 0 ||
1473                         strcmp(s,"r6") == 0 || 
1474                         strcmp(s,"r7") == 0 )
1475                         pic14_emitcode("mov","%s,%s  ; %d",
1476                         aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1477                         else
1478                         */
1479                         
1480                         if(strcmp(s,"W")==0 )
1481                                 pic14_emitcode("movf","%s,w  ; %d",s,__LINE__);
1482                         
1483                         pic14_emitcode("movwf","%s",
1484                                 aop->aopu.aop_reg[offset]->name);
1485                         
1486                         if(strcmp(s,zero)==0) {
1487                                 emitpcode(POC_CLRF,popGet(aop,offset));
1488                                 
1489                         } else if(strcmp(s,"W")==0) {
1490                                 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1491                                 pcop->type = PO_GPR_REGISTER;
1492                                 
1493                                 PCOR(pcop)->rIdx = -1;
1494                                 PCOR(pcop)->r = NULL;
1495                                 
1496                                 DEBUGpic14_emitcode(";","%d",__LINE__);
1497                                 pcop->name = Safe_strdup(s);
1498                                 emitpcode(POC_MOVFW,pcop);
1499                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1500                         } else if(strcmp(s,one)==0) {
1501                                 emitpcode(POC_CLRF,popGet(aop,offset));
1502                                 emitpcode(POC_INCF,popGet(aop,offset));
1503                         } else {
1504                                 emitpcode(POC_MOVWF,popGet(aop,offset));
1505                         }
1506                 }
1507                 break;
1508                 
1509         case AOP_DPTR:
1510         case AOP_DPTR2:
1511                 
1512                 if (aop->type == AOP_DPTR2)
1513                 {
1514                         genSetDPTR(1);
1515                 }
1516                 
1517                 if (aop->code) {
1518                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1519                                 "aopPut writting to code space");
1520                         exit(0);
1521                 }
1522                 
1523                 while (offset > aop->coff) {
1524                         aop->coff++;
1525                         pic14_emitcode ("inc","dptr");
1526                 }
1527                 
1528                 while (offset < aop->coff) {
1529                         aop->coff-- ;
1530                         pic14_emitcode("lcall","__decdptr");
1531                 }
1532                 
1533                 aop->coff = offset;
1534                 
1535                 /* if not in accumulater */
1536                 MOVA(s);
1537                 
1538                 pic14_emitcode ("movx","@dptr,a");
1539                 
1540                 if (aop->type == AOP_DPTR2)
1541                 {
1542                         genSetDPTR(0);
1543                 }
1544                 break;
1545                 
1546         case AOP_R0:
1547         case AOP_R1:
1548                 while (offset > aop->coff) {
1549                         aop->coff++;
1550                         pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1551                 }
1552                 while (offset < aop->coff) {
1553                         aop->coff-- ;
1554                         pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1555                 }
1556                 aop->coff = offset;
1557                 
1558                 if (aop->paged) {
1559                         MOVA(s);                         
1560                         pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1561                         
1562                 } else
1563                         if (*s == '@') {
1564                                 MOVA(s);
1565                                 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1566                         } else
1567                                 if (strcmp(s,"r0") == 0 ||
1568                                         strcmp(s,"r1") == 0 ||
1569                                         strcmp(s,"r2") == 0 ||
1570                                         strcmp(s,"r3") == 0 ||
1571                                         strcmp(s,"r4") == 0 ||
1572                                         strcmp(s,"r5") == 0 ||
1573                                         strcmp(s,"r6") == 0 || 
1574                                         strcmp(s,"r7") == 0 ) {
1575                                         char buffer[10];
1576                                         sprintf(buffer,"a%s",s);
1577                                         pic14_emitcode("mov","@%s,%s",
1578                                                 aop->aopu.aop_ptr->name,buffer);
1579                                 } else
1580                                         pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1581                                 
1582                                 break;
1583                                 
1584         case AOP_STK:
1585                 if (strcmp(s,"a") == 0)
1586                         pic14_emitcode("push","acc");
1587                 else
1588                         pic14_emitcode("push","%s",s);
1589                 
1590                 break;
1591                 
1592         case AOP_CRY:
1593                 /* if bit variable */
1594                 if (!aop->aopu.aop_dir) {
1595                         pic14_emitcode("clr","a");
1596                         pic14_emitcode("rlc","a");
1597                 } else {
1598                         if (s == zero) 
1599                                 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1600                         else
1601                                 if (s == one)
1602                                         pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1603                                 else
1604                                         if (!strcmp(s,"c"))
1605                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1606                                         else {
1607                                                 lbl = newiTempLabel(NULL);
1608                                                 
1609                                                 if (strcmp(s,"a")) {
1610                                                         MOVA(s);
1611                                                 }
1612                                                 pic14_emitcode("clr","c");
1613                                                 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1614                                                 pic14_emitcode("cpl","c");
1615                                                 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1616                                                 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1617                                         }
1618                 }
1619                 break;
1620                 
1621         case AOP_STR:
1622                 aop->coff = offset;
1623                 if (strcmp(aop->aopu.aop_str[offset],s))
1624                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1625                 break;
1626                 
1627         case AOP_ACC:
1628                 aop->coff = offset;
1629                 if (!offset && (strcmp(s,"acc") == 0))
1630                         break;
1631                 
1632                 if (strcmp(aop->aopu.aop_str[offset],s))
1633                         pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1634                 break;
1635                 
1636         default :
1637                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1638                         "aopPut got unsupported aop->type");
1639                 exit(0);
1640         }
1641         
1642 }
1643
1644 /*-----------------------------------------------------------------*/
1645 /* mov2w - generate either a MOVLW or MOVFW based operand type     */
1646 /*-----------------------------------------------------------------*/
1647 void mov2w (asmop *aop, int offset)
1648 {
1649         
1650         if(!aop)
1651                 return;
1652         
1653         DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
1654         
1655         if ( aop->type == AOP_PCODE ||
1656                 aop->type == AOP_LIT ||
1657                 aop->type == AOP_IMMD )
1658                 emitpcode(POC_MOVLW,popGet(aop,offset));
1659         else
1660                 emitpcode(POC_MOVFW,popGet(aop,offset));
1661         
1662 }
1663
1664 /*-----------------------------------------------------------------*/
1665 /* reAdjustPreg - points a register back to where it should        */
1666 /*-----------------------------------------------------------------*/
1667 static void reAdjustPreg (asmop *aop)
1668 {
1669         int size ;
1670         
1671         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1672         aop->coff = 0;
1673         if ((size = aop->size) <= 1)
1674                 return ;
1675         size-- ;
1676         switch (aop->type) {
1677         case AOP_R0 :
1678         case AOP_R1 :
1679                 while (size--)
1680                         pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1681                 break;                  
1682         case AOP_DPTR :
1683         case AOP_DPTR2:
1684                 if (aop->type == AOP_DPTR2)
1685                 {
1686                         genSetDPTR(1);
1687                 } 
1688                 while (size--)
1689                 {
1690                         pic14_emitcode("lcall","__decdptr");
1691                 }
1692                 
1693                 if (aop->type == AOP_DPTR2)
1694                 {
1695                         genSetDPTR(0);
1696                 }
1697                 break;
1698                 
1699         }
1700         
1701 }
1702
1703
1704 #if 0
1705 /*-----------------------------------------------------------------*/
1706 /* opIsGptr: returns non-zero if the passed operand is             */
1707 /* a generic pointer type.                                         */
1708 /*-----------------------------------------------------------------*/ 
1709 static int opIsGptr(operand *op)
1710 {
1711         sym_link *type = operandType(op);
1712         
1713         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1714         if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1715         {
1716                 return 1;
1717         }
1718         return 0;          
1719 }
1720 #endif
1721
1722 /*-----------------------------------------------------------------*/
1723 /* pic14_getDataSize - get the operand data size                   */
1724 /*-----------------------------------------------------------------*/
1725 int pic14_getDataSize(operand *op)
1726 {
1727         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1728         
1729         
1730         return AOP_SIZE(op);
1731         
1732         // tsd- in the pic port, the genptr size is 1, so this code here
1733         // fails. ( in the 8051 port, the size was 4).
1734 #if 0
1735         int size;
1736         size = AOP_SIZE(op);
1737         if (size == GPTRSIZE)
1738         {
1739                 sym_link *type = operandType(op);
1740                 if (IS_GENPTR(type))
1741                 {
1742                 /* generic pointer; arithmetic operations
1743                 * should ignore the high byte (pointer type).
1744                         */
1745                         size--;
1746                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1747                 }
1748         }
1749         return size;
1750 #endif
1751 }
1752
1753 /*-----------------------------------------------------------------*/
1754 /* pic14_outAcc - output Acc                                       */
1755 /*-----------------------------------------------------------------*/
1756 void pic14_outAcc(operand *result)
1757 {
1758         int size,offset;
1759         DEBUGpic14_emitcode ("; ***","%s  %d - ",__FUNCTION__,__LINE__);
1760         DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1761         
1762         
1763         size = pic14_getDataSize(result);
1764         if(size){
1765                 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1766                 size--;
1767                 offset = 1;
1768                 /* unsigned or positive */
1769                 while(size--)
1770                         emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1771         }
1772         
1773 }
1774
1775 /*-----------------------------------------------------------------*/
1776 /* pic14_outBitC - output a bit C                                  */
1777 /*-----------------------------------------------------------------*/
1778 void pic14_outBitC(operand *result)
1779 {
1780         
1781         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1782         /* if the result is bit */
1783         if (AOP_TYPE(result) == AOP_CRY) 
1784                 aopPut(AOP(result),"c",0);
1785         else {
1786                 pic14_emitcode("clr","a  ; %d", __LINE__);
1787                 pic14_emitcode("rlc","a");
1788                 pic14_outAcc(result);
1789         }
1790 }
1791
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_toBoolean - emit code for orl a,operator(sizeop)          */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_toBoolean(operand *oper)
1796 {
1797         int size = AOP_SIZE(oper) - 1;
1798         int offset = 1;
1799         
1800         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1801         
1802         if ( AOP_TYPE(oper) != AOP_ACC) {
1803                 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1804         }
1805         while (size--) {
1806                 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1807         }
1808 }
1809
1810
1811 /*-----------------------------------------------------------------*/
1812 /* genNot - generate code for ! operation                          */
1813 /*-----------------------------------------------------------------*/
1814 static void genNot (iCode *ic)
1815 {
1816         symbol *tlbl;
1817         int size;
1818         
1819         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1820         /* assign asmOps to operand & result */
1821         aopOp (IC_LEFT(ic),ic,FALSE);
1822         aopOp (IC_RESULT(ic),ic,TRUE);
1823         
1824         DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1825         /* if in bit space then a special case */
1826         if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1827                 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1828                         emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1829                         emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1830                 } else {
1831                         emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1832                         emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1833                         emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1834                 }
1835                 goto release;
1836         }
1837         
1838         size = AOP_SIZE(IC_LEFT(ic));
1839         if(size == 1) {
1840                 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1841                 emitpcode(POC_ANDLW,popGetLit(1));
1842                 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1843                 goto release;
1844         }
1845         pic14_toBoolean(IC_LEFT(ic));
1846         
1847         tlbl = newiTempLabel(NULL);
1848         pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1849         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1850         pic14_outBitC(IC_RESULT(ic));
1851         
1852 release:        
1853         /* release the aops */
1854         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1855         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1856 }
1857
1858
1859 /*-----------------------------------------------------------------*/
1860 /* genCpl - generate code for complement                                                   */
1861 /*-----------------------------------------------------------------*/
1862 static void genCpl (iCode *ic)
1863 {
1864         operand *left, *result;
1865         int size, offset=0;  
1866         
1867         
1868         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1869         aopOp((left = IC_LEFT(ic)),ic,FALSE);
1870         aopOp((result=IC_RESULT(ic)),ic,TRUE);
1871         
1872         /* if both are in bit space then 
1873         a special case */
1874         if (AOP_TYPE(result) == AOP_CRY &&
1875                 AOP_TYPE(left) == AOP_CRY ) { 
1876                 
1877                 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir); 
1878                 pic14_emitcode("cpl","c"); 
1879                 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir); 
1880                 goto release; 
1881         } 
1882         
1883         size = AOP_SIZE(result);
1884         while (size--) {
1885                 
1886                 if(AOP_TYPE(left) == AOP_ACC) 
1887                         emitpcode(POC_XORLW, popGetLit(0xff));
1888                 else
1889                         emitpcode(POC_COMFW,popGet(AOP(left),offset));
1890                 
1891                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1892                 offset++;
1893         }
1894         
1895         
1896 release:
1897         /* release the aops */
1898         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899         freeAsmop(result,NULL,ic,TRUE);
1900 }
1901
1902 /*-----------------------------------------------------------------*/
1903 /* genUminusFloat - unary minus for floating points                        */
1904 /*-----------------------------------------------------------------*/
1905 static void genUminusFloat(operand *op,operand *result)
1906 {
1907         int size ,offset =0 ;
1908         char *l;
1909         
1910         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1911         /* for this we just need to flip the 
1912         first it then copy the rest in place */
1913         size = AOP_SIZE(op) - 1;
1914         l = aopGet(AOP(op),3,FALSE,FALSE);
1915         
1916         MOVA(l);          
1917         
1918         pic14_emitcode("cpl","acc.7");
1919         aopPut(AOP(result),"a",3);      
1920         
1921         while(size--) {
1922                 aopPut(AOP(result),
1923                         aopGet(AOP(op),offset,FALSE,FALSE),
1924                         offset);
1925                 offset++;
1926         }                
1927 }
1928
1929 /*-----------------------------------------------------------------*/
1930 /* genUminus - unary minus code generation                                                 */
1931 /*-----------------------------------------------------------------*/
1932 static void genUminus (iCode *ic)
1933 {
1934         int size, i;
1935         sym_link *optype, *rtype;
1936         
1937         
1938         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1939         /* assign asmops */
1940         aopOp(IC_LEFT(ic),ic,FALSE);
1941         aopOp(IC_RESULT(ic),ic,TRUE);
1942         
1943         /* if both in bit space then special
1944         case */
1945         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1946                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
1947                 
1948                 emitpcode(POC_BCF,       popGet(AOP(IC_RESULT(ic)),0));
1949                 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1950                 emitpcode(POC_BSF,       popGet(AOP(IC_RESULT(ic)),0));
1951                 
1952                 goto release; 
1953         } 
1954         
1955         optype = operandType(IC_LEFT(ic));
1956         rtype = operandType(IC_RESULT(ic));
1957         
1958         /* if float then do float stuff */
1959         if (IS_FLOAT(optype)) {
1960                 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1961                 goto release;
1962         }
1963         
1964         /* otherwise subtract from zero by taking the 2's complement */
1965         size = AOP_SIZE(IC_LEFT(ic));
1966         
1967         for(i=0; i<size; i++) {
1968                 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1969                         emitpcode(POC_COMF,  popGet(AOP(IC_LEFT(ic)),i));
1970                 else {
1971                         emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1972                         emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1973                 }
1974         }
1975         
1976         emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),0));
1977         for(i=1; i<size; i++) {
1978                 emitSKPNZ;
1979                 emitpcode(POC_INCF,  popGet(AOP(IC_RESULT(ic)),i));
1980         }
1981         
1982 release:
1983         /* release the aops */
1984         freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1985         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);  
1986 }
1987
1988 /*-----------------------------------------------------------------*/
1989 /* saveRegisters - will look for a call and save the registers     */
1990 /*-----------------------------------------------------------------*/
1991 static void saveRegisters(iCode *lic) 
1992 {
1993         int i;
1994         iCode *ic;
1995         bitVect *rsave;
1996         sym_link *dtype;
1997         
1998         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
1999         /* look for call */
2000         for (ic = lic ; ic ; ic = ic->next) 
2001                 if (ic->op == CALL || ic->op == PCALL)
2002                         break;
2003                 
2004                 if (!ic) {
2005                         fprintf(stderr,"found parameter push with no function call\n");
2006                         return ;
2007                 }
2008                 
2009                 /* if the registers have been saved already then
2010                 do nothing */
2011                 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2012                         return ;
2013                 
2014                         /* find the registers in use at this time 
2015                 and push them away to safety */
2016                 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2017                         ic->rUsed);
2018                 
2019                 ic->regsSaved = 1;
2020                 if (options.useXstack) {
2021                         if (bitVectBitValue(rsave,R0_IDX))
2022                                 pic14_emitcode("mov","b,r0");
2023                         pic14_emitcode("mov","r0,%s",spname);
2024                         for (i = 0 ; i < pic14_nRegs ; i++) {
2025                                 if (bitVectBitValue(rsave,i)) {
2026                                         if (i == R0_IDX)
2027                                                 pic14_emitcode("mov","a,b");
2028                                         else
2029                                                 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2030                                         pic14_emitcode("movx","@r0,a");
2031                                         pic14_emitcode("inc","r0");
2032                                 }
2033                         }
2034                         pic14_emitcode("mov","%s,r0",spname);
2035                         if (bitVectBitValue(rsave,R0_IDX))
2036                                 pic14_emitcode("mov","r0,b");     
2037                 }// else
2038                 //for (i = 0 ; i < pic14_nRegs ; i++) {
2039                 //        if (bitVectBitValue(rsave,i))
2040                 //      pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2041                 //}
2042                 
2043                 dtype = operandType(IC_LEFT(ic));
2044                 if (currFunc && dtype && 
2045                         (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2046                         IFFUNC_ISISR(currFunc->type) &&
2047                         !ic->bankSaved) 
2048                         
2049                         saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2050                 
2051 }
2052 /*-----------------------------------------------------------------*/
2053 /* unsaveRegisters - pop the pushed registers                                      */
2054 /*-----------------------------------------------------------------*/
2055 static void unsaveRegisters (iCode *ic)
2056 {
2057         int i;
2058         bitVect *rsave;
2059         
2060         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2061         /* find the registers in use at this time 
2062         and push them away to safety */
2063         rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2064                 ic->rUsed);
2065         
2066         if (options.useXstack) {
2067                 pic14_emitcode("mov","r0,%s",spname); 
2068                 for (i =  pic14_nRegs ; i >= 0 ; i--) {
2069                         if (bitVectBitValue(rsave,i)) {
2070                                 pic14_emitcode("dec","r0");
2071                                 pic14_emitcode("movx","a,@r0");
2072                                 if (i == R0_IDX)
2073                                         pic14_emitcode("mov","b,a");
2074                                 else
2075                                         pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2076                         }       
2077                         
2078                 }
2079                 pic14_emitcode("mov","%s,r0",spname);
2080                 if (bitVectBitValue(rsave,R0_IDX))
2081                         pic14_emitcode("mov","r0,b");
2082         } //else
2083         //for (i =  pic14_nRegs ; i >= 0 ; i--) {
2084         //      if (bitVectBitValue(rsave,i))
2085         //  pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2086         //}
2087         
2088 }  
2089
2090
2091 /*-----------------------------------------------------------------*/
2092 /* pushSide -                            */
2093 /*-----------------------------------------------------------------*/
2094 static void pushSide(operand * oper, int size)
2095 {
2096 #if 0
2097         int offset = 0;
2098         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2099         while (size--) {
2100                 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2101                 if (AOP_TYPE(oper) != AOP_REG &&
2102                         AOP_TYPE(oper) != AOP_DIR &&
2103                         strcmp(l,"a") ) {
2104                         pic14_emitcode("mov","a,%s",l);
2105                         pic14_emitcode("push","acc");
2106                 } else
2107                         pic14_emitcode("push","%s",l);
2108         }
2109 #endif
2110 }
2111
2112 /*-----------------------------------------------------------------*/
2113 /* assignResultValue -                           */
2114 /*-----------------------------------------------------------------*/
2115 static void assignResultValue(operand * oper)
2116 {
2117         int size = AOP_SIZE(oper);
2118         
2119         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2120         
2121         DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2122         
2123         while (size--) {
2124                 if (GpsuedoStkPtr++)
2125                         emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2126                 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2127         }
2128 }
2129
2130
2131 /*-----------------------------------------------------------------*/
2132 /* genIpush - genrate code for pushing this gets a little complex  */
2133 /*-----------------------------------------------------------------*/
2134 static void genIpush (iCode *ic)
2135 {
2136         
2137         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 #if 0
2139         int size, offset = 0 ;
2140         char *l;
2141         
2142         
2143         /* if this is not a parm push : ie. it is spill push 
2144         and spill push is always done on the local stack */
2145         if (!ic->parmPush) {
2146                 
2147                 /* and the item is spilt then do nothing */
2148                 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2149                         return ;
2150                 
2151                 aopOp(IC_LEFT(ic),ic,FALSE);
2152                 size = AOP_SIZE(IC_LEFT(ic));
2153                 /* push it on the stack */
2154                 while(size--) {
2155                         l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2156                         if (*l == '#') {
2157                                 MOVA(l);
2158                                 l = "acc";
2159                         }
2160                         pic14_emitcode("push","%s",l);
2161                 }
2162                 return ;                
2163         }
2164         
2165         /* this is a paramter push: in this case we call
2166         the routine to find the call and save those
2167         registers that need to be saved */   
2168         saveRegisters(ic);
2169         
2170         /* then do the push */
2171         aopOp(IC_LEFT(ic),ic,FALSE);
2172         
2173         
2174         // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2175         size = AOP_SIZE(IC_LEFT(ic));
2176         
2177         while (size--) {
2178                 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2179                 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && 
2180                         AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2181                         strcmp(l,"a") ) {
2182                         pic14_emitcode("mov","a,%s",l);
2183                         pic14_emitcode("push","acc");
2184                 } else
2185                         pic14_emitcode("push","%s",l);
2186         }         
2187         
2188         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2189 #endif
2190 }
2191
2192 /*-----------------------------------------------------------------*/
2193 /* genIpop - recover the registers: can happen only for spilling   */
2194 /*-----------------------------------------------------------------*/
2195 static void genIpop (iCode *ic)
2196 {
2197         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2198 #if 0
2199         int size,offset ;
2200         
2201         
2202         /* if the temp was not pushed then */
2203         if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2204                 return ;
2205         
2206         aopOp(IC_LEFT(ic),ic,FALSE);
2207         size = AOP_SIZE(IC_LEFT(ic));
2208         offset = (size-1);
2209         while (size--) 
2210                 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2211                 FALSE,TRUE));
2212         
2213         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2214 #endif
2215 }
2216
2217 /*-----------------------------------------------------------------*/
2218 /* unsaverbank - restores the resgister bank from stack                    */
2219 /*-----------------------------------------------------------------*/
2220 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2221 {
2222         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2223 #if 0
2224         int i;
2225         asmop *aop ;
2226         regs *r = NULL;
2227         
2228         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2229         if (popPsw) {
2230                 if (options.useXstack) {
2231                         aop = newAsmop(0);
2232                         r = getFreePtr(ic,&aop,FALSE);
2233                         
2234                         
2235                         pic14_emitcode("mov","%s,_spx",r->name);
2236                         pic14_emitcode("movx","a,@%s",r->name);
2237                         pic14_emitcode("mov","psw,a");
2238                         pic14_emitcode("dec","%s",r->name);
2239                         
2240                 }else
2241                         pic14_emitcode ("pop","psw");
2242         }
2243         
2244         for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2245                 if (options.useXstack) {           
2246                         pic14_emitcode("movx","a,@%s",r->name);
2247                         //pic14_emitcode("mov","(%s+%d),a",
2248                         //         regspic14[i].base,8*bank+regspic14[i].offset);
2249                         pic14_emitcode("dec","%s",r->name);
2250                         
2251                 } else 
2252                         pic14_emitcode("pop",""); //"(%s+%d)",
2253                 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2254         }
2255         
2256         if (options.useXstack) {
2257                 
2258                 pic14_emitcode("mov","_spx,%s",r->name);
2259                 freeAsmop(NULL,aop,ic,TRUE);
2260                 
2261         }
2262 #endif 
2263 }
2264
2265 /*-----------------------------------------------------------------*/
2266 /* saverbank - saves an entire register bank on the stack                  */
2267 /*-----------------------------------------------------------------*/
2268 static void saverbank (int bank, iCode *ic, bool pushPsw)
2269 {
2270         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2271 #if 0
2272         int i;
2273         asmop *aop ;
2274         regs *r = NULL;
2275         
2276         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2277         if (options.useXstack) {
2278                 
2279                 aop = newAsmop(0);
2280                 r = getFreePtr(ic,&aop,FALSE);  
2281                 pic14_emitcode("mov","%s,_spx",r->name);
2282                 
2283         }
2284         
2285         for (i = 0 ; i < pic14_nRegs ;i++) {
2286                 if (options.useXstack) {
2287                         pic14_emitcode("inc","%s",r->name);
2288                         //pic14_emitcode("mov","a,(%s+%d)",
2289                         //               regspic14[i].base,8*bank+regspic14[i].offset);
2290                         pic14_emitcode("movx","@%s,a",r->name);                 
2291                 } else 
2292                         pic14_emitcode("push","");// "(%s+%d)",
2293                 //regspic14[i].base,8*bank+regspic14[i].offset);
2294         }
2295         
2296         if (pushPsw) {
2297                 if (options.useXstack) {
2298                         pic14_emitcode("mov","a,psw");
2299                         pic14_emitcode("movx","@%s,a",r->name); 
2300                         pic14_emitcode("inc","%s",r->name);
2301                         pic14_emitcode("mov","_spx,%s",r->name);                 
2302                         freeAsmop (NULL,aop,ic,TRUE);
2303                         
2304                 } else
2305                         pic14_emitcode("push","psw");
2306                 
2307                 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2308         }
2309         ic->bankSaved = 1;
2310 #endif
2311 }
2312
2313 /*-----------------------------------------------------------------*/
2314 /* genCall - generates a call statement                                                    */
2315 /*-----------------------------------------------------------------*/
2316 static void genCall (iCode *ic)
2317 {
2318         sym_link *dtype;         
2319         symbol *sym;
2320         unsigned char *name;
2321         int isExtern;
2322         
2323         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2324         
2325         /* if caller saves & we have not saved then */
2326         if (!ic->regsSaved)
2327                 saveRegisters(ic);
2328         
2329                 /* if we are calling a function that is not using
2330                 the same register bank then we need to save the
2331         destination registers on the stack */
2332         dtype = operandType(IC_LEFT(ic));
2333         if (currFunc && dtype && 
2334                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2335                 IFFUNC_ISISR(currFunc->type) &&
2336                 !ic->bankSaved) 
2337                 
2338                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2339         
2340         /* if send set is not empty the assign */
2341         if (_G.sendSet) {
2342                 iCode *sic;
2343                 /* For the Pic port, there is no data stack.
2344                 * So parameters passed to functions are stored
2345                 * in registers. (The pCode optimizer will get
2346                 * rid of most of these :).
2347                 */
2348                 int psuedoStkPtr=-1;
2349                 int firstTimeThruLoop = 1;
2350                 
2351                 _G.sendSet = reverseSet(_G.sendSet);
2352                 
2353                 /* First figure how many parameters are getting passed */
2354                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2355                 sic = setNextItem(_G.sendSet)) {
2356                         
2357                         aopOp(IC_LEFT(sic),sic,FALSE);
2358                         psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2359                         freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2360                 }
2361                 
2362                 for (sic = setFirstItem(_G.sendSet) ; sic ; 
2363                 sic = setNextItem(_G.sendSet)) {
2364                         int size, offset = 0;
2365                         
2366                         aopOp(IC_LEFT(sic),sic,FALSE);
2367                         size = AOP_SIZE(IC_LEFT(sic));
2368                         
2369                         while (size--) {
2370                                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2371                                         AopType(AOP_TYPE(IC_LEFT(sic))));
2372                                 
2373                                 if(!firstTimeThruLoop) {
2374                                 /* If this is not the first time we've been through the loop
2375                                 * then we need to save the parameter in a temporary
2376                                 * register. The last byte of the last parameter is
2377                                         * passed in W. */
2378                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2379                                         
2380                                 }
2381                                 firstTimeThruLoop=0;
2382                                 
2383                                 mov2w (AOP(IC_LEFT(sic)),  offset);
2384                                 offset++;
2385                         }
2386                         freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2387                 }
2388                 _G.sendSet = NULL;
2389         }
2390         /* make the call */
2391         sym = OP_SYMBOL(IC_LEFT(ic));
2392         name = sym->rname[0] ? sym->rname : sym->name;
2393         isExtern = IS_EXTERN(sym->etype);
2394         if (isExtern) {
2395                 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2396         }
2397         emitpcode(POC_CALL,popGetWithString(name,isExtern));
2398         if (isExtern) {
2399                 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2400         }
2401         GpsuedoStkPtr=0;
2402         /* if we need assign a result value */
2403         if ((IS_ITEMP(IC_RESULT(ic)) && 
2404                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2405                 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2406                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2407                 
2408                 _G.accInUse++;
2409                 aopOp(IC_RESULT(ic),ic,FALSE);
2410                 _G.accInUse--;
2411                 
2412                 assignResultValue(IC_RESULT(ic));
2413                 
2414                 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2415                         AopType(AOP_TYPE(IC_RESULT(ic))));
2416                 
2417                 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2418         }
2419         
2420         /* adjust the stack for parameters if 
2421         required */
2422         if (ic->parmBytes) {
2423                 int i;
2424                 if (ic->parmBytes > 3) {
2425                         pic14_emitcode("mov","a,%s",spname);
2426                         pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2427                         pic14_emitcode("mov","%s,a",spname);
2428                 } else 
2429                         for ( i = 0 ; i <  ic->parmBytes ;i++)
2430                                 pic14_emitcode("dec","%s",spname);
2431                         
2432         }
2433         
2434         /* if register bank was saved then pop them */
2435         if (ic->bankSaved)
2436                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2437         
2438         /* if we hade saved some registers then unsave them */
2439         if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2440                 unsaveRegisters (ic);
2441         
2442         
2443 }
2444
2445 /*-----------------------------------------------------------------*/
2446 /* genPcall - generates a call by pointer statement                        */
2447 /*-----------------------------------------------------------------*/
2448 static void genPcall (iCode *ic)
2449 {
2450         sym_link *dtype;
2451         symbol *albl = newiTempLabel(NULL);
2452         symbol *blbl = newiTempLabel(NULL);
2453         PIC_OPCODE poc;
2454         pCodeOp *pcop;
2455         operand *left;
2456         
2457         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2458         /* if caller saves & we have not saved then */
2459         if (!ic->regsSaved)
2460                 saveRegisters(ic);
2461         
2462                 /* if we are calling a function that is not using
2463                 the same register bank then we need to save the
2464         destination registers on the stack */
2465         dtype = operandType(IC_LEFT(ic));
2466         if (currFunc && dtype && 
2467                 IFFUNC_ISISR(currFunc->type) &&
2468                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2469                 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2470         
2471         left = IC_LEFT(ic);
2472         aopOp(left,ic,FALSE);
2473         DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2474         
2475         pushSide(IC_LEFT(ic), FPTRSIZE);
2476         
2477         /* if send set is not empty, assign parameters */
2478         if (_G.sendSet) {
2479                 
2480                 DEBUGpic14_emitcode ("; ***","%s  %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2481                 /* no way to pass args - W always gets used to make the call */
2482         }
2483         /* first idea - factor out a common helper function and call it.
2484         But don't know how to get it generated only once in its own block
2485         
2486         if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2487                 char *rname;
2488                 char *buffer;
2489                 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2490                 DEBUGpic14_emitcode ("; ***","%s  %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2491                 buffer = Safe_calloc(1,strlen(rname)+16);
2492                 sprintf(buffer, "%s_goto_helper", rname);
2493                 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2494                 free(buffer);
2495         }
2496         */
2497         emitpcode(POC_CALL,popGetLabel(albl->key));
2498         pcop = popGetLabel(blbl->key);
2499         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2500         emitpcode(POC_GOTO,pcop);
2501         emitpLabel(albl->key);
2502         
2503         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2504         
2505         emitpcode(poc,popGet(AOP(left),1));
2506         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2507         emitpcode(poc,popGet(AOP(left),0));
2508         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2509         
2510         emitpLabel(blbl->key);
2511         
2512         freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); 
2513         
2514         /* if we need to assign a result value */
2515         if ((IS_ITEMP(IC_RESULT(ic)) &&
2516                 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2517                 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2518                 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2519                 
2520                 _G.accInUse++;
2521                 aopOp(IC_RESULT(ic),ic,FALSE);
2522                 _G.accInUse--;
2523                 
2524                 assignResultValue(IC_RESULT(ic));
2525                 
2526                 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2527         }
2528         
2529         /* if register bank was saved then unsave them */
2530         if (currFunc && dtype && 
2531                 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532                 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533         
2534                 /* if we hade saved some registers then
2535         unsave them */
2536         if (ic->regsSaved)
2537                 unsaveRegisters (ic);
2538         
2539 }
2540
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result  is rematerializable                                       */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2545 {
2546         //      DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2547         if (SKIP_IC(ic) || ic->op == IFX)
2548                 return 0;
2549         
2550         if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551                 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552                 if (sym->remat && !POINTER_SET(ic)) 
2553                         return 1;
2554         }
2555         
2556         return 0;
2557 }
2558
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2561 #else
2562 #define STRCASECMP strcasecmp
2563 #endif
2564
2565 #if 0
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list   */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2570 {
2571         DEBUGpic14_emitcode ("; ***","%s  %d - WARNING no code generated",__FUNCTION__,__LINE__);
2572         int i =0;
2573         
2574         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2575         if (options.excludeRegs[i] &&
2576                 STRCASECMP(options.excludeRegs[i],"none") == 0)
2577                 return FALSE ;
2578         
2579         for ( i = 0 ; options.excludeRegs[i]; i++) {
2580                 if (options.excludeRegs[i] &&
2581                         STRCASECMP(s,options.excludeRegs[i]) == 0)
2582                         return TRUE;
2583         }
2584         return FALSE ;
2585 }
2586 #endif
2587
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry                                 */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2592 {
2593         symbol *sym;
2594         sym_link *ftype;
2595         
2596         DEBUGpic14_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2597         
2598         labelOffset += (max_key+4);
2599         max_key=0;
2600         GpsuedoStkPtr=0;
2601         _G.nRegsSaved = 0;
2602         /* create the function header */
2603         pic14_emitcode(";","-----------------------------------------");
2604         pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605         pic14_emitcode(";","-----------------------------------------");
2606         
2607         pic14_emitcode("","%s:",sym->rname);
2608         addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2609         
2610         ftype = operandType(IC_LEFT(ic));
2611         
2612         /* if critical function then turn interrupts off */
2613         if (IFFUNC_ISCRITICAL(ftype))
2614                 pic14_emitcode("clr","ea");
2615         
2616                 /* here we need to generate the equates for the
2617         register bank if required */
2618 #if 0
2619         if (FUNC_REGBANK(ftype) != rbank) {
2620                 int i ;
2621                 
2622                 rbank = FUNC_REGBANK(ftype);
2623                 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624                         if (strcmp(regspic14[i].base,"0") == 0)
2625                                 pic14_emitcode("","%s = 0x%02x",
2626                                 regspic14[i].dname,
2627                                 8*rbank+regspic14[i].offset);
2628                         else
2629                                 pic14_emitcode ("","%s = %s + 0x%02x",
2630                                 regspic14[i].dname,
2631                                 regspic14[i].base,
2632                                 8*rbank+regspic14[i].offset);
2633                 }
2634         }
2635 #endif
2636         
2637         /* if this is an interrupt service routine */
2638         if (IFFUNC_ISISR(sym->type)) {
2639         /*  already done in pic14createInterruptVect() - delete me
2640         addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641         emitpcodeNULLop(POC_NOP);
2642         emitpcodeNULLop(POC_NOP);
2643         emitpcodeNULLop(POC_NOP);
2644                 */
2645                 emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
2646                 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2647                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2648                 emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
2649                 emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
2650                 emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
2651                 emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2652                 
2653                 pBlockConvert2ISR(pb);
2654 #if 0  
2655                 if (!inExcludeList("acc"))              
2656                         pic14_emitcode ("push","acc");  
2657                 if (!inExcludeList("b"))
2658                         pic14_emitcode ("push","b");
2659                 if (!inExcludeList("dpl"))
2660                         pic14_emitcode ("push","dpl");
2661                 if (!inExcludeList("dph"))
2662                         pic14_emitcode ("push","dph");
2663                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2664                 {
2665                         pic14_emitcode ("push", "dpx");
2666                         /* Make sure we're using standard DPTR */
2667                         pic14_emitcode ("push", "dps");
2668                         pic14_emitcode ("mov", "dps, #0x00");
2669                         if (options.stack10bit)
2670                         { 
2671                                 /* This ISR could conceivably use DPTR2. Better save it. */
2672                                 pic14_emitcode ("push", "dpl1");
2673                                 pic14_emitcode ("push", "dph1");
2674                                 pic14_emitcode ("push", "dpx1");
2675                         }
2676                 }
2677                 /* if this isr has no bank i.e. is going to
2678                 run with bank 0 , then we need to save more
2679 registers :-) */
2680                 if (!FUNC_REGBANK(sym->type)) {
2681                         
2682                 /* if this function does not call any other
2683                 function then we can be economical and
2684                         save only those registers that are used */
2685                         if (! IFFUNC_HASFCALL(sym->type)) {
2686                                 int i;
2687                                 
2688                                 /* if any registers used */
2689                                 if (sym->regsUsed) {
2690                                         /* save the registers used */
2691                                         for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2692                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2693                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2694                                                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);               
2695                                         }
2696                                 }
2697                                 
2698                         } else {
2699                         /* this function has    a function call cannot
2700                         determines register usage so we will have the
2701                                 entire bank */
2702                                 saverbank(0,ic,FALSE);
2703                         }       
2704                 }
2705 #endif
2706         } else {
2707         /* if callee-save to be used for this function
2708                 then save the registers being used in this function */
2709                 if (IFFUNC_CALLEESAVES(sym->type)) {
2710                         int i;
2711                         
2712                         /* if any registers used */
2713                         if (sym->regsUsed) {
2714                                 /* save the registers used */
2715                                 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2716                                         if (bitVectBitValue(sym->regsUsed,i) ||
2717                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2718                                                 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2719                                                 _G.nRegsSaved++;
2720                                         }
2721                                 }
2722                         }
2723                 }
2724         }
2725         
2726         /* set the register bank to the desired value */
2727         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2728                 pic14_emitcode("push","psw");
2729                 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);       
2730         }
2731         
2732         if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2733                 
2734                 if (options.useXstack) {
2735                         pic14_emitcode("mov","r0,%s",spname);
2736                         pic14_emitcode("mov","a,_bp");
2737                         pic14_emitcode("movx","@r0,a");
2738                         pic14_emitcode("inc","%s",spname);
2739                 }
2740                 else
2741                 {
2742                         /* set up the stack */
2743                         pic14_emitcode ("push","_bp");   /* save the callers stack      */
2744                 }
2745                 pic14_emitcode ("mov","_bp,%s",spname);
2746         }
2747         
2748         /* adjust the stack for the function */
2749         if (sym->stack) {
2750                 
2751                 int i = sym->stack;
2752                 if (i > 256 ) 
2753                         werror(W_STACK_OVERFLOW,sym->name);
2754                 
2755                 if (i > 3 && sym->recvSize < 4) {                
2756                         
2757                         pic14_emitcode ("mov","a,sp");
2758                         pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2759                         pic14_emitcode ("mov","sp,a");
2760                         
2761                 }
2762                 else
2763                         while(i--)
2764                                 pic14_emitcode("inc","sp");
2765         }
2766         
2767         if (sym->xstack) {
2768                 
2769                 pic14_emitcode ("mov","a,_spx");
2770                 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2771                 pic14_emitcode ("mov","_spx,a");
2772         }
2773         
2774 }
2775
2776 /*-----------------------------------------------------------------*/
2777 /* genEndFunction - generates epilogue for functions                       */
2778 /*-----------------------------------------------------------------*/
2779 static void genEndFunction (iCode *ic)
2780 {
2781         symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2782         
2783         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2784         
2785         if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2786         {
2787                 pic14_emitcode ("mov","%s,_bp",spname);
2788         }
2789         
2790         /* if use external stack but some variables were
2791         added to the local stack then decrement the
2792         local stack */
2793         if (options.useXstack && sym->stack) {    
2794                 pic14_emitcode("mov","a,sp");
2795                 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2796                 pic14_emitcode("mov","sp,a");
2797         }
2798         
2799         
2800         if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2801                 if (options.useXstack) {
2802                         pic14_emitcode("mov","r0,%s",spname);
2803                         pic14_emitcode("movx","a,@r0");
2804                         pic14_emitcode("mov","_bp,a");
2805                         pic14_emitcode("dec","%s",spname);
2806                 }
2807                 else
2808                 {
2809                         pic14_emitcode ("pop","_bp");
2810                 }
2811         }
2812         
2813         /* restore the register bank    */        
2814         if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2815                 pic14_emitcode ("pop","psw");
2816         
2817         if (IFFUNC_ISISR(sym->type)) {
2818                 
2819                 /* now we need to restore the registers */
2820                 /* if this isr has no bank i.e. is going to
2821                 run with bank 0 , then we need to save more
2822 registers :-) */
2823                 if (!FUNC_REGBANK(sym->type)) {
2824                         
2825                 /* if this function does not call any other
2826                 function then we can be economical and
2827                         save only those registers that are used */
2828                         if (! IFFUNC_HASFCALL(sym->type)) {
2829                                 int i;
2830                                 
2831                                 /* if any registers used */
2832                                 if (sym->regsUsed) {
2833                                         /* save the registers used */
2834                                         for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2835                                                 if (bitVectBitValue(sym->regsUsed,i) ||
2836                                                         (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2837                                                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2838                                         }
2839                                 }
2840                                 
2841                         } else {
2842                         /* this function has    a function call cannot
2843                         determines register usage so we will have the
2844                                 entire bank */
2845                                 unsaverbank(0,ic,FALSE);
2846                         }       
2847                 }
2848 #if 0
2849                 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2850                 {
2851                         if (options.stack10bit)
2852                         {
2853                                 pic14_emitcode ("pop", "dpx1");
2854                                 pic14_emitcode ("pop", "dph1");
2855                                 pic14_emitcode ("pop", "dpl1");
2856                         } 
2857                         pic14_emitcode ("pop", "dps");
2858                         pic14_emitcode ("pop", "dpx");
2859                 }
2860                 if (!inExcludeList("dph"))
2861                         pic14_emitcode ("pop","dph");
2862                 if (!inExcludeList("dpl"))
2863                         pic14_emitcode ("pop","dpl");
2864                 if (!inExcludeList("b"))
2865                         pic14_emitcode ("pop","b");
2866                 if (!inExcludeList("acc"))
2867                         pic14_emitcode ("pop","acc");
2868                 
2869                 if (IFFUNC_ISCRITICAL(sym->type))
2870                         pic14_emitcode("setb","ea");
2871 #endif
2872                 
2873                 /* if debug then send end of function */
2874                 /*      if (options.debug && currFunc) { */
2875                 if (currFunc) {
2876                         debugFile->writeEndFunction (currFunc, ic, 1);
2877                 }
2878                 
2879                 pic14_emitcode ("reti","");
2880                 emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
2881                 emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
2882                 emitpcode(POC_CLRF,   popCopyReg(&pc_status));
2883                 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2884                 emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
2885                 emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
2886                 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2887                 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2888                 emitpcodeNULLop(POC_RETFIE);
2889         }
2890         else {
2891                 if (IFFUNC_ISCRITICAL(sym->type))
2892                         pic14_emitcode("setb","ea");
2893                 
2894                 if (IFFUNC_CALLEESAVES(sym->type)) {
2895                         int i;
2896                         
2897                         /* if any registers used */
2898                         if (sym->regsUsed) {
2899                                 /* save the registers used */
2900                                 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2901                                         if (bitVectBitValue(sym->regsUsed,i) ||
2902                                                 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2903                                                 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2904                                 }
2905                         }
2906                         
2907                 }
2908                 
2909                 /* if debug then send end of function */
2910                 if (currFunc) {
2911                         debugFile->writeEndFunction (currFunc, ic, 1);
2912                 }
2913                 
2914                 pic14_emitcode ("return","");
2915                 emitpcodeNULLop(POC_RETURN);
2916                 
2917                 /* Mark the end of a function */
2918                 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2919         }
2920         
2921 }
2922
2923 /*-----------------------------------------------------------------*/
2924 /* genRet - generate code for return statement                                     */
2925 /*-----------------------------------------------------------------*/
2926 static void genRet (iCode *ic)
2927 {
2928         int size,offset = 0 , pushed = 0;
2929         
2930         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2931         /* if we have no return value then
2932         just generate the "ret" */
2933         if (!IC_LEFT(ic)) 
2934                 goto jumpret;           
2935         
2936                 /* we have something to return then
2937         move the return value into place */
2938         aopOp(IC_LEFT(ic),ic,FALSE);
2939         size = AOP_SIZE(IC_LEFT(ic));
2940         
2941         while (size--) {
2942                 char *l ;
2943                 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2944                         /* #NOCHANGE */
2945                         l = aopGet(AOP(IC_LEFT(ic)),offset++,
2946                                 FALSE,TRUE);
2947                         pic14_emitcode("push","%s",l);
2948                         pushed++;
2949                 } else {
2950                         l = aopGet(AOP(IC_LEFT(ic)),offset,
2951                                 FALSE,FALSE);
2952                         if (strcmp(fReturn[offset],l)) {
2953                                 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) && 
2954                                         AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2955                                         ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2956                                         ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2957                                         emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2958                                 }else {
2959                                         emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2960                                 }
2961                                 if(size) {
2962                                         emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2963                                 }
2964                                 offset++;
2965                         }
2966                 }
2967         }
2968         
2969         if (pushed) {
2970                 while(pushed) {
2971                         pushed--;
2972                         if (strcmp(fReturn[pushed],"a"))
2973                                 pic14_emitcode("pop",fReturn[pushed]);
2974                         else
2975                                 pic14_emitcode("pop","acc");
2976                 }
2977         }
2978         freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2979         
2980 jumpret:
2981 /* generate a jump to the return label
2982         if the next is not the return statement */
2983         if (!(ic->next && ic->next->op == LABEL &&
2984                 IC_LABEL(ic->next) == returnLabel)) {
2985                 
2986                 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2987                 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2988         }
2989         
2990 }
2991
2992 /*-----------------------------------------------------------------*/
2993 /* genLabel - generates a label                                                                    */
2994 /*-----------------------------------------------------------------*/
2995 static void genLabel (iCode *ic)
2996 {
2997         /* special case never generate */
2998         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
2999         if (IC_LABEL(ic) == entryLabel)
3000                 return ;
3001         
3002         emitpLabel(IC_LABEL(ic)->key);
3003         pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3004 }
3005
3006 /*-----------------------------------------------------------------*/
3007 /* genGoto - generates a goto                                                                      */
3008 /*-----------------------------------------------------------------*/
3009 //tsd
3010 static void genGoto (iCode *ic)
3011 {
3012         emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3013         pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3014 }
3015
3016
3017 /*-----------------------------------------------------------------*/
3018 /* genMultbits :- multiplication of bits                                                   */
3019 /*-----------------------------------------------------------------*/
3020 static void genMultbits (operand *left, 
3021                                                  operand *right, 
3022                                                  operand *result)
3023 {
3024         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3025         
3026         if(!pic14_sameRegs(AOP(result),AOP(right)))
3027                 emitpcode(POC_BSF,      popGet(AOP(result),0));
3028         
3029         emitpcode(POC_BTFSC,popGet(AOP(right),0));
3030         emitpcode(POC_BTFSS,popGet(AOP(left),0));
3031         emitpcode(POC_BCF,  popGet(AOP(result),0));
3032         
3033 }
3034
3035
3036 /*-----------------------------------------------------------------*/
3037 /* genMultOneByte : 8 bit multiplication & division                        */
3038 /*-----------------------------------------------------------------*/
3039 static void genMultOneByte (operand *left,
3040                                                         operand *right,
3041                                                         operand *result)
3042 {
3043         sym_link *opetype = operandType(result);
3044         
3045         // symbol *lbl ;
3046         int size,offset;
3047         
3048         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3049         DEBUGpic14_AopType(__LINE__,left,right,result);
3050         DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3051         
3052         /* (if two literals, the value is computed before) */
3053         /* if one literal, literal on the right */
3054         if (AOP_TYPE(left) == AOP_LIT){
3055                 operand *t = right;
3056                 right = left;
3057                 left = t;
3058         }
3059         
3060         size = AOP_SIZE(result);
3061         if(size == 1) {
3062                 
3063                 if (AOP_TYPE(right) == AOP_LIT){
3064                         pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s", 
3065                                 aopGet(AOP(right),0,FALSE,FALSE), 
3066                                 aopGet(AOP(left),0,FALSE,FALSE), 
3067                                 aopGet(AOP(result),0,FALSE,FALSE));
3068                         pic14_emitcode("call","genMultLit");
3069                 } else {
3070                         pic14_emitcode("multiply ","variable :%s by variable %s and store in %s", 
3071                                 aopGet(AOP(right),0,FALSE,FALSE), 
3072                                 aopGet(AOP(left),0,FALSE,FALSE), 
3073                                 aopGet(AOP(result),0,FALSE,FALSE));
3074                         pic14_emitcode("call","genMult8X8_8");
3075                         
3076                 }
3077                 genMult8X8_8 (left, right,result);
3078                 
3079                 
3080                 /* signed or unsigned */
3081                 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3082                 //l = aopGet(AOP(left),0,FALSE,FALSE);
3083                 //MOVA(l);               
3084                 //pic14_emitcode("mul","ab");
3085                 /* if result size = 1, mul signed = mul unsigned */
3086                 //aopPut(AOP(result),"a",0);
3087                 
3088         } else {        // (size > 1)
3089                 
3090                 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
3091                         aopGet(AOP(right),0,FALSE,FALSE), 
3092                         aopGet(AOP(left),0,FALSE,FALSE), 
3093                         aopGet(AOP(result),0,FALSE,FALSE));
3094                 
3095                 if (SPEC_USIGN(opetype)){
3096                         pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3097                         genUMult8X8_16 (left, right, result, NULL);
3098                         
3099                         if (size > 2) {
3100                                 /* for filling the MSBs */
3101                                 emitpcode(POC_CLRF,  popGet(AOP(result),2));
3102                                 emitpcode(POC_CLRF,  popGet(AOP(result),3));
3103                         }
3104                 }
3105                 else{
3106                         pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3107                         
3108                         pic14_emitcode("mov","a,b");
3109                         
3110                         /* adjust the MSB if left or right neg */
3111                         
3112                         /* if one literal */
3113                         if (AOP_TYPE(right) == AOP_LIT){
3114                                 pic14_emitcode("multiply ","right is a lit");
3115                                 /* AND literal negative */
3116                                 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3117                                         /* adjust MSB (c==0 after mul) */
3118                                         pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3119                                 }
3120                         }
3121                         else{
3122                                 genSMult8X8_16 (left, right, result, NULL);
3123                         }
3124                         
3125                         if(size > 2){
3126                                 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3127                                 /* get the sign */
3128                                 pic14_emitcode("rlc","a");
3129                                 pic14_emitcode("subb","a,acc");
3130                         }
3131                 }
3132                 
3133                 size -= 2;
3134                 offset = 2;
3135                 if (size > 0)
3136                         while (size--)
3137                                 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3138                         //aopPut(AOP(result),"a",offset++);
3139         }
3140 }
3141
3142 /*-----------------------------------------------------------------*/
3143 /* genMult - generates code for multiplication                                     */
3144 /*-----------------------------------------------------------------*/
3145 static void genMult (iCode *ic)
3146 {
3147         operand *left = IC_LEFT(ic);
3148         operand *right = IC_RIGHT(ic);
3149         operand *result= IC_RESULT(ic); 
3150         
3151         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3152         /* assign the amsops */
3153         aopOp (left,ic,FALSE);
3154         aopOp (right,ic,FALSE);
3155         aopOp (result,ic,TRUE);
3156         
3157         DEBUGpic14_AopType(__LINE__,left,right,result);
3158         
3159         /* special cases first */
3160         /* both are bits */
3161         if (AOP_TYPE(left) == AOP_CRY &&
3162                 AOP_TYPE(right)== AOP_CRY) {
3163                 genMultbits(left,right,result);
3164                 goto release ;
3165         }
3166         
3167         /* if both are of size == 1 */
3168         if (AOP_SIZE(left) == 1 &&
3169                 AOP_SIZE(right) == 1 ) {
3170                 genMultOneByte(left,right,result);
3171                 goto release ;
3172         }
3173         
3174         pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3175         
3176         /* should have been converted to function call */
3177         //assert(0) ;
3178         
3179 release :
3180         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3181         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182         freeAsmop(result,NULL,ic,TRUE); 
3183 }
3184
3185 /*-----------------------------------------------------------------*/
3186 /* genDivbits :- division of bits                                                                  */
3187 /*-----------------------------------------------------------------*/
3188 static void genDivbits (operand *left, 
3189                                                 operand *right, 
3190                                                 operand *result)
3191 {
3192         
3193         char *l;
3194         
3195         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3196         /* the result must be bit */      
3197         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3198         l = aopGet(AOP(left),0,FALSE,FALSE);
3199         
3200         MOVA(l);          
3201         
3202         pic14_emitcode("div","ab");
3203         pic14_emitcode("rrc","a");
3204         aopPut(AOP(result),"c",0);
3205 }
3206
3207 /*-----------------------------------------------------------------*/
3208 /* genDivOneByte : 8 bit division                                                                  */
3209 /*-----------------------------------------------------------------*/
3210 static void genDivOneByte (operand *left,
3211                                                    operand *right,
3212                                                    operand *result)
3213 {
3214         sym_link *opetype = operandType(result);
3215         char *l ;
3216         symbol *lbl ;
3217         int size,offset;
3218         
3219         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3220         size = AOP_SIZE(result) - 1;
3221         offset = 1;
3222         /* signed or unsigned */
3223         if (SPEC_USIGN(opetype)) {
3224                 /* unsigned is easy */
3225                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3226                 l = aopGet(AOP(left),0,FALSE,FALSE);
3227                 MOVA(l);                
3228                 pic14_emitcode("div","ab");
3229                 aopPut(AOP(result),"a",0);
3230                 while (size--)
3231                         aopPut(AOP(result),zero,offset++);
3232                 return ;
3233         }
3234         
3235         /* signed is a little bit more difficult */
3236         
3237         /* save the signs of the operands */
3238         l = aopGet(AOP(left),0,FALSE,FALSE);      
3239         MOVA(l);          
3240         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3241         pic14_emitcode("push","acc"); /* save it on the stack */
3242         
3243         /* now sign adjust for both left & right */
3244         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3245         MOVA(l);                 
3246         lbl = newiTempLabel(NULL);
3247         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));   
3248         pic14_emitcode("cpl","a");   
3249         pic14_emitcode("inc","a");
3250         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3251         pic14_emitcode("mov","b,a");
3252         
3253         /* sign adjust left side */
3254         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3255         MOVA(l);
3256         
3257         lbl = newiTempLabel(NULL);
3258         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3259         pic14_emitcode("cpl","a");
3260         pic14_emitcode("inc","a");
3261         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3262         
3263         /* now the division */
3264         pic14_emitcode("div","ab");
3265         /* we are interested in the lower order
3266         only */
3267         pic14_emitcode("mov","b,a");
3268         lbl = newiTempLabel(NULL);
3269         pic14_emitcode("pop","acc");     
3270         /* if there was an over flow we don't 
3271         adjust the sign of the result */
3272         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3273         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3274         CLRC;
3275         pic14_emitcode("clr","a");
3276         pic14_emitcode("subb","a,b");
3277         pic14_emitcode("mov","b,a");
3278         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3279         
3280         /* now we are done */
3281         aopPut(AOP(result),"b",0);
3282         if(size > 0){
3283                 pic14_emitcode("mov","c,b.7");
3284                 pic14_emitcode("subb","a,acc");   
3285         }
3286         while (size--)
3287                 aopPut(AOP(result),"a",offset++);
3288         
3289 }
3290
3291 /*-----------------------------------------------------------------*/
3292 /* genDiv - generates code for division                                                    */
3293 /*-----------------------------------------------------------------*/
3294 static void genDiv (iCode *ic)
3295 {
3296         operand *left = IC_LEFT(ic);
3297         operand *right = IC_RIGHT(ic);
3298         operand *result= IC_RESULT(ic); 
3299         
3300         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3301         /* assign the amsops */
3302         aopOp (left,ic,FALSE);
3303         aopOp (right,ic,FALSE);
3304         aopOp (result,ic,TRUE);
3305         
3306         /* special cases first */
3307         /* both are bits */
3308         if (AOP_TYPE(left) == AOP_CRY &&
3309                 AOP_TYPE(right)== AOP_CRY) {
3310                 genDivbits(left,right,result);
3311                 goto release ;
3312         }
3313         
3314         /* if both are of size == 1 */
3315         if (AOP_SIZE(left) == 1 &&
3316                 AOP_SIZE(right) == 1 ) {
3317                 genDivOneByte(left,right,result);
3318                 goto release ;
3319         }
3320         
3321         /* should have been converted to function call */
3322         assert(0);
3323 release :
3324         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3325         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3326         freeAsmop(result,NULL,ic,TRUE); 
3327 }
3328
3329 /*-----------------------------------------------------------------*/
3330 /* genModbits :- modulus of bits                                                                   */
3331 /*-----------------------------------------------------------------*/
3332 static void genModbits (operand *left, 
3333                                                 operand *right, 
3334                                                 operand *result)
3335 {
3336         
3337         char *l;
3338         
3339         /* the result must be bit */      
3340         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3341         l = aopGet(AOP(left),0,FALSE,FALSE);
3342         
3343         MOVA(l);
3344         
3345         pic14_emitcode("div","ab");
3346         pic14_emitcode("mov","a,b");
3347         pic14_emitcode("rrc","a");
3348         aopPut(AOP(result),"c",0);
3349 }
3350
3351 /*-----------------------------------------------------------------*/
3352 /* genModOneByte : 8 bit modulus                                                                   */
3353 /*-----------------------------------------------------------------*/
3354 static void genModOneByte (operand *left,
3355                                                    operand *right,
3356                                                    operand *result)
3357 {
3358         sym_link *opetype = operandType(result);
3359         char *l ;
3360         symbol *lbl ;
3361         
3362         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3363         /* signed or unsigned */
3364         if (SPEC_USIGN(opetype)) {
3365                 /* unsigned is easy */
3366                 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3367                 l = aopGet(AOP(left),0,FALSE,FALSE);
3368                 MOVA(l);        
3369                 pic14_emitcode("div","ab");
3370                 aopPut(AOP(result),"b",0);
3371                 return ;
3372         }
3373         
3374         /* signed is a little bit more difficult */
3375         
3376         /* save the signs of the operands */
3377         l = aopGet(AOP(left),0,FALSE,FALSE);      
3378         MOVA(l);
3379         
3380         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3381         pic14_emitcode("push","acc"); /* save it on the stack */
3382         
3383         /* now sign adjust for both left & right */
3384         l =  aopGet(AOP(right),0,FALSE,FALSE);  
3385         MOVA(l);
3386         
3387         lbl = newiTempLabel(NULL);
3388         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));  
3389         pic14_emitcode("cpl","a");   
3390         pic14_emitcode("inc","a");
3391         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3392         pic14_emitcode("mov","b,a"); 
3393         
3394         /* sign adjust left side */
3395         l =  aopGet(AOP(left),0,FALSE,FALSE);    
3396         MOVA(l);
3397         
3398         lbl = newiTempLabel(NULL);
3399         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3400         pic14_emitcode("cpl","a");   
3401         pic14_emitcode("inc","a");
3402         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3403         
3404         /* now the multiplication */
3405         pic14_emitcode("div","ab");
3406         /* we are interested in the lower order
3407         only */
3408         lbl = newiTempLabel(NULL);
3409         pic14_emitcode("pop","acc");     
3410         /* if there was an over flow we don't 
3411         adjust the sign of the result */
3412         pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3413         pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3414         CLRC ;
3415         pic14_emitcode("clr","a");
3416         pic14_emitcode("subb","a,b");
3417         pic14_emitcode("mov","b,a");
3418         pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3419         
3420         /* now we are done */
3421         aopPut(AOP(result),"b",0);
3422         
3423 }
3424
3425 /*-----------------------------------------------------------------*/
3426 /* genMod - generates code for division                                                    */
3427 /*-----------------------------------------------------------------*/
3428 static void genMod (iCode *ic)
3429 {
3430         operand *left = IC_LEFT(ic);
3431         operand *right = IC_RIGHT(ic);
3432         operand *result= IC_RESULT(ic);  
3433         
3434         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3435         /* assign the amsops */
3436         aopOp (left,ic,FALSE);
3437         aopOp (right,ic,FALSE);
3438         aopOp (result,ic,TRUE);
3439         
3440         /* special cases first */
3441         /* both are bits */
3442         if (AOP_TYPE(left) == AOP_CRY &&
3443                 AOP_TYPE(right)== AOP_CRY) {
3444                 genModbits(left,right,result);
3445                 goto release ;
3446         }
3447         
3448         /* if both are of size == 1 */
3449         if (AOP_SIZE(left) == 1 &&
3450                 AOP_SIZE(right) == 1 ) {
3451                 genModOneByte(left,right,result);
3452                 goto release ;
3453         }
3454         
3455         /* should have been converted to function call */
3456         assert(0);
3457         
3458 release :
3459         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3460         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3461         freeAsmop(result,NULL,ic,TRUE); 
3462 }
3463
3464 /*-----------------------------------------------------------------*/
3465 /* genIfxJump :- will create a jump depending on the ifx                   */
3466 /*-----------------------------------------------------------------*/
3467 /*
3468 note: May need to add parameter to indicate when a variable is in bit space.
3469 */
3470 static void genIfxJump (iCode *ic, char *jval)
3471 {
3472         
3473         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3474         /* if true label then we jump if condition
3475         supplied is true */
3476         if ( IC_TRUE(ic) ) {
3477                 
3478                 if(strcmp(jval,"a") == 0)
3479                         emitSKPZ;
3480                 else if (strcmp(jval,"c") == 0)
3481                         emitSKPC;
3482                 else {
3483                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3484                         emitpcode(POC_BTFSC,    newpCodeOpBit(jval,-1,1));
3485                 }
3486                 
3487                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3488                 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3489                 
3490         }
3491         else {
3492                 /* false label is present */
3493                 if(strcmp(jval,"a") == 0)
3494                         emitSKPNZ;
3495                 else if (strcmp(jval,"c") == 0)
3496                         emitSKPNC;
3497                 else {
3498                         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); 
3499                         emitpcode(POC_BTFSS,    newpCodeOpBit(jval,-1,1));
3500                 }
3501                 
3502                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3503                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3504                 
3505         }
3506         
3507         
3508         /* mark the icode as generated */
3509         ic->generated = 1;
3510 }
3511
3512 /*-----------------------------------------------------------------*/
3513 /* genSkip                                                                                                                 */
3514 /*-----------------------------------------------------------------*/
3515 static void genSkip(iCode *ifx,int status_bit)
3516 {
3517         if(!ifx)
3518                 return;
3519         
3520         if ( IC_TRUE(ifx) ) {
3521                 switch(status_bit) {
3522                 case 'z':
3523                         emitSKPNZ;
3524                         break;
3525                         
3526                 case 'c':
3527                         emitSKPNC;
3528                         break;
3529                         
3530                 case 'd':
3531                         emitSKPDC;
3532                         break;
3533                         
3534                 }
3535                 
3536                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3537                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3538                 
3539         } else {
3540                 
3541                 switch(status_bit) {
3542                         
3543                 case 'z':
3544                         emitSKPZ;
3545                         break;
3546                         
3547                 case 'c':
3548                         emitSKPC;
3549                         break;
3550                         
3551                 case 'd':
3552                         emitSKPDC;
3553                         break;
3554                 }
3555                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3556                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3557                 
3558         }
3559         
3560 }
3561
3562 /*-----------------------------------------------------------------*/
3563 /* genSkipc                                                                                                        */
3564 /*-----------------------------------------------------------------*/
3565 static void genSkipc(resolvedIfx *rifx)
3566 {
3567         if(!rifx)
3568                 return;
3569         
3570         if(rifx->condition)
3571                 emitSKPC;
3572         else
3573                 emitSKPNC;
3574         
3575         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3576         rifx->generated = 1;
3577 }
3578
3579 /*-----------------------------------------------------------------*/
3580 /* genSkipz2                                                                                                       */
3581 /*-----------------------------------------------------------------*/
3582 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3583 {
3584         if(!rifx)
3585                 return;
3586         
3587         if( (rifx->condition ^ invert_condition) & 1)
3588                 emitSKPZ;
3589         else
3590                 emitSKPNZ;
3591         
3592         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3593         rifx->generated = 1;
3594 }
3595
3596 /*-----------------------------------------------------------------*/
3597 /* genSkipz                                                        */
3598 /*-----------------------------------------------------------------*/
3599 static void genSkipz(iCode *ifx, int condition)
3600 {
3601         if(!ifx)
3602                 return;
3603         
3604         if(condition)
3605                 emitSKPNZ;
3606         else
3607                 emitSKPZ;
3608         
3609         if ( IC_TRUE(ifx) )
3610                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3611         else
3612                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3613         
3614         if ( IC_TRUE(ifx) )
3615                 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3616         else
3617                 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3618         
3619 }
3620 /*-----------------------------------------------------------------*/
3621 /* genSkipCond                                                     */
3622 /*-----------------------------------------------------------------*/
3623 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3624 {
3625         if(!rifx)
3626                 return;
3627         
3628         if(rifx->condition)
3629                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3630         else
3631                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3632         
3633         
3634         emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3635         rifx->generated = 1;
3636 }
3637
3638 #if 0
3639 /*-----------------------------------------------------------------*/
3640 /* genChkZeroes :- greater or less than comparison                 */
3641 /*     For each byte in a literal that is zero, inclusive or the   */
3642 /*     the corresponding byte in the operand with W                */
3643 /*     returns true if any of the bytes are zero                   */
3644 /*-----------------------------------------------------------------*/
3645 static int genChkZeroes(operand *op, int lit,  int size)
3646 {
3647         
3648         int i;
3649         int flag =1;
3650         
3651         while(size--) {
3652                 i = (lit >> (size*8)) & 0xff;
3653                 
3654                 if(i==0) {
3655                         if(flag) 
3656                                 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3657                         else
3658                                 emitpcode(POC_IORFW, popGet(AOP(op),size));
3659                         flag = 0;
3660                 }
3661         }
3662         
3663         return (flag==0);
3664 }
3665 #endif
3666
3667 /*-----------------------------------------------------------------*/
3668 /* genCmp :- greater or less than comparison                       */
3669 /*-----------------------------------------------------------------*/
3670 static void genCmp (operand *left,operand *right,
3671                                         operand *result, iCode *ifx, int sign)
3672 {
3673         int size; //, offset = 0 ;
3674         unsigned long lit = 0L,i = 0;
3675         resolvedIfx rFalseIfx;
3676         //  resolvedIfx rTrueIfx;
3677         symbol *truelbl;
3678         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
3679         /*
3680         if(ifx) {
3681         DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3682         DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3683         }
3684         */
3685         
3686         resolveIfx(&rFalseIfx,ifx);
3687         truelbl  = newiTempLabel(NULL);
3688         size = max(AOP_SIZE(left),AOP_SIZE(right));
3689         
3690         DEBUGpic14_AopType(__LINE__,left,right,result);
3691         
3692 #define _swapp
3693         
3694         /* if literal is on the right then swap with left */
3695         if ((AOP_TYPE(right) == AOP_LIT)) {
3696                 operand *tmp = right ;
3697                 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3698                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3699 #ifdef _swapp
3700                 
3701                 lit = (lit - 1) & mask;
3702                 right = left;
3703                 left = tmp;
3704                 rFalseIfx.condition ^= 1;
3705 #endif
3706                 
3707         } else if ((AOP_TYPE(left) == AOP_LIT)) {
3708                 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3709         }
3710         
3711         
3712         //if(IC_TRUE(ifx) == NULL)
3713         /* if left & right are bit variables */
3714         if (AOP_TYPE(left) == AOP_CRY &&
3715                 AOP_TYPE(right) == AOP_CRY ) {
3716                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3717                 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3718         } else {
3719         /* subtract right from left if at the
3720         end the carry flag is set then we know that
3721                 left is greater than right */
3722                 
3723                 symbol *lbl  = newiTempLabel(NULL);
3724                 
3725 #ifndef _swapp
3726                 if(AOP_TYPE(right) == AOP_LIT) {
3727                         
3728                         //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3729                         
3730                         DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3731                         
3732                         /* special cases */
3733                         
3734                         if(lit == 0) {
3735                                 
3736                                 if(sign != 0) 
3737                                         genSkipCond(&rFalseIfx,left,size-1,7);
3738                                 else 
3739                                         /* no need to compare to 0...*/
3740                                         /* NOTE: this is a de-generate compare that most certainly 
3741                                         *       creates some dead code. */
3742                                         emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3743                                 
3744                                 if(ifx) ifx->generated = 1;
3745                                 return;
3746                                 
3747                         }
3748                         size--;
3749                         
3750                         if(size == 0) {
3751                                 //i = (lit >> (size*8)) & 0xff;
3752                                 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3753                                 
3754                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3755                                 
3756                                 i = ((0-lit) & 0xff);
3757                                 if(sign) {
3758                                         if( i == 0x81) { 
3759                                         /* lit is 0x7f, all signed chars are less than
3760                                                 * this except for 0x7f itself */
3761                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
3762                                                 genSkipz2(&rFalseIfx,0);
3763                                         } else {
3764                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
3765                                                 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3766                                                 genSkipc(&rFalseIfx);
3767                                         }
3768                                         
3769                                 } else {
3770                                         if(lit == 1) {
3771                                                 genSkipz2(&rFalseIfx,1);
3772                                         } else {
3773                                                 emitpcode(POC_ADDLW, popGetLit(i));
3774                                                 genSkipc(&rFalseIfx);
3775                                         }
3776                                 }
3777                                 
3778                                 if(ifx) ifx->generated = 1;
3779                                 return;
3780                         }
3781                         
3782                         /* chars are out of the way. now do ints and longs */
3783                         
3784                         
3785                         DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3786                         
3787                         /* special cases */
3788                         
3789                         if(sign) {
3790                                 
3791                                 if(lit == 0) {
3792                                         genSkipCond(&rFalseIfx,left,size,7);
3793                                         if(ifx) ifx->generated = 1;
3794                                         return;
3795                                 }
3796                                 
3797                                 if(lit <0x100) {
3798                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3799                                         
3800                                         //rFalseIfx.condition ^= 1;
3801                                         //genSkipCond(&rFalseIfx,left,size,7);
3802                                         //rFalseIfx.condition ^= 1;
3803                                         
3804                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3805                                         if(rFalseIfx.condition)
3806                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3807                                         else
3808                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3809                                         
3810                                         emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3811                                         emitpcode(POC_ADDFW, popGet(AOP(left),0));
3812                                         emitpcode(POC_MOVFW, popGet(AOP(left),1));
3813                                         
3814                                         while(size > 1)
3815                                                 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3816                                         
3817                                         if(rFalseIfx.condition) {
3818                                                 emitSKPZ;
3819                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3820                                                 
3821                                         } else {
3822                                                 emitSKPNZ;
3823                                         }
3824                                         
3825                                         genSkipc(&rFalseIfx);
3826                                         emitpLabel(truelbl->key);
3827                                         if(ifx) ifx->generated = 1;
3828                                         return;
3829                                         
3830                                 }
3831                                 
3832                                 if(size == 1) {
3833                                         
3834                                         if( (lit & 0xff) == 0) {
3835                                                 /* lower byte is zero */
3836                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3837                                                 i = ((lit >> 8) & 0xff) ^0x80;
3838                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3839                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3840                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3841                                                 genSkipc(&rFalseIfx);
3842                                                 
3843                                                 
3844                                                 if(ifx) ifx->generated = 1;
3845                                                 return;
3846                                                 
3847                                         }
3848                                 } else {
3849                                         /* Special cases for signed longs */
3850                                         if( (lit & 0xffffff) == 0) {
3851                                                 /* lower byte is zero */
3852                                                 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3853                                                 i = ((lit >> 8*3) & 0xff) ^0x80;
3854                                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3855                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
3856                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3857                                                 genSkipc(&rFalseIfx);
3858                                                 
3859                                                 
3860                                                 if(ifx) ifx->generated = 1;
3861                                                 return;
3862                                                 
3863                                         }
3864                                         
3865                                 }
3866                                 
3867                                 
3868                                 if(lit & (0x80 << (size*8))) {
3869                                         /* lit is negative */
3870                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3871                                         
3872                                         //genSkipCond(&rFalseIfx,left,size,7);
3873                                         
3874                                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3875                                         
3876                                         if(rFalseIfx.condition)
3877                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3878                                         else
3879                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3880                                         
3881                                         
3882                                 } else {
3883                                         /* lit is positive */
3884                                         DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3885                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3886                                         if(rFalseIfx.condition)
3887                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
3888                                         else
3889                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
3890                                         
3891                                 }
3892                                 
3893                                 /* There are no more special cases, so perform a general compare */
3894                                 
3895                                 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3896                                 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3897                                 
3898                                 while(size--) {
3899                                         
3900                                         emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3901                                         emitSKPNZ;
3902                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3903                                 }
3904                                 //rFalseIfx.condition ^= 1;
3905                                 genSkipc(&rFalseIfx);
3906                                 
3907                                 emitpLabel(truelbl->key);
3908                                 
3909                                 if(ifx) ifx->generated = 1;
3910                                 return;
3911                                 
3912                                 
3913                         }
3914
3915
3916                         /* sign is out of the way. So now do an unsigned compare */
3917                         DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3918
3919
3920                         /* General case - compare to an unsigned literal on the right.*/
3921
3922                         i = (lit >> (size*8)) & 0xff;
3923                         emitpcode(POC_MOVLW, popGetLit(i));
3924                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3925                         while(size--) {
3926                                 i = (lit >> (size*8)) & 0xff;
3927                                 
3928                                 if(i) {
3929                                         emitpcode(POC_MOVLW, popGetLit(i));
3930                                         emitSKPNZ;
3931                                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
3932                                 } else {
3933                                 /* this byte of the lit is zero, 
3934                                         *if it's not the last then OR in the variable */
3935                                         if(size)
3936                                                 emitpcode(POC_IORFW, popGet(AOP(left),size));
3937                                 }
3938                         }
3939
3940
3941                 emitpLabel(lbl->key);
3942                 //if(emitFinalCheck)
3943                 genSkipc(&rFalseIfx);
3944                 if(sign)
3945                         emitpLabel(truelbl->key);
3946
3947                 if(ifx) ifx->generated = 1;
3948                 return;
3949
3950
3951                 }
3952 #endif  // _swapp
3953
3954                 if(AOP_TYPE(left) == AOP_LIT) {
3955                         //symbol *lbl = newiTempLabel(NULL);
3956                         
3957                         //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3958                         
3959                         
3960                         DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3961                         
3962                         /* Special cases */
3963                         if((lit == 0) && (sign == 0)){
3964                                 
3965                                 size--;
3966                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3967                                 while(size) 
3968                                         emitpcode(POC_IORFW, popGet(AOP(right),--size));
3969                                 
3970                                 genSkipz2(&rFalseIfx,0);
3971                                 if(ifx) ifx->generated = 1;
3972                                 return;
3973                         }
3974                         
3975                         if(size==1) {
3976                                 /* Special cases */
3977                                 lit &= 0xff;
3978                                 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3979                                         /* degenerate compare can never be true */
3980                                         if(rFalseIfx.condition == 0)
3981                                                 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3982                                         
3983                                         if(ifx) ifx->generated = 1;
3984                                         return;
3985                                 }
3986                                 
3987                                 if(sign) {
3988                                         /* signed comparisons to a literal byte */
3989                                         
3990                                         int lp1 = (lit+1) & 0xff;
3991                                         
3992                                         DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3993                                         switch (lp1) {
3994                                         case 0:
3995                                                 rFalseIfx.condition ^= 1;
3996                                                 genSkipCond(&rFalseIfx,right,0,7);
3997                                                 break;
3998                                         case 0x7f:
3999                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4000                                                 emitpcode(POC_XORLW, popGetLit(0x7f));
4001                                                 genSkipz2(&rFalseIfx,1);
4002                                                 break;
4003                                         default:
4004                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4005                                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4006                                                 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4007                                                 rFalseIfx.condition ^= 1;
4008                                                 genSkipc(&rFalseIfx);
4009                                                 break;
4010                                         }
4011                                         if(ifx) ifx->generated = 1;
4012                                 } else {
4013                                         /* unsigned comparisons to a literal byte */
4014                                         
4015                                         switch(lit & 0xff ) {
4016                                         case 0:
4017                                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4018                                                 genSkipz2(&rFalseIfx,0);
4019                                                 if(ifx) ifx->generated = 1;
4020                                                 break;
4021                                         case 0x7f:
4022                                                 genSkipCond(&rFalseIfx,right,0,7);
4023                                                 if(ifx) ifx->generated = 1;
4024                                                 break;
4025                                                 
4026                                         default:
4027                                                 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4028                                                 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4029                                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4030                                                 rFalseIfx.condition ^= 1;
4031                                                 if (AOP_TYPE(result) == AOP_CRY) {
4032                                                         genSkipc(&rFalseIfx);
4033                                                         if(ifx) ifx->generated = 1;
4034                                                 } else {
4035                                                         DEBUGpic14_emitcode ("; ***","%s  %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4036                                                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4037                                                         emitpcode(POC_RLF, popGet(AOP(result),0));
4038                                                         emitpcode(POC_MOVLW, popGetLit(0x01));
4039                                                         emitpcode(POC_XORWF, popGet(AOP(result),0));
4040                                                 }       
4041                                                 break;
4042                                         }
4043                                 }
4044                                 
4045                                 //goto check_carry;
4046                                 return;
4047                                 
4048                         } else {
4049                                 
4050                                 /* Size is greater than 1 */
4051                                 
4052                                 if(sign) {
4053                                         int lp1 = lit+1;
4054                                         
4055                                         size--;
4056                                         
4057                                         if(lp1 == 0) {
4058                                                 /* this means lit = 0xffffffff, or -1 */
4059                                                 
4060                                                 
4061                                                 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4062                                                 rFalseIfx.condition ^= 1;
4063                                                 genSkipCond(&rFalseIfx,right,size,7);
4064                                                 if(ifx) ifx->generated = 1;
4065                                                 return;
4066                                         }
4067                                         
4068                                         if(lit == 0) {
4069                                                 int s = size;
4070                                                 
4071                                                 if(rFalseIfx.condition) {
4072                                                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4073                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4074                                                 }
4075                                                 
4076                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4077                                                 while(size--)
4078                                                         emitpcode(POC_IORFW, popGet(AOP(right),size));
4079                                                 
4080                                                 
4081                                                 emitSKPZ;
4082                                                 if(rFalseIfx.condition) {
4083                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4084                                                         emitpLabel(truelbl->key);
4085                                                 }else {
4086                                                         rFalseIfx.condition ^= 1;
4087                                                         genSkipCond(&rFalseIfx,right,s,7);
4088                                                 }
4089                                                 
4090                                                 if(ifx) ifx->generated = 1;
4091                                                 return;
4092                                         }
4093                                         
4094                                         if((size == 1) &&  (0 == (lp1&0xff))) {
4095                                                 /* lower byte of signed word is zero */
4096                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
4097                                                 i = ((lp1 >> 8) & 0xff) ^0x80;
4098                                                 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4099                                                 emitpcode(POC_ADDLW, popGetLit( 0x80));
4100                                                 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4101                                                 rFalseIfx.condition ^= 1;
4102                                                 genSkipc(&rFalseIfx);
4103                                                 
4104                                                 
4105                                                 if(ifx) ifx->generated = 1;
4106                                                 return;
4107                                         }
4108                                         
4109                                         if(lit & (0x80 << (size*8))) {
4110                                                 /* Lit is less than zero */
4111                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
4112                                                 //rFalseIfx.condition ^= 1;
4113                                                 //genSkipCond(&rFalseIfx,left,size,7);
4114                                                 //rFalseIfx.condition ^= 1;
4115                                                 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4116                                                 //emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4117                                                 
4118                                                 if(rFalseIfx.condition)
4119                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4120                                                 else
4121                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4122                                                 
4123                                                 
4124                                         } else {
4125                                                 /* Lit is greater than or equal to zero */
4126                                                 DEBUGpic14_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
4127                                                 //rFalseIfx.condition ^= 1;
4128                                                 //genSkipCond(&rFalseIfx,right,size,7);
4129                                                 //rFalseIfx.condition ^= 1;
4130                                                 
4131                                                 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132                                                 //emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4133                                                 
4134                                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4135                                                 if(rFalseIfx.condition)
4136                                                         emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4137                                                 else
4138                                                         emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4139                                                 
4140                                         }
4141                                         
4142                                         
4143                                         emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4144                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4145                                         
4146                                         while(size--) {
4147                                                 
4148                                                 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4149                                                 emitSKPNZ;
4150                                                 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4151                                         }
4152                                         rFalseIfx.condition ^= 1;
4153                                         //rFalseIfx.condition = 1;
4154                                         genSkipc(&rFalseIfx);
4155                                         
4156                                         emitpLabel(truelbl->key);
4157                                         
4158                                         if(ifx) ifx->generated = 1;
4159                                         return;
4160                                         // end of if (sign)
4161                                 } else {
4162                                         
4163                                         /* compare word or long to an unsigned literal on the right.*/
4164                                         
4165                                         
4166                                         size--;
4167                                         if(lit < 0xff) {
4168                                                 DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4169                                                 switch (lit) {
4170                                                 case 0:
4171                                                         break; /* handled above */
4172                                                 /*
4173                                                 case 0xff:
4174                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4175                                                         while(size--)
4176                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4177                                                         genSkipz2(&rFalseIfx,0);
4178                                                         break;
4179                                                 */
4180                                                 default:
4181                                                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4182                                                         while(--size)
4183                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4184                                                         
4185                                                         emitSKPZ;
4186                                                         if(rFalseIfx.condition)
4187                                                                 emitpcode(POC_GOTO,  popGetLabel(rFalseIfx.lbl->key));
4188                                                         else
4189                                                                 emitpcode(POC_GOTO,  popGetLabel(truelbl->key));
4190                                                         
4191                                                         
4192                                                         emitpcode(POC_MOVLW, popGetLit(lit+1));
4193                                                         emitpcode(POC_SUBFW, popGet(AOP(right),0));
4194                                                         
4195                                                         rFalseIfx.condition ^= 1;
4196                                                         genSkipc(&rFalseIfx);
4197                                                 }
4198                                                 
4199                                                 emitpLabel(truelbl->key);
4200                                                 
4201                                                 if(ifx) ifx->generated = 1;
4202                                                 return;
4203                                         }
4204                                         
4205                                         
4206                                         lit++;
4207                                         DEBUGpic14_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4208                                         i = (lit >> (size*8)) & 0xff;
4209                                         
4210                                         emitpcode(POC_MOVLW, popGetLit(i));
4211                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4212                                         
4213                                         while(size--) {
4214                                                 i = (lit >> (size*8)) & 0xff;
4215                                                 
4216                                                 if(i) {
4217                                                         emitpcode(POC_MOVLW, popGetLit(i));
4218                                                         emitSKPNZ;
4219                                                         emitpcode(POC_SUBFW, popGet(AOP(right),size));
4220                                                 } else {
4221                                                 /* this byte of the lit is zero, 
4222                                                         *if it's not the last then OR in the variable */
4223                                                         if(size)
4224                                                                 emitpcode(POC_IORFW, popGet(AOP(right),size));
4225                                                 }
4226                                         }
4227                                         
4228                                         
4229                                         emitpLabel(lbl->key);
4230                                         
4231                                         rFalseIfx.condition ^= 1;
4232                                         genSkipc(&rFalseIfx);
4233                                 }
4234                                 
4235                                 if(sign)
4236                                         emitpLabel(truelbl->key);
4237                                 if(ifx) ifx->generated = 1;
4238                                 return;
4239                         }
4240                 }
4241                 /* Compare two variables */
4242                 
4243                 DEBUGpic14_emitcode(";sign","%d",sign);
4244                 
4245                 size--;
4246                 if(sign) {
4247                         /* Sigh. thus sucks... */
4248                         if(size) {
4249                                 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4250                                 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4251                                 emitpcode(POC_MOVLW, popGetLit(0x80));
4252                                 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4253                                 emitpcode(POC_XORFW, popGet(AOP(right),size));
4254                                 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4255                         } else {
4256                                 /* Signed char comparison */
4257                                 /* Special thanks to Nikolai Golovchenko for this snippet */
4258                                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4259                                 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4260                                 emitpcode(POC_RRFW,  popGet(AOP(left),0)); /* could be any register */
4261                                 emitpcode(POC_XORFW, popGet(AOP(left),0));
4262                                 emitpcode(POC_XORFW, popGet(AOP(right),0));
4263                                 emitpcode(POC_ADDLW, popGetLit(0x80));
4264                                 
4265                                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4266                                 genSkipc(&rFalseIfx);
4267                                 
4268                                 if(ifx) ifx->generated = 1;
4269                                 return;
4270                         }
4271                         
4272                 } else {
4273                         
4274                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4275                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4276                 }
4277                 
4278                 
4279                 /* The rest of the bytes of a multi-byte compare */
4280                 while (size) {
4281                         
4282                         emitSKPZ;
4283                         emitpcode(POC_GOTO,  popGetLabel(lbl->key));
4284                         size--;
4285                         
4286                         emitpcode(POC_MOVFW, popGet(AOP(right),size));
4287                         emitpcode(POC_SUBFW, popGet(AOP(left),size));
4288                         
4289                         
4290                 }
4291                 
4292                 emitpLabel(lbl->key);
4293                 
4294                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4295                 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
4296                         (AOP_TYPE(result) == AOP_REG)) {
4297                         emitpcode(POC_CLRF, popGet(AOP(result),0));
4298                         emitpcode(POC_RLF, popGet(AOP(result),0));
4299                 } else {
4300                         genSkipc(&rFalseIfx);
4301                 }       
4302                 //genSkipc(&rFalseIfx);
4303                 if(ifx) ifx->generated = 1;
4304                 
4305                 return;
4306                 
4307         }
4308         
4309         // check_carry:
4310         if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4311                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4312                 pic14_outBitC(result);
4313         } else {
4314                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4315                 /* if the result is used in the next
4316                 ifx conditional branch then generate
4317                 code a little differently */
4318                 if (ifx )
4319                         genIfxJump (ifx,"c");
4320                 else
4321                         pic14_outBitC(result);
4322                 /* leave the result in acc */
4323         }
4324         
4325 }
4326
4327 /*-----------------------------------------------------------------*/
4328 /* genCmpGt :- greater than comparison                             */
4329 /*-----------------------------------------------------------------*/
4330 static void genCmpGt (iCode *ic, iCode *ifx)
4331 {
4332         operand *left, *right, *result;
4333         sym_link *letype , *retype;
4334         int sign ;
4335         
4336         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4337         left = IC_LEFT(ic);
4338         right= IC_RIGHT(ic);
4339         result = IC_RESULT(ic);
4340         
4341         letype = getSpec(operandType(left));
4342         retype =getSpec(operandType(right));
4343         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4344         /* assign the amsops */
4345         aopOp (left,ic,FALSE);
4346         aopOp (right,ic,FALSE);
4347         aopOp (result,ic,TRUE);
4348         
4349         genCmp(right, left, result, ifx, sign);
4350         
4351         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4352         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4353         freeAsmop(result,NULL,ic,TRUE); 
4354 }
4355
4356 /*-----------------------------------------------------------------*/
4357 /* genCmpLt - less than comparisons                                */
4358 /*-----------------------------------------------------------------*/
4359 static void genCmpLt (iCode *ic, iCode *ifx)
4360 {
4361         operand *left, *right, *result;
4362         sym_link *letype , *retype;
4363         int sign ;
4364         
4365         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4366         left = IC_LEFT(ic);
4367         right= IC_RIGHT(ic);
4368         result = IC_RESULT(ic);
4369         
4370         letype = getSpec(operandType(left));
4371         retype =getSpec(operandType(right));
4372         sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4373         
4374         /* assign the amsops */
4375         aopOp (left,ic,FALSE);
4376         aopOp (right,ic,FALSE);
4377         aopOp (result,ic,TRUE);
4378         
4379         genCmp(left, right, result, ifx, sign);
4380         
4381         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4382         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4383         freeAsmop(result,NULL,ic,TRUE); 
4384 }
4385
4386 /*-----------------------------------------------------------------*/
4387 /* genc16bit2lit - compare a 16 bit value to a literal             */
4388 /*-----------------------------------------------------------------*/
4389 static void genc16bit2lit(operand *op, int lit, int offset)
4390 {
4391         int i;
4392         
4393         DEBUGpic14_emitcode ("; ***","%s  %d, lit = %d",__FUNCTION__,__LINE__,lit);
4394         if( (lit&0xff) == 0) 
4395                 i=1;
4396         else
4397                 i=0;
4398         
4399         switch( BYTEofLONG(lit,i)) { 
4400         case 0:
4401                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4402                 break;
4403         case 1:
4404                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4405                 break;
4406         case 0xff:
4407                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4408                 break;
4409         default:
4410                 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4411                 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4412         }
4413         
4414         i ^= 1;
4415         
4416         switch( BYTEofLONG(lit,i)) { 
4417         case 0:
4418                 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4419                 break;
4420         case 1:
4421                 emitSKPNZ;
4422                 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4423                 break;
4424         case 0xff:
4425                 emitSKPNZ;
4426                 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4427                 break;
4428         default:
4429                 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4430                 emitSKPNZ;
4431                 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4432                 
4433         }
4434         
4435 }
4436
4437 /*-----------------------------------------------------------------*/
4438 /* gencjneshort - compare and jump if not equal                    */
4439 /*-----------------------------------------------------------------*/
4440 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4441 {
4442         int size = max(AOP_SIZE(left),AOP_SIZE(right));
4443         int offset = 0;
4444         int res_offset = 0;  /* the result may be a different size then left or right */
4445         int res_size = AOP_SIZE(result);
4446         resolvedIfx rIfx;
4447         symbol *lbl;
4448         
4449         unsigned long lit = 0L;
4450         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4451         DEBUGpic14_AopType(__LINE__,left,right,result);
4452         if(result)
4453                 DEBUGpic14_emitcode ("; ***","%s  %d result is not null",__FUNCTION__,__LINE__);
4454         resolveIfx(&rIfx,ifx);
4455         lbl =  newiTempLabel(NULL);
4456         
4457         
4458         /* if the left side is a literal or 
4459         if the right is in a pointer register and left 
4460         is not */
4461         if ((AOP_TYPE(left) == AOP_LIT) || 
4462                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4463                 operand *t = right;
4464                 right = left;
4465                 left = t;
4466         }
4467         if(AOP_TYPE(right) == AOP_LIT)
4468                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4469         
4470         /* if the right side is a literal then anything goes */
4471         if (AOP_TYPE(right) == AOP_LIT &&
4472                 AOP_TYPE(left) != AOP_DIR ) {
4473                 switch(size) {
4474                 case 2:
4475                         genc16bit2lit(left, lit, 0);
4476                         emitSKPNZ;
4477                         emitpcode(POC_GOTO,popGetLabel(lbl->key));
4478                         break;
4479                 default:
4480                         while (size--) {
4481                                 if(lit & 0xff) {
4482                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4483                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4484                                 } else {
4485                                         emitpcode(POC_MOVF,popGet(AOP(left),offset));
4486                                 }
4487                                 
4488                                 emitSKPNZ;
4489                                 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4490                                 offset++;
4491                                 if(res_offset < res_size-1)
4492                                         res_offset++;
4493                                 lit >>= 8;
4494                         }
4495                         break;
4496                 }
4497         }
4498         
4499         /* if the right side is in a register or in direct space or
4500         if the left is a pointer register & right is not */    
4501         else if (AOP_TYPE(right) == AOP_REG ||
4502                 AOP_TYPE(right) == AOP_DIR || 
4503                 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4504                 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4505                 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4506                 int lbl_key = lbl->key;
4507                 
4508                 if(result) {
4509                         emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4510                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4511                 }else {
4512                         DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
4513                         fprintf(stderr, "%s  %d error - expecting result to be non_null\n",
4514                                 __FUNCTION__,__LINE__);
4515                         return;
4516                 }
4517                 
4518                 /*     switch(size) { */
4519                 /*     case 2: */
4520                 /*       genc16bit2lit(left, lit, 0); */
4521                 /*       emitSKPNZ; */
4522                 /*       emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4523                 /*       break; */
4524                 /*     default: */
4525                 while (size--) {
4526                         int emit_skip=1;
4527                         if((AOP_TYPE(left) == AOP_DIR) && 
4528                                 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4529                                 
4530                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4531                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4532                                 
4533                         } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4534                                 
4535                                 switch (lit & 0xff) {
4536                                 case 0:
4537                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4538                                         break;
4539                                 case 1:
4540                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4541                                         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4542                                         //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4543                                         emit_skip=0;
4544                                         break;
4545                                 case 0xff:
4546                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4547                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4548                                         //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4549                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4550                                         emit_skip=0;
4551                                         break;
4552                                 default:
4553                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4554                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4555                                 }
4556                                 lit >>= 8;
4557                                 
4558                         } else {
4559                                 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4560                         }
4561                         if(emit_skip) {
4562                                 if(AOP_TYPE(result) == AOP_CRY) {
4563                                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4564                                         if(rIfx.condition)
4565                                                 emitSKPNZ;
4566                                         else
4567                                                 emitSKPZ;
4568                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4569                                 } else {
4570                                         /* fix me. probably need to check result size too */
4571                                         //emitpcode(POC_CLRF,popGet(AOP(result),0));
4572                                         if(rIfx.condition)
4573                                                 emitSKPZ;
4574                                         else
4575                                                 emitSKPNZ;
4576                                         emitpcode(POC_GOTO,popGetLabel(lbl_key));
4577                                         //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4578                                 }
4579                                 if(ifx)
4580                                         ifx->generated=1;
4581                         }
4582                         emit_skip++;
4583                         offset++;
4584                         if(res_offset < res_size-1)
4585                                 res_offset++;
4586                 }
4587                 /*       break; */
4588                 /*     } */
4589         } else if(AOP_TYPE(right) == AOP_REG &&
4590                 AOP_TYPE(left) != AOP_DIR){
4591                 
4592                 while(size--) {
4593                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4594                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4595                         pic14_emitcode(";***","%s  %d",__FUNCTION__,__LINE__);
4596                         if(rIfx.condition)
4597                                 emitSKPNZ;
4598                         else
4599                                 emitSKPZ;
4600                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4601                         offset++;
4602                         if(res_offset < res_size-1)
4603                                 res_offset++;
4604                 }
4605                 
4606         }else{
4607                 /* right is a pointer reg need both a & b */
4608                 while(size--) {
4609                         char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4610                         if(strcmp(l,"b"))
4611                                 pic14_emitcode("mov","b,%s",l);
4612                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4613                         pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);    
4614                         offset++;
4615                 }
4616         }
4617         
4618         emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4619         if(!rIfx.condition)
4620                 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4621         
4622         emitpLabel(lbl->key);
4623         
4624         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4625         
4626         if(ifx)
4627                 ifx->generated = 1;
4628 }
4629
4630 #if 0
4631 /*-----------------------------------------------------------------*/
4632 /* gencjne - compare and jump if not equal                         */
4633 /*-----------------------------------------------------------------*/
4634 static void gencjne(operand *left, operand *right, iCode *ifx)
4635 {
4636         symbol *tlbl  = newiTempLabel(NULL);
4637         
4638         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4639         gencjneshort(left, right, lbl);
4640         
4641         pic14_emitcode("mov","a,%s",one);
4642         pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4643         pic14_emitcode("","%05d_DS_:",lbl->key+100);
4644         pic14_emitcode("clr","a");
4645         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4646         
4647         emitpLabel(lbl->key);
4648         emitpLabel(tlbl->key);
4649         
4650 }
4651 #endif
4652
4653 /*-----------------------------------------------------------------*/
4654 /* genCmpEq - generates code for equal to                          */
4655 /*-----------------------------------------------------------------*/
4656 static void genCmpEq (iCode *ic, iCode *ifx)
4657 {
4658         operand *left, *right, *result;
4659         unsigned long lit = 0L;
4660         int size,offset=0;
4661         
4662         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4663         
4664         if(ifx)
4665                 DEBUGpic14_emitcode ("; ifx is non-null","");
4666         else
4667                 DEBUGpic14_emitcode ("; ifx is null","");
4668         
4669         aopOp((left=IC_LEFT(ic)),ic,FALSE);
4670         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4671         aopOp((result=IC_RESULT(ic)),ic,TRUE);
4672         
4673         size = max(AOP_SIZE(left),AOP_SIZE(right));
4674         
4675         DEBUGpic14_AopType(__LINE__,left,right,result);
4676         
4677         /* if literal, literal on the right or 
4678         if the right is in a pointer register and left 
4679         is not */
4680         if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
4681                 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4682                 operand *tmp = right ;
4683                 right = left;
4684                 left = tmp;
4685         }
4686         
4687         
4688         if(ifx && !AOP_SIZE(result)){
4689                 symbol *tlbl;
4690                 /* if they are both bit variables */
4691                 if (AOP_TYPE(left) == AOP_CRY &&
4692                         ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4693                         if(AOP_TYPE(right) == AOP_LIT){
4694                                 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4695                                 if(lit == 0L){
4696                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4697                                         pic14_emitcode("cpl","c");
4698                                 } else if(lit == 1L) {
4699                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4700                                 } else {
4701                                         pic14_emitcode("clr","c");
4702                                 }
4703                                 /* AOP_TYPE(right) == AOP_CRY */
4704                         } else {
4705                                 symbol *lbl = newiTempLabel(NULL);
4706                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4707                                 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4708                                 pic14_emitcode("cpl","c");
4709                                 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4710                         }
4711                         /* if true label then we jump if condition
4712                         supplied is true */
4713                         tlbl = newiTempLabel(NULL);
4714                         if ( IC_TRUE(ifx) ) {
4715                                 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4716                                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4717                         } else {
4718                                 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4719                                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4720                         }
4721                         pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4722                         
4723                         {
4724                                 /* left and right are both bit variables, result is carry */
4725                                 resolvedIfx rIfx;
4726                                 
4727                                 resolveIfx(&rIfx,ifx);
4728                                 
4729                                 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4730                                 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4731                                 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4732                                 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4733                                 genSkipz2(&rIfx,0);
4734                         }
4735                 } else {
4736                         
4737                         /* They're not both bit variables. Is the right a literal? */
4738                         if(AOP_TYPE(right) == AOP_LIT) {
4739                                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4740                                 
4741                                 switch(size) {
4742                                         
4743                                 case 1:
4744                                         switch(lit & 0xff) {
4745                                         case 1:
4746                                                 if ( IC_TRUE(ifx) ) {
4747                                                         emitpcode(POC_DECFW,popGet(AOP(left),offset));
4748                                                         emitSKPNZ;
4749                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4750                                                 } else {
4751                                                         emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4752                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4753                                                 }
4754                                                 break;
4755                                         case 0xff:
4756                                                 if ( IC_TRUE(ifx) ) {
4757                                                         emitpcode(POC_INCFW,popGet(AOP(left),offset));
4758                                                         emitSKPNZ;
4759                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4760                                                 } else {
4761                                                         emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4762                                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4763                                                 }
4764                                                 break;
4765                                         default:
4766                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4767                                                 if(lit)
4768                                                         emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4769                                                 genSkip(ifx,'z');
4770                                         }
4771                                         
4772                                         
4773                                         /* end of size == 1 */
4774                                         break;
4775                                         
4776                                         case 2:
4777                                                 genc16bit2lit(left,lit,offset);
4778                                                 genSkip(ifx,'z');
4779                                                 break;
4780                                                 /* end of size == 2 */
4781                                                 
4782                                         default:
4783                                                 /* size is 4 */
4784                                                 if(lit==0) {
4785                                                         emitpcode(POC_MOVFW,popGet(AOP(left),0));
4786                                                         emitpcode(POC_IORFW,popGet(AOP(left),1));
4787                                                         emitpcode(POC_IORFW,popGet(AOP(left),2));
4788                                                         emitpcode(POC_IORFW,popGet(AOP(left),3));
4789                                                         
4790                                                 } else {
4791                                                         
4792                                                         /* search for patterns that can be optimized */
4793                                                         
4794                                                         genc16bit2lit(left,lit,0);
4795                                                         lit >>= 16;
4796                                                         if(lit) {
4797                                                                 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4798                                                                 //genSkip(ifx,'z');
4799                                                                 genc16bit2lit(left,lit,2);
4800                                                         } else {
4801                                                                 emitpcode(POC_IORFW,popGet(AOP(left),2));
4802                                                                 emitpcode(POC_IORFW,popGet(AOP(left),3));
4803                                                                 
4804                                                         }
4805                                                         
4806                                                 }
4807                                                 
4808                                                 genSkip(ifx,'z');
4809                                 }
4810                                 
4811                                 ifx->generated = 1;
4812                                 goto release ;
4813                                 
4814                                 
4815                         } else if(AOP_TYPE(right) == AOP_CRY ) {
4816                                 /* we know the left is not a bit, but that the right is */
4817                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4818                                 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4819                                         popGet(AOP(right),offset));
4820                                 emitpcode(POC_XORLW,popGetLit(1));
4821                                 
4822                                 /* if the two are equal, then W will be 0 and the Z bit is set
4823                                 * we could test Z now, or go ahead and check the high order bytes if
4824                                 * the variable we're comparing is larger than a byte. */
4825                                 
4826                                 while(--size)
4827                                         emitpcode(POC_IORFW,popGet(AOP(left),offset));
4828                                 
4829                                 if ( IC_TRUE(ifx) ) {
4830                                         emitSKPNZ;
4831                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4832                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4833                                 } else {
4834                                         emitSKPZ;
4835                                         emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4836                                         pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4837                                 }
4838                                 
4839                         } else {
4840                                 /* They're both variables that are larger than bits */
4841                                 int s = size;
4842                                 
4843                                 tlbl = newiTempLabel(NULL);
4844                                 
4845                                 while(size--) {
4846                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4847                                         emitpcode(POC_XORFW,popGet(AOP(right),offset));
4848                                         
4849                                         if ( IC_TRUE(ifx) ) {
4850                                                 if(size) {
4851                                                         emitSKPZ;
4852                                                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4853                                                         pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4854                                                 } else {
4855                                                         emitSKPNZ;
4856                                                         emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4857                                                         pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4858                                                 }
4859                                         } else {
4860                                                 emitSKPZ;
4861                                                 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4862                                                 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4863                                         }
4864                                         offset++;
4865                                 }
4866                                 if(s>1 && IC_TRUE(ifx)) {
4867                                         emitpLabel(tlbl->key);
4868                                         pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);                
4869                                 }
4870                         }
4871                 }
4872                 /* mark the icode as generated */
4873                 ifx->generated = 1;
4874                 goto release ;
4875         }
4876   
4877   /* if they are both bit variables */
4878   if (AOP_TYPE(left) == AOP_CRY &&
4879           ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4880           if(AOP_TYPE(right) == AOP_LIT){
4881                   unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4882                   if(lit == 0L){
4883                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4884                           pic14_emitcode("cpl","c");
4885                   } else if(lit == 1L) {
4886                           pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4887                   } else {
4888                           pic14_emitcode("clr","c");
4889                   }
4890                   /* AOP_TYPE(right) == AOP_CRY */
4891           } else {
4892                   symbol *lbl = newiTempLabel(NULL);
4893                   pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4894                   pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4895                   pic14_emitcode("cpl","c");
4896                   pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4897           }
4898           /* c = 1 if egal */
4899           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4900                   pic14_outBitC(result);
4901                   goto release ;
4902           }
4903           if (ifx) {
4904                   genIfxJump (ifx,"c");
4905                   goto release ;
4906           }
4907           /* if the result is used in an arithmetic operation
4908           then put the result in place */
4909           pic14_outBitC(result);
4910   } else {
4911           
4912           DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4913           gencjne(left,right,result,ifx);
4914           /*
4915           if(ifx) 
4916           gencjne(left,right,newiTempLabel(NULL));
4917           else {
4918           if(IC_TRUE(ifx)->key)
4919           gencjne(left,right,IC_TRUE(ifx)->key);
4920           else
4921           gencjne(left,right,IC_FALSE(ifx)->key);
4922           ifx->generated = 1;
4923           goto release ;
4924           }
4925           if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4926           aopPut(AOP(result),"a",0);
4927           goto release ;
4928           }
4929           
4930                 if (ifx) {
4931                 genIfxJump (ifx,"a");
4932                 goto release ;
4933                 }
4934           */
4935           /* if the result is used in an arithmetic operation
4936           then put the result in place */
4937           /*
4938           if (AOP_TYPE(result) != AOP_CRY) 
4939           pic14_outAcc(result);
4940           */
4941           /* leave the result in acc */
4942   }
4943   
4944 release:
4945   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4946   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4947   freeAsmop(result,NULL,ic,TRUE);
4948 }
4949
4950 /*-----------------------------------------------------------------*/
4951 /* ifxForOp - returns the icode containing the ifx for operand     */
4952 /*-----------------------------------------------------------------*/
4953 static iCode *ifxForOp ( operand *op, iCode *ic )
4954 {
4955         /* if true symbol then needs to be assigned */
4956         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
4957         if (IS_TRUE_SYMOP(op))
4958                 return NULL ;
4959         
4960                 /* if this has register type condition and
4961                 the next instruction is ifx with the same operand
4962         and live to of the operand is upto the ifx only then */
4963         if (ic->next &&
4964                 ic->next->op == IFX &&
4965                 IC_COND(ic->next)->key == op->key &&
4966                 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4967                 return ic->next;
4968         
4969         if (ic->next &&
4970                 ic->next->op == IFX &&
4971                 IC_COND(ic->next)->key == op->key) {
4972                 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4973                 return ic->next;
4974         }
4975         
4976         DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4977         if (ic->next &&
4978                 ic->next->op == IFX)
4979                 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4980         
4981         if (ic->next &&
4982                 ic->next->op == IFX &&
4983                 IC_COND(ic->next)->key == op->key) {
4984                 DEBUGpic14_emitcode ("; "," key is okay");
4985                 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4986                         OP_SYMBOL(op)->liveTo,
4987                         ic->next->seq);
4988         }
4989         
4990         
4991         return NULL;
4992 }
4993 /*-----------------------------------------------------------------*/
4994 /* genAndOp - for && operation                                     */
4995 /*-----------------------------------------------------------------*/
4996 static void genAndOp (iCode *ic)
4997 {
4998         operand *left,*right, *result;
4999         /*     symbol *tlbl; */
5000         
5001         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5002         /* note here that && operations that are in an
5003         if statement are taken away by backPatchLabels
5004         only those used in arthmetic operations remain */
5005         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5006         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5007         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5008         
5009         DEBUGpic14_AopType(__LINE__,left,right,result);
5010         
5011         emitpcode(POC_MOVFW,popGet(AOP(left),0));
5012         emitpcode(POC_ANDFW,popGet(AOP(right),0));
5013         emitpcode(POC_MOVWF,popGet(AOP(result),0));
5014         
5015         /* if both are bit variables */
5016         /*     if (AOP_TYPE(left) == AOP_CRY && */
5017         /*         AOP_TYPE(right) == AOP_CRY ) { */
5018         /*         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5019         /*         pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5020         /*         pic14_outBitC(result); */
5021         /*     } else { */
5022         /*         tlbl = newiTempLabel(NULL); */
5023         /*         pic14_toBoolean(left);     */
5024         /*         pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5025         /*         pic14_toBoolean(right); */
5026         /*         pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5027         /*         pic14_outBitAcc(result); */
5028         /*     } */
5029         
5030         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5031         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032         freeAsmop(result,NULL,ic,TRUE);
5033 }
5034
5035
5036 /*-----------------------------------------------------------------*/
5037 /* genOrOp - for || operation                                      */
5038 /*-----------------------------------------------------------------*/
5039 /*
5040 tsd pic port -
5041 modified this code, but it doesn't appear to ever get called
5042 */
5043
5044 static void genOrOp (iCode *ic)
5045 {
5046         operand *left,*right, *result;
5047         symbol *tlbl;
5048         
5049         /* note here that || operations that are in an
5050         if statement are taken away by backPatchLabels
5051         only those used in arthmetic operations remain */
5052         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5053         aopOp((left=IC_LEFT(ic)),ic,FALSE);
5054         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5055         aopOp((result=IC_RESULT(ic)),ic,FALSE);
5056         
5057         DEBUGpic14_AopType(__LINE__,left,right,result);
5058         
5059         /* if both are bit variables */
5060         if (AOP_TYPE(left) == AOP_CRY &&
5061                 AOP_TYPE(right) == AOP_CRY ) {
5062                 pic14_emitcode("clrc","");
5063                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5064                         AOP(left)->aopu.aop_dir,
5065                         AOP(left)->aopu.aop_dir);
5066                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5067                         AOP(right)->aopu.aop_dir,
5068                         AOP(right)->aopu.aop_dir);
5069                 pic14_emitcode("setc","");
5070                 
5071         } else {
5072                 tlbl = newiTempLabel(NULL);
5073                 pic14_toBoolean(left);
5074                 emitSKPZ;
5075                 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5076                 pic14_toBoolean(right);
5077                 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5078                 
5079                 pic14_outBitAcc(result);
5080         }
5081         
5082         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5083         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084         freeAsmop(result,NULL,ic,TRUE);            
5085 }
5086
5087 /*-----------------------------------------------------------------*/
5088 /* isLiteralBit - test if lit == 2^n                               */
5089 /*-----------------------------------------------------------------*/
5090 static int isLiteralBit(unsigned long lit)
5091 {
5092         unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5093                 0x100L,0x200L,0x400L,0x800L,
5094                 0x1000L,0x2000L,0x4000L,0x8000L,
5095                 0x10000L,0x20000L,0x40000L,0x80000L,
5096                 0x100000L,0x200000L,0x400000L,0x800000L,
5097                 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5098                 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5099         int idx;
5100         
5101         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5102         for(idx = 0; idx < 32; idx++)
5103                 if(lit == pw[idx])
5104                         return idx+1;
5105                 return 0;
5106 }
5107
5108 /*-----------------------------------------------------------------*/
5109 /* continueIfTrue -                                                */
5110 /*-----------------------------------------------------------------*/
5111 static void continueIfTrue (iCode *ic)
5112 {
5113         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5114         if(IC_TRUE(ic))
5115                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5116         ic->generated = 1;
5117 }
5118
5119 /*-----------------------------------------------------------------*/
5120 /* jmpIfTrue -                                                     */
5121 /*-----------------------------------------------------------------*/
5122 static void jumpIfTrue (iCode *ic)
5123 {
5124         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5125         if(!IC_TRUE(ic))
5126                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5127         ic->generated = 1;
5128 }
5129
5130 /*-----------------------------------------------------------------*/
5131 /* jmpTrueOrFalse -                                                */
5132 /*-----------------------------------------------------------------*/
5133 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5134 {
5135         // ugly but optimized by peephole
5136         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5137         if(IC_TRUE(ic)){
5138                 symbol *nlbl = newiTempLabel(NULL);
5139                 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);                 
5140                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5141                 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5142                 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5143         }
5144         else{
5145                 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5146                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5147         }
5148         ic->generated = 1;
5149 }
5150
5151 /*-----------------------------------------------------------------*/
5152 /* genAnd  - code for and                                          */
5153 /*-----------------------------------------------------------------*/
5154 static void genAnd (iCode *ic, iCode *ifx)
5155 {
5156         operand *left, *right, *result;
5157         int size, offset=0;  
5158         unsigned long lit = 0L;
5159         int bytelit = 0;
5160         resolvedIfx rIfx;
5161         
5162         
5163         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5164         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5165         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5166         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5167         
5168         resolveIfx(&rIfx,ifx);
5169         
5170         /* if left is a literal & right is not then exchange them */
5171         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5172                 AOP_NEEDSACC(left)) {
5173                 operand *tmp = right ;
5174                 right = left;
5175                 left = tmp;
5176         }
5177         
5178         /* if result = right then exchange them */
5179         if(pic14_sameRegs(AOP(result),AOP(right))){
5180                 operand *tmp = right ;
5181                 right = left;
5182                 left = tmp;
5183         }
5184         
5185         /* if right is bit then exchange them */
5186         if (AOP_TYPE(right) == AOP_CRY &&
5187                 AOP_TYPE(left) != AOP_CRY){
5188                 operand *tmp = right ;
5189                 right = left;
5190                 left = tmp;
5191         }
5192         if(AOP_TYPE(right) == AOP_LIT)
5193                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5194         
5195         size = AOP_SIZE(result);
5196         
5197         DEBUGpic14_AopType(__LINE__,left,right,result);
5198         
5199         // if(bit & yy)
5200         // result = bit & yy;
5201         if (AOP_TYPE(left) == AOP_CRY){
5202                 // c = bit & literal;
5203                 if(AOP_TYPE(right) == AOP_LIT){
5204                         if(lit & 1) {
5205                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5206                                         // no change
5207                                         goto release;
5208                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5209                         } else {
5210                                 // bit(result) = 0;
5211                                 if(size && (AOP_TYPE(result) == AOP_CRY)){
5212                                         pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5213                                         goto release;
5214                                 }
5215                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5216                                         jumpIfTrue(ifx);
5217                                         goto release;
5218                                 }
5219                                 pic14_emitcode("clr","c");
5220                         }
5221                 } else {
5222                         if (AOP_TYPE(right) == AOP_CRY){
5223                                 // c = bit & bit;
5224                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5225                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5226                         } else {
5227                                 // c = bit & val;
5228                                 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5229                                 // c = lsb
5230                                 pic14_emitcode("rrc","a");
5231                                 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5232                         }
5233                 }
5234                 // bit = c
5235                 // val = c
5236                 if(size)
5237                         pic14_outBitC(result);
5238                 // if(bit & ...)
5239                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5240                         genIfxJump(ifx, "c");           
5241                 goto release ;
5242         }
5243         
5244         // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
5245         // bit = val & 0xZZ     - size = 1, ifx = FALSE -
5246         if((AOP_TYPE(right) == AOP_LIT) &&
5247                 (AOP_TYPE(result) == AOP_CRY) &&
5248                 (AOP_TYPE(left) != AOP_CRY)){
5249                 int posbit = isLiteralBit(lit);
5250                 /* left &  2^n */
5251                 if(posbit){
5252                         posbit--;
5253                         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5254                         // bit = left & 2^n
5255                         if(size)
5256                                 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5257                         // if(left &  2^n)
5258                         else{
5259                                 if(ifx){
5260                                         int offset = 0;
5261                                         while (posbit > 7) {
5262                                                 posbit -= 8;
5263                                                 offset++;
5264                                         }
5265                                         emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5266                                                 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5267                                         emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5268                                         
5269                                         ifx->generated = 1;
5270                                 }
5271                                 goto release;
5272                         }
5273                 } else {
5274                         symbol *tlbl = newiTempLabel(NULL);
5275                         int sizel = AOP_SIZE(left);
5276                         if(size)
5277                                 pic14_emitcode("setb","c");
5278                         while(sizel--){
5279                                 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5280                                         MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5281                                         // byte ==  2^n ?
5282                                         if((posbit = isLiteralBit(bytelit)) != 0)
5283                                                 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5284                                         else{
5285                                                 if(bytelit != 0x0FFL)
5286                                                         pic14_emitcode("anl","a,%s",
5287                                                         aopGet(AOP(right),offset,FALSE,TRUE));
5288                                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5289                                         }
5290                                 }
5291                                 offset++;
5292                         }
5293                         // bit = left & literal
5294                         if(size){
5295                                 pic14_emitcode("clr","c");
5296                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5297                         }
5298                         // if(left & literal)
5299                         else{
5300                                 if(ifx)
5301                                         jmpTrueOrFalse(ifx, tlbl);
5302                                 goto release ;
5303                         }
5304                 }
5305                 pic14_outBitC(result);
5306                 goto release ;
5307         }
5308         
5309         /* if left is same as result */
5310         if(pic14_sameRegs(AOP(result),AOP(left))){
5311                 int know_W = -1;
5312                 for(;size--; offset++,lit>>=8) {
5313                         if(AOP_TYPE(right) == AOP_LIT){
5314                                 switch(lit & 0xff) {
5315                                 case 0x00:
5316                                         /*  and'ing with 0 has clears the result */
5317                                         pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5318                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
5319                                         break;
5320                                 case 0xff:
5321                                         /* and'ing with 0xff is a nop when the result and left are the same */
5322                                         break;
5323                                         
5324                                 default:
5325                                         {
5326                                                 int p = my_powof2( (~lit) & 0xff );
5327                                                 if(p>=0) {
5328                                                         /* only one bit is set in the literal, so use a bcf instruction */
5329                                                         pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5330                                                         emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5331                                                         
5332                                                 } else {
5333                                                         pic14_emitcode("movlw","0x%x", (lit & 0xff));
5334                                                         pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5335                                                         if(know_W != (int)(lit&0xff))
5336                                                                 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5337                                                         know_W = lit &0xff;
5338                                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5339                                                 }
5340                                         }    
5341                                 }
5342                         } else {
5343                                 if (AOP_TYPE(left) == AOP_ACC) {
5344                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5345                                 } else {        
5346                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5347                                         emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5348                                         
5349                                 }
5350                         }
5351                 }
5352                 
5353         } else {
5354                 // left & result in different registers
5355                 if(AOP_TYPE(result) == AOP_CRY){
5356                         // result = bit
5357                         // if(size), result in bit
5358                         // if(!size && ifx), conditional oper: if(left & right)
5359                         symbol *tlbl = newiTempLabel(NULL);
5360                         int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5361                         if(size)
5362                                 pic14_emitcode("setb","c");
5363                         while(sizer--){
5364                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5365                                 pic14_emitcode("anl","a,%s",
5366                                         aopGet(AOP(left),offset,FALSE,FALSE));
5367                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5368                                 offset++;
5369                         }
5370                         if(size){
5371                                 CLRC;
5372                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5373                                 pic14_outBitC(result);
5374                         } else if(ifx)
5375                                 jmpTrueOrFalse(ifx, tlbl);
5376                 } else {
5377                         for(;(size--);offset++) {
5378                                 // normal case
5379                                 // result = left & right
5380                                 if(AOP_TYPE(right) == AOP_LIT){
5381                                         int t = (lit >> (offset*8)) & 0x0FFL;
5382                                         switch(t) { 
5383                                         case 0x00:
5384                                                 pic14_emitcode("clrf","%s",
5385                                                         aopGet(AOP(result),offset,FALSE,FALSE));
5386                                                 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5387                                                 break;
5388                                         case 0xff:
5389                                                 if(AOP_TYPE(left) != AOP_ACC) {
5390                                                         pic14_emitcode("movf","%s,w",
5391                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5392                                                         pic14_emitcode("movwf","%s",
5393                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5394                                                         emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5395                                                 }
5396                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5397                                                 break;
5398                                         default:
5399                                                 if(AOP_TYPE(left) == AOP_ACC) {
5400                                                         emitpcode(POC_ANDLW, popGetLit(t));
5401                                                 } else {
5402                                                         pic14_emitcode("movlw","0x%x",t);
5403                                                         pic14_emitcode("andwf","%s,w",
5404                                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5405                                                         pic14_emitcode("movwf","%s",
5406                                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5407                                                         
5408                                                         emitpcode(POC_MOVLW, popGetLit(t));
5409                                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5410                                                 }
5411                                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5412                                         }
5413                                         continue;
5414                                 }
5415                                 
5416                                 if (AOP_TYPE(left) == AOP_ACC) {
5417                                         pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5418                                         emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5419                                 } else {
5420                                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5421                                         pic14_emitcode("andwf","%s,w",
5422                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5423                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5424                                         emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5425                                 }
5426                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5427                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5428                         }
5429                 }
5430         }
5431         
5432 release :
5433         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5434         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5435         freeAsmop(result,NULL,ic,TRUE);     
5436 }
5437
5438 /*-----------------------------------------------------------------*/
5439 /* genOr  - code for or                                            */
5440 /*-----------------------------------------------------------------*/
5441 static void genOr (iCode *ic, iCode *ifx)
5442 {
5443         operand *left, *right, *result;
5444         int size, offset=0;
5445         unsigned long lit = 0L;
5446         
5447         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5448         
5449         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5450         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5451         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5452         
5453         DEBUGpic14_AopType(__LINE__,left,right,result);
5454         
5455         /* if left is a literal & right is not then exchange them */
5456         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5457                 AOP_NEEDSACC(left)) {
5458                 operand *tmp = right ;
5459                 right = left;
5460                 left = tmp;
5461         }
5462         
5463         /* if result = right then exchange them */
5464         if(pic14_sameRegs(AOP(result),AOP(right))){
5465                 operand *tmp = right ;
5466                 right = left;
5467                 left = tmp;
5468         }
5469         
5470         /* if right is bit then exchange them */
5471         if (AOP_TYPE(right) == AOP_CRY &&
5472                 AOP_TYPE(left) != AOP_CRY){
5473                 operand *tmp = right ;
5474                 right = left;
5475                 left = tmp;
5476         }
5477         
5478         DEBUGpic14_AopType(__LINE__,left,right,result);
5479         
5480         if(AOP_TYPE(right) == AOP_LIT)
5481                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5482         
5483         size = AOP_SIZE(result);
5484         
5485         // if(bit | yy)
5486         // xx = bit | yy;
5487         if (AOP_TYPE(left) == AOP_CRY){
5488                 if(AOP_TYPE(right) == AOP_LIT){
5489                         // c = bit & literal;
5490                         if(lit){
5491                                 // lit != 0 => result = 1
5492                                 if(AOP_TYPE(result) == AOP_CRY){
5493                                         if(size)
5494                                                 emitpcode(POC_BSF, popGet(AOP(result),0));
5495                                         //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5496                                         //   AOP(result)->aopu.aop_dir,
5497                                         //   AOP(result)->aopu.aop_dir);
5498                                         else if(ifx)
5499                                                 continueIfTrue(ifx);
5500                                         goto release;
5501                                 }
5502                         } else {
5503                                 // lit == 0 => result = left
5504                                 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5505                                         goto release;
5506                                 pic14_emitcode(";XXX mov","c,%s  %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5507                         }
5508                 } else {
5509                         if (AOP_TYPE(right) == AOP_CRY){
5510                                 if(pic14_sameRegs(AOP(result),AOP(left))){
5511                                         // c = bit | bit;
5512                                         emitpcode(POC_BCF,   popGet(AOP(result),0));
5513                                         emitpcode(POC_BTFSC, popGet(AOP(right),0));
5514                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5515                                         
5516                                         pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5517                                                 AOP(result)->aopu.aop_dir,
5518                                                 AOP(result)->aopu.aop_dir);
5519                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5520                                                 AOP(right)->aopu.aop_dir,
5521                                                 AOP(right)->aopu.aop_dir);
5522                                         pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5523                                                 AOP(result)->aopu.aop_dir,
5524                                                 AOP(result)->aopu.aop_dir);
5525                                 } else {
5526                                         if( AOP_TYPE(result) == AOP_ACC) {
5527                                                 emitpcode(POC_MOVLW, popGetLit(0));
5528                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5529                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5530                                                 emitpcode(POC_MOVLW, popGetLit(1));
5531                                                 
5532                                         } else {
5533                                                 
5534                                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5535                                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5536                                                 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5537                                                 emitpcode(POC_BSF,   popGet(AOP(result),0));
5538                                                 
5539                                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5540                                                         AOP(result)->aopu.aop_dir,
5541                                                         AOP(result)->aopu.aop_dir);
5542                                                 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5543                                                         AOP(right)->aopu.aop_dir,
5544                                                         AOP(right)->aopu.aop_dir);
5545                                                 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5546                                                         AOP(left)->aopu.aop_dir,
5547                                                         AOP(left)->aopu.aop_dir);
5548                                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5549                                                         AOP(result)->aopu.aop_dir,
5550                                                         AOP(result)->aopu.aop_dir);
5551                                         }
5552                                 }
5553                         } else {
5554                                 // c = bit | val;
5555                                 symbol *tlbl = newiTempLabel(NULL);
5556                                 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5557                                 
5558                                 
5559                                 emitpcode(POC_BCF,   popGet(AOP(result),0));
5560                                 if( AOP_TYPE(right) == AOP_ACC) {
5561                                         emitpcode(POC_IORLW, popGetLit(0));
5562                                         emitSKPNZ;
5563                                         emitpcode(POC_BTFSC, popGet(AOP(left),0));
5564                                         emitpcode(POC_BSF,   popGet(AOP(result),0));
5565                                 }
5566                                 
5567                                 
5568                                 
5569                                 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5570                                         pic14_emitcode(";XXX setb","c");
5571                                 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5572                                         AOP(left)->aopu.aop_dir,tlbl->key+100);
5573                                 pic14_toBoolean(right);
5574                                 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5575                                 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5576                                         jmpTrueOrFalse(ifx, tlbl);
5577                                         goto release;
5578                                 } else {
5579                                         CLRC;
5580                                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5581                                 }
5582                         }
5583                 }
5584                 // bit = c
5585                 // val = c
5586                 if(size)
5587                         pic14_outBitC(result);
5588                 // if(bit | ...)
5589                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5590                         genIfxJump(ifx, "c");           
5591                 goto release ;
5592   }
5593   
5594   // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
5595   // bit = val | 0xZZ     - size = 1, ifx = FALSE -
5596   if((AOP_TYPE(right) == AOP_LIT) &&
5597           (AOP_TYPE(result) == AOP_CRY) &&
5598           (AOP_TYPE(left) != AOP_CRY)){
5599           if(lit){
5600                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5601                   // result = 1
5602                   if(size)
5603                           pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5604                   else 
5605                           continueIfTrue(ifx);
5606                   goto release;
5607           } else {
5608                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5609                   // lit = 0, result = boolean(left)
5610                   if(size)
5611                           pic14_emitcode(";XXX setb","c");
5612                   pic14_toBoolean(right);
5613                   if(size){
5614                           symbol *tlbl = newiTempLabel(NULL);
5615                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5616                           CLRC;
5617                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5618                   } else {
5619                           genIfxJump (ifx,"a");
5620                           goto release;
5621                   }
5622           }
5623           pic14_outBitC(result);
5624           goto release ;
5625   }
5626   
5627   /* if left is same as result */
5628   if(pic14_sameRegs(AOP(result),AOP(left))){
5629           int know_W = -1;
5630           for(;size--; offset++,lit>>=8) {
5631                   if(AOP_TYPE(right) == AOP_LIT){
5632                           if((lit & 0xff) == 0)
5633                                   /*  or'ing with 0 has no effect */
5634                                   continue;
5635                           else {
5636                                   int p = my_powof2(lit & 0xff);
5637                                   if(p>=0) {
5638                                           /* only one bit is set in the literal, so use a bsf instruction */
5639                                           emitpcode(POC_BSF,
5640                                                   newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5641                                   } else {
5642                                           if(know_W != (int)(lit & 0xff))
5643                                                   emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5644                                           know_W = lit & 0xff;
5645                                           emitpcode(POC_IORWF, popGet(AOP(left),offset));
5646                                   }
5647                                   
5648                           }
5649                   } else {
5650                           if (AOP_TYPE(left) == AOP_ACC) {
5651                                   emitpcode(POC_IORFW,  popGet(AOP(right),offset));
5652                                   pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5653                           } else {        
5654                                   emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5655                                   emitpcode(POC_IORWF,  popGet(AOP(left),offset));
5656                                   
5657                                   pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5658                                   pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5659                                   
5660                           }
5661                   }
5662           }
5663   } else {
5664           // left & result in different registers
5665           if(AOP_TYPE(result) == AOP_CRY){
5666                   // result = bit
5667                   // if(size), result in bit
5668                   // if(!size && ifx), conditional oper: if(left | right)
5669                   symbol *tlbl = newiTempLabel(NULL);
5670                   int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5671                   pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5672                   
5673                   
5674                   if(size)
5675                           pic14_emitcode(";XXX setb","c");
5676                   while(sizer--){
5677                           MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5678                           pic14_emitcode(";XXX orl","a,%s",
5679                                   aopGet(AOP(left),offset,FALSE,FALSE));
5680                           pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5681                           offset++;
5682                   }
5683                   if(size){
5684                           CLRC;
5685                           pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5686                           pic14_outBitC(result);
5687                   } else if(ifx)
5688                           jmpTrueOrFalse(ifx, tlbl);
5689           } else for(;(size--);offset++){
5690                   // normal case
5691                   // result = left & right
5692                   if(AOP_TYPE(right) == AOP_LIT){
5693                           int t = (lit >> (offset*8)) & 0x0FFL;
5694                           switch(t) { 
5695                           case 0x00:
5696                                   if (AOP_TYPE(left) != AOP_ACC) {
5697                                           emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
5698                                   }
5699                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5700                                   
5701                                   break;
5702                           default:
5703                                   if (AOP_TYPE(left) == AOP_ACC) {
5704                                           emitpcode(POC_IORLW,  popGetLit(t));
5705                                   } else {
5706                                           emitpcode(POC_MOVLW,  popGetLit(t));
5707                                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5708                                   }
5709                                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));        
5710                           }
5711                           continue;
5712                   }
5713                   
5714                   // faster than result <- left, anl result,right
5715                   // and better if result is SFR
5716                   if (AOP_TYPE(left) == AOP_ACC) {
5717                           emitpcode(POC_IORWF,  popGet(AOP(right),offset));
5718                           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5719                   } else {
5720                           emitpcode(POC_MOVFW,  popGet(AOP(right),offset));
5721                           emitpcode(POC_IORFW,  popGet(AOP(left),offset));
5722                           
5723                           pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5724                           pic14_emitcode("iorwf","%s,w",
5725                                   aopGet(AOP(left),offset,FALSE,FALSE));
5726                   }
5727                   emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
5728                   pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5729           }
5730   }
5731   
5732 release :
5733   freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5734   freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5735   freeAsmop(result,NULL,ic,TRUE);     
5736 }
5737
5738 /*-----------------------------------------------------------------*/
5739 /* genXor - code for xclusive or                                   */
5740 /*-----------------------------------------------------------------*/
5741 static void genXor (iCode *ic, iCode *ifx)
5742 {
5743         operand *left, *right, *result;
5744         int size, offset=0;
5745         unsigned long lit = 0L;
5746         
5747         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5748         
5749         aopOp((left = IC_LEFT(ic)),ic,FALSE);
5750         aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5751         aopOp((result=IC_RESULT(ic)),ic,TRUE);
5752         
5753         /* if left is a literal & right is not ||
5754         if left needs acc & right does not */
5755         if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5756                 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5757                 operand *tmp = right ;
5758                 right = left;
5759                 left = tmp;
5760         }
5761         
5762         /* if result = right then exchange them */
5763         if(pic14_sameRegs(AOP(result),AOP(right))){
5764                 operand *tmp = right ;
5765                 right = left;
5766                 left = tmp;
5767         }
5768         
5769         /* if right is bit then exchange them */
5770         if (AOP_TYPE(right) == AOP_CRY &&
5771                 AOP_TYPE(left) != AOP_CRY){
5772                 operand *tmp = right ;
5773                 right = left;
5774                 left = tmp;
5775         }
5776         if(AOP_TYPE(right) == AOP_LIT)
5777                 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5778         
5779         size = AOP_SIZE(result);
5780         
5781         // if(bit ^ yy)
5782         // xx = bit ^ yy;
5783         if (AOP_TYPE(left) == AOP_CRY){
5784                 if(AOP_TYPE(right) == AOP_LIT){
5785                         // c = bit & literal;
5786                         if(lit>>1){
5787                                 // lit>>1  != 0 => result = 1
5788                                 if(AOP_TYPE(result) == AOP_CRY){
5789                                         if(size)
5790                                         {emitpcode(POC_BSF,  popGet(AOP(result),offset));
5791                                         pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5792                                         else if(ifx)
5793                                                 continueIfTrue(ifx);
5794                                         goto release;
5795                                 }
5796                                 pic14_emitcode("setb","c");
5797                         } else{
5798                                 // lit == (0 or 1)
5799                                 if(lit == 0){
5800                                         // lit == 0, result = left
5801                                         if(size && pic14_sameRegs(AOP(result),AOP(left)))
5802                                                 goto release;
5803                                         pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5804                                 } else{
5805                                         // lit == 1, result = not(left)
5806                                         if(size && pic14_sameRegs(AOP(result),AOP(left))){
5807                                                 emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
5808                                                 emitpcode(POC_XORWF,  popGet(AOP(result),offset));
5809                                                 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5810                                                 goto release;
5811                                         } else {
5812                                                 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5813                                                 pic14_emitcode("cpl","c");
5814                                         }
5815                                 }
5816                         }
5817                         
5818                 } else {
5819                         // right != literal
5820                         symbol *tlbl = newiTempLabel(NULL);
5821                         if (AOP_TYPE(right) == AOP_CRY){
5822                                 // c = bit ^ bit;
5823                                 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5824                         }
5825                         else{
5826                                 int sizer = AOP_SIZE(right);
5827                                 // c = bit ^ val
5828                                 // if val>>1 != 0, result = 1
5829                                 pic14_emitcode("setb","c");
5830                                 while(sizer){
5831                                         MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5832                                         if(sizer == 1)
5833                                                 // test the msb of the lsb
5834                                                 pic14_emitcode("anl","a,#0xfe");
5835                                         pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5836                                         sizer--;
5837                                 }
5838                                 // val = (0,1)
5839                                 pic14_emitcode("rrc","a");
5840                         }
5841                         pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5842                         pic14_emitcode("cpl","c");
5843                         pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5844                 }
5845                 // bit = c
5846                 // val = c
5847                 if(size)
5848                         pic14_outBitC(result);
5849                 // if(bit | ...)
5850                 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5851                         genIfxJump(ifx, "c");           
5852                 goto release ;
5853         }
5854         
5855         if(pic14_sameRegs(AOP(result),AOP(left))){
5856                 /* if left is same as result */
5857                 for(;size--; offset++) {
5858                         if(AOP_TYPE(right) == AOP_LIT){
5859                                 int t  = (lit >> (offset*8)) & 0x0FFL;
5860                                 if(t == 0x00L)
5861                                         continue;
5862                                 else
5863                                         if (IS_AOP_PREG(left)) {
5864                                                 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5865                                                 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5866                                                 aopPut(AOP(result),"a",offset);
5867                                         } else {
5868                                                 emitpcode(POC_MOVLW, popGetLit(t));
5869                                                 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5870                                                 pic14_emitcode("xrl","%s,%s",
5871                                                         aopGet(AOP(left),offset,FALSE,TRUE),
5872                                                         aopGet(AOP(right),offset,FALSE,FALSE));
5873                                         }
5874                         } else {
5875                                 if (AOP_TYPE(left) == AOP_ACC)
5876                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5877                                 else {
5878                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5879                                         emitpcode(POC_XORWF,popGet(AOP(left),offset));
5880                                         /*
5881                                         if (IS_AOP_PREG(left)) {
5882                                         pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5883                                         aopPut(AOP(result),"a",offset);
5884                                         } else
5885                                         pic14_emitcode("xrl","%s,a",
5886                                         aopGet(AOP(left),offset,FALSE,TRUE));
5887                                         */
5888                                 }
5889                         }
5890                 }
5891         } else {
5892                 // left & result in different registers
5893                 if(AOP_TYPE(result) == AOP_CRY){
5894                         // result = bit
5895                         // if(size), result in bit
5896                         // if(!size && ifx), conditional oper: if(left ^ right)
5897                         symbol *tlbl = newiTempLabel(NULL);
5898                         int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5899                         if(size)
5900                                 pic14_emitcode("setb","c");
5901                         while(sizer--){
5902                                 if((AOP_TYPE(right) == AOP_LIT) &&
5903                                         (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5904                                         MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5905                                 } else {
5906                                         MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5907                                         pic14_emitcode("xrl","a,%s",
5908                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5909                                 }
5910                                 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5911                                 offset++;
5912                         }
5913                         if(size){
5914                                 CLRC;
5915                                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5916                                 pic14_outBitC(result);
5917                         } else if(ifx)
5918                                 jmpTrueOrFalse(ifx, tlbl);
5919                 } else for(;(size--);offset++){
5920                         // normal case
5921                         // result = left & right
5922                         if(AOP_TYPE(right) == AOP_LIT){
5923                                 int t = (lit >> (offset*8)) & 0x0FFL;
5924                                 switch(t) { 
5925                                 case 0x00:
5926                                         if (AOP_TYPE(left) != AOP_ACC) {
5927                                                 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5928                                         }
5929                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5930                                         pic14_emitcode("movf","%s,w",
5931                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5932                                         pic14_emitcode("movwf","%s",
5933                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5934                                         break;
5935                                 case 0xff:
5936                                         if (AOP_TYPE(left) == AOP_ACC) {
5937                                                 emitpcode(POC_XORLW, popGetLit(t));
5938                                         } else {
5939                                                 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5940                                         }
5941                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5942                                         break;
5943                                 default:
5944                                         if (AOP_TYPE(left) == AOP_ACC) {
5945                                                 emitpcode(POC_XORLW, popGetLit(t));
5946                                         } else {
5947                                                 emitpcode(POC_MOVLW, popGetLit(t));
5948                                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5949                                         }
5950                                         emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5951                                         pic14_emitcode("movlw","0x%x",t);
5952                                         pic14_emitcode("xorwf","%s,w",
5953                                                 aopGet(AOP(left),offset,FALSE,FALSE));
5954                                         pic14_emitcode("movwf","%s",
5955                                                 aopGet(AOP(result),offset,FALSE,FALSE));
5956                                         
5957                                 }
5958                                 continue;
5959                         }
5960                         
5961                         // faster than result <- left, anl result,right
5962                         // and better if result is SFR
5963                         if (AOP_TYPE(left) == AOP_ACC) {
5964                                 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5965                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5966                         } else {
5967                                 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5968                                 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5969                                 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5970                                 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5971                         }
5972                         if ( AOP_TYPE(result) != AOP_ACC){
5973                                 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5974                                 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5975                         }
5976                 }
5977         }
5978         
5979 release :
5980         freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5981         freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5982         freeAsmop(result,NULL,ic,TRUE);     
5983 }
5984
5985 /*-----------------------------------------------------------------*/
5986 /* genInline - write the inline code out                           */
5987 /*-----------------------------------------------------------------*/
5988 static void genInline (iCode *ic)
5989 {
5990         char *buffer, *bp, *bp1;
5991         
5992         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
5993         
5994         _G.inLine += (!options.asmpeep);
5995         
5996         buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5997         strcpy(buffer,IC_INLINE(ic));
5998         
5999         /* emit each line as a code */
6000         while (*bp) {
6001                 if (*bp == '\n') {
6002                         *bp++ = '\0';
6003                         
6004                         if(*bp1)
6005                                 addpCode2pBlock(pb,AssembleLine(bp1));
6006                         bp1 = bp;
6007                 } else {
6008                         if (*bp == ':') {
6009                                 bp++;
6010                                 *bp = '\0';
6011                                 bp++;
6012                                 pic14_emitcode(bp1,"");
6013                                 bp1 = bp;
6014                         } else
6015                                 bp++;
6016                 }
6017         }
6018         if ((bp1 != bp) && *bp1)
6019                 addpCode2pBlock(pb,AssembleLine(bp1));
6020         
6021         Safe_free(buffer);
6022         
6023         _G.inLine -= (!options.asmpeep);
6024 }
6025
6026 /*-----------------------------------------------------------------*/
6027 /* genRRC - rotate right with carry                                */
6028 /*-----------------------------------------------------------------*/
6029 static void genRRC (iCode *ic)
6030 {
6031         operand *left , *result ;
6032         int size, offset = 0, same;
6033         
6034         /* rotate right with carry */
6035         left = IC_LEFT(ic);
6036         result=IC_RESULT(ic);
6037         aopOp (left,ic,FALSE);
6038         aopOp (result,ic,FALSE);
6039         
6040         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6041         
6042         same = pic14_sameRegs(AOP(result),AOP(left));
6043         
6044         size = AOP_SIZE(result);    
6045         
6046         /* get the lsb and put it into the carry */
6047         emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6048         
6049         offset = 0 ;
6050         
6051         while(size--) {
6052                 
6053                 if(same) {
6054                         emitpcode(POC_RRF, popGet(AOP(left),offset));
6055                 } else {
6056                         emitpcode(POC_RRFW, popGet(AOP(left),offset));
6057                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6058                 }
6059                 
6060                 offset++;
6061         }
6062         
6063         freeAsmop(left,NULL,ic,TRUE);
6064         freeAsmop(result,NULL,ic,TRUE);
6065 }
6066
6067 /*-----------------------------------------------------------------*/
6068 /* genRLC - generate code for rotate left with carry               */
6069 /*-----------------------------------------------------------------*/
6070 static void genRLC (iCode *ic)
6071 {    
6072         operand *left , *result ;
6073         int size, offset = 0;
6074         int same;
6075         
6076         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6077         /* rotate right with carry */
6078         left = IC_LEFT(ic);
6079         result=IC_RESULT(ic);
6080         aopOp (left,ic,FALSE);
6081         aopOp (result,ic,FALSE);
6082         
6083         DEBUGpic14_AopType(__LINE__,left,NULL,result);
6084         
6085         same = pic14_sameRegs(AOP(result),AOP(left));
6086         
6087         /* move it to the result */
6088         size = AOP_SIZE(result);    
6089         
6090         /* get the msb and put it into the carry */
6091         emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6092         
6093         offset = 0 ;
6094         
6095         while(size--) {
6096                 
6097                 if(same) {
6098                         emitpcode(POC_RLF, popGet(AOP(left),offset));
6099                 } else {
6100                         emitpcode(POC_RLFW, popGet(AOP(left),offset));
6101                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6102                 }
6103                 
6104                 offset++;
6105         }
6106         
6107         
6108         freeAsmop(left,NULL,ic,TRUE);
6109         freeAsmop(result,NULL,ic,TRUE);
6110 }
6111
6112 /*-----------------------------------------------------------------*/
6113 /* genGetHbit - generates code get highest order bit               */
6114 /*-----------------------------------------------------------------*/
6115 static void genGetHbit (iCode *ic)
6116 {
6117         operand *left, *result;
6118         left = IC_LEFT(ic);
6119         result=IC_RESULT(ic);
6120         aopOp (left,ic,FALSE);
6121         aopOp (result,ic,FALSE);
6122         
6123         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6124         /* get the highest order byte into a */
6125         MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6126         if(AOP_TYPE(result) == AOP_CRY){
6127                 pic14_emitcode("rlc","a");
6128                 pic14_outBitC(result);
6129         }
6130         else{
6131                 pic14_emitcode("rl","a");
6132                 pic14_emitcode("anl","a,#0x01");
6133                 pic14_outAcc(result);
6134         }
6135         
6136         
6137         freeAsmop(left,NULL,ic,TRUE);
6138         freeAsmop(result,NULL,ic,TRUE);
6139 }
6140
6141 /*-----------------------------------------------------------------*/
6142 /* AccRol - rotate left accumulator by known count                 */
6143 /*-----------------------------------------------------------------*/
6144 static void AccRol (int shCount)
6145 {
6146         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6147         shCount &= 0x0007;              // shCount : 0..7
6148         switch(shCount){
6149         case 0 :
6150                 break;
6151         case 1 :
6152                 pic14_emitcode("rl","a");
6153                 break;
6154         case 2 :
6155                 pic14_emitcode("rl","a");
6156                 pic14_emitcode("rl","a");
6157                 break;
6158         case 3 :
6159                 pic14_emitcode("swap","a");
6160                 pic14_emitcode("rr","a");
6161                 break;
6162         case 4 :
6163                 pic14_emitcode("swap","a");
6164                 break;
6165         case 5 :
6166                 pic14_emitcode("swap","a");
6167                 pic14_emitcode("rl","a");
6168                 break;
6169         case 6 :
6170                 pic14_emitcode("rr","a");
6171                 pic14_emitcode("rr","a");
6172                 break;
6173         case 7 :
6174                 pic14_emitcode("rr","a");
6175                 break;
6176         }
6177 }
6178
6179 /*-----------------------------------------------------------------*/
6180 /* AccLsh - left shift accumulator by known count                  */
6181 /*-----------------------------------------------------------------*/
6182 static void AccLsh (int shCount)
6183 {
6184         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6185         if(shCount != 0){
6186                 if(shCount == 1)
6187                         pic14_emitcode("add","a,acc");
6188                 else 
6189                         if(shCount == 2) {
6190                                 pic14_emitcode("add","a,acc");
6191                                 pic14_emitcode("add","a,acc");
6192                         } else {
6193                                 /* rotate left accumulator */
6194                                 AccRol(shCount);
6195                                 /* and kill the lower order bits */
6196                                 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6197                         }
6198         }
6199 }
6200
6201 /*-----------------------------------------------------------------*/
6202 /* AccRsh - right shift accumulator by known count                 */
6203 /*-----------------------------------------------------------------*/
6204 static void AccRsh (int shCount)
6205 {
6206         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6207         if(shCount != 0){
6208                 if(shCount == 1){
6209                         CLRC;
6210                         pic14_emitcode("rrc","a");
6211                 } else {
6212                         /* rotate right accumulator */
6213                         AccRol(8 - shCount);
6214                         /* and kill the higher order bits */
6215                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6216                 }
6217         }
6218 }
6219
6220 #if 0
6221 /*-----------------------------------------------------------------*/
6222 /* AccSRsh - signed right shift accumulator by known count                 */
6223 /*-----------------------------------------------------------------*/
6224 static void AccSRsh (int shCount)
6225 {
6226         symbol *tlbl ;
6227         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6228         if(shCount != 0){
6229                 if(shCount == 1){
6230                         pic14_emitcode("mov","c,acc.7");
6231                         pic14_emitcode("rrc","a");
6232                 } else if(shCount == 2){
6233                         pic14_emitcode("mov","c,acc.7");
6234                         pic14_emitcode("rrc","a");
6235                         pic14_emitcode("mov","c,acc.7");
6236                         pic14_emitcode("rrc","a");
6237                 } else {
6238                         tlbl = newiTempLabel(NULL);
6239                         /* rotate right accumulator */
6240                         AccRol(8 - shCount);
6241                         /* and kill the higher order bits */
6242                         pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6243                         pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6244                         pic14_emitcode("orl","a,#0x%02x",
6245                                 (unsigned char)~SRMask[shCount]);
6246                         pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6247                 }
6248         }
6249 }
6250 #endif
6251 /*-----------------------------------------------------------------*/
6252 /* shiftR1Left2Result - shift right one byte from left to result   */
6253 /*-----------------------------------------------------------------*/
6254 static void shiftR1Left2ResultSigned (operand *left, int offl,
6255                                                                           operand *result, int offr,
6256                                                                           int shCount)
6257 {
6258         int same;
6259         
6260         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6261         
6262         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6263         
6264         switch(shCount) {
6265         case 1:
6266                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6267                 if(same) 
6268                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6269                 else {
6270                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6271                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6272                 }
6273                 
6274                 break;
6275         case 2:
6276                 
6277                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6278                 if(same) 
6279                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6280                 else {
6281                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6282                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6283                 }
6284                 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6285                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6286                 
6287                 break;
6288                 
6289         case 3:
6290                 if(same)
6291                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6292                 else {
6293                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6294                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6295                 }
6296                 
6297                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6298                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6299                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6300                 
6301                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6302                 emitpcode(POC_IORLW, popGetLit(0xe0));
6303                 
6304                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6305                 break;
6306                 
6307         case 4:
6308                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6309                 emitpcode(POC_ANDLW,  popGetLit(0x0f));
6310                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6311                 emitpcode(POC_IORLW,  popGetLit(0xf0));
6312                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6313                 break;
6314         case 5:
6315                 if(same) {
6316                         emitpcode(POC_SWAPF,  popGet(AOP(result),offr));
6317                 } else {
6318                         emitpcode(POC_SWAPFW,  popGet(AOP(left),offl));
6319                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6320                 }
6321                 emitpcode(POC_RRFW,   popGet(AOP(result),offr));
6322                 emitpcode(POC_ANDLW,  popGetLit(0x07));
6323                 emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6324                 emitpcode(POC_IORLW,  popGetLit(0xf8));
6325                 emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6326                 break;
6327                 
6328         case 6:
6329                 if(same) {
6330                         emitpcode(POC_MOVLW, popGetLit(0x00));
6331                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6332                         emitpcode(POC_MOVLW, popGetLit(0xfe));
6333                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6334                         emitpcode(POC_IORLW, popGetLit(0x01));
6335                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6336                 } else {
6337                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6338                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6339                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6340                         emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6341                         emitpcode(POC_BCF,   newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6342                 }
6343                 break;
6344                 
6345         case 7:
6346                 if(same) {
6347                         emitpcode(POC_MOVLW, popGetLit(0x00));
6348                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6349                         emitpcode(POC_MOVLW, popGetLit(0xff));
6350                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6351                 } else {
6352                         emitpcode(POC_CLRF,  popGet(AOP(result),offr));
6353                         emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6354                         emitpcode(POC_DECF,  popGet(AOP(result),offr));
6355                 }
6356                 
6357         default:
6358                 break;
6359         }
6360 }
6361
6362 /*-----------------------------------------------------------------*/
6363 /* shiftR1Left2Result - shift right one byte from left to result   */
6364 /*-----------------------------------------------------------------*/
6365 static void shiftR1Left2Result (operand *left, int offl,
6366                                                                 operand *result, int offr,
6367                                                                 int shCount, int sign)
6368 {
6369         int same;
6370         
6371         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6372         
6373         same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6374         
6375         /* Copy the msb into the carry if signed. */
6376         if(sign) {
6377                 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6378                 return;
6379         }
6380         
6381         
6382         
6383         switch(shCount) {
6384         case 1:
6385                 emitCLRC;
6386                 if(same) 
6387                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6388                 else {
6389                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6390                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6391                 }
6392                 break;
6393         case 2:
6394                 emitCLRC;
6395                 if(same) {
6396                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6397                 } else {
6398                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6399                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6400                 }
6401                 emitCLRC;
6402                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6403                 
6404                 break;
6405         case 3:
6406                 if(same)
6407                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6408                 else {
6409                         emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6410                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6411                 }
6412                 
6413                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6414                 emitpcode(POC_RLFW,  popGet(AOP(result),offr));
6415                 emitpcode(POC_ANDLW, popGetLit(0x1f));
6416                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6417                 break;
6418                 
6419         case 4:
6420                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6421                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6422                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6423                 break;
6424                 
6425         case 5:
6426                 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6427                 emitpcode(POC_ANDLW, popGetLit(0x0f));
6428                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6429                 emitCLRC;
6430                 emitpcode(POC_RRF, popGet(AOP(result),offr));
6431                 
6432                 break;
6433         case 6:
6434                 
6435                 emitpcode(POC_RLFW,  popGet(AOP(left),offl));
6436                 emitpcode(POC_ANDLW, popGetLit(0x80));
6437                 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6439                 emitpcode(POC_RLF,   popGet(AOP(result),offr));
6440                 break;
6441                 
6442         case 7:
6443                 
6444                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6445                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6446                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6447                 
6448                 break;
6449                 
6450         default:
6451                 break;
6452         }
6453 }
6454
6455 /*-----------------------------------------------------------------*/
6456 /* shiftL1Left2Result - shift left one byte from left to result    */
6457 /*-----------------------------------------------------------------*/
6458 static void shiftL1Left2Result (operand *left, int offl,
6459                                                                 operand *result, int offr, int shCount)
6460 {
6461         int same;
6462         
6463         //    char *l;
6464         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6465         
6466         same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6467         DEBUGpic14_emitcode ("; ***","same =  %d",same);
6468         //    l = aopGet(AOP(left),offl,FALSE,FALSE);
6469         //    MOVA(l);
6470         /* shift left accumulator */
6471         //AccLsh(shCount); // don't comment out just yet...
6472         //    aopPut(AOP(result),"a",offr);
6473         
6474         switch(shCount) {
6475         case 1:
6476                 /* Shift left 1 bit position */
6477                 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6478                 if(same) {
6479                         emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6480                 } else {
6481                         emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6482                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6483                 }
6484                 break;
6485         case 2:
6486                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6487                 emitpcode(POC_ANDLW,popGetLit(0x7e));
6488                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6489                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6490                 break;
6491         case 3:
6492                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6493                 emitpcode(POC_ANDLW,popGetLit(0x3e));
6494                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6495                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6496                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6497                 break;
6498         case 4:
6499                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6500                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6501                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6502                 break;
6503         case 5:
6504                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6505                 emitpcode(POC_ANDLW, popGetLit(0xf0));
6506                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6507                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6508                 break;
6509         case 6:
6510                 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6511                 emitpcode(POC_ANDLW, popGetLit(0x30));
6512                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6513                 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6514                 emitpcode(POC_RLF,  popGet(AOP(result),offr));
6515                 break;
6516         case 7:
6517                 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6518                 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6519                 emitpcode(POC_RRF,  popGet(AOP(result),offr));
6520                 break;
6521                 
6522         default:
6523                 DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6524         }
6525         
6526 }
6527
6528 /*-----------------------------------------------------------------*/
6529 /* movLeft2Result - move byte from left to result                  */
6530 /*-----------------------------------------------------------------*/
6531 static void movLeft2Result (operand *left, int offl,
6532                                                         operand *result, int offr)
6533 {
6534         char *l;
6535         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6536         if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6537                 l = aopGet(AOP(left),offl,FALSE,FALSE);
6538                 
6539                 if (*l == '@' && (IS_AOP_PREG(result))) {
6540                         pic14_emitcode("mov","a,%s",l);
6541                         aopPut(AOP(result),"a",offr);
6542                 } else {
6543                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6544                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6545                 }
6546         }
6547 }
6548
6549 /*-----------------------------------------------------------------*/
6550 /* shiftL2Left2Result - shift left two bytes from left to result   */
6551 /*-----------------------------------------------------------------*/
6552 static void shiftL2Left2Result (operand *left, int offl,
6553                                                                 operand *result, int offr, int shCount)
6554 {
6555         
6556         
6557         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6558         
6559         if(pic14_sameRegs(AOP(result), AOP(left))) {
6560                 switch(shCount) {
6561                 case 0:
6562                         break;
6563                 case 1:
6564                 case 2:
6565                 case 3:
6566                         
6567                         emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6568                         emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6569                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6570                         
6571                         while(--shCount) {
6572                                 emitCLRC;
6573                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6574                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6575                         }
6576                         
6577                         break;
6578                 case 4:
6579                 case 5:
6580                         emitpcode(POC_MOVLW, popGetLit(0x0f));
6581                         emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6582                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6583                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6584                         emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6585                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6586                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6587                         if(shCount >=5) {
6588                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6589                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6590                         }
6591                         break;
6592                 case 6:
6593                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6594                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6595                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6596                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6597                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6598                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6599                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6600                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6601                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6602                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6603                         break;
6604                 case 7:
6605                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6606                         emitpcode(POC_RRFW, popGet(AOP(result),offr));
6607                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6608                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6609                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6610                 }
6611                 
6612         } else {
6613                 switch(shCount) {
6614                 case 0:
6615                         break;
6616                 case 1:
6617                 case 2:
6618                 case 3:
6619                 /* note, use a mov/add for the shift since the mov has a
6620                         chance of getting optimized out */
6621                         emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6622                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6623                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6624                         emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16));
6625                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6626                         
6627                         while(--shCount) {
6628                                 emitCLRC;
6629                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6630                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6631                         }
6632                         break;
6633                         
6634                 case 4:
6635                 case 5:
6636                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6637                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6638                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6639                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6640                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6641                         emitpcode(POC_ANDLW, popGetLit(0xF0));
6642                         emitpcode(POC_XORWF, popGet(AOP(result),offr));
6643                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6644                         
6645                         
6646                         if(shCount == 5) {
6647                                 emitpcode(POC_RLF, popGet(AOP(result),offr));
6648                                 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6649                         }
6650                         break;
6651                 case 6:
6652                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6653                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6654                         emitpcode(POC_RRFW, popGet(AOP(result),offl));
6655                         emitpcode(POC_MOVWF,  popGet(AOP(result),offr));
6656                         
6657                         emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16));
6658                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6659                         emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6660                         emitpcode(POC_ANDLW,popGetLit(0xc0));
6661                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6662                         emitpcode(POC_XORWF,popGet(AOP(result),offr));
6663                         emitpcode(POC_XORFW,popGet(AOP(result),offr));
6664                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6665                         break;
6666                 case 7:
6667                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6668                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6669                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6670                         emitpcode(POC_CLRF, popGet(AOP(result),offr));
6671                         emitpcode(POC_RRF,  popGet(AOP(result),offr));
6672                 }
6673         }
6674         
6675 }
6676 /*-----------------------------------------------------------------*/
6677 /* shiftR2Left2Result - shift right two bytes from left to result  */
6678 /*-----------------------------------------------------------------*/
6679 static void shiftR2Left2Result (operand *left, int offl,
6680                                                                 operand *result, int offr,
6681                                                                 int shCount, int sign)
6682 {
6683         int same=0;
6684         
6685         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6686         same = pic14_sameRegs(AOP(result), AOP(left));
6687         
6688         if(same && ((offl + MSB16) == offr)){
6689                 same=1;
6690                 /* don't crash result[offr] */
6691                 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6692                 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6693         }
6694         /* else {
6695         movLeft2Result(left,offl, result, offr);
6696         MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6697         }
6698         */
6699         /* a:x >> shCount (x = lsb(result))*/
6700         /*
6701         if(sign)
6702         AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6703         else {
6704         AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6705         */
6706         switch(shCount) {
6707         case 0:
6708                 break;
6709         case 1:
6710         case 2:
6711         case 3:
6712                 if(sign)
6713                         emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6714                 else
6715                         emitCLRC;
6716                 
6717                 if(same) {
6718                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6719                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6720                 } else {
6721                         emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6722                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6723                         emitpcode(POC_RRFW, popGet(AOP(left),offl));
6724                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6725                 }
6726                 
6727                 while(--shCount) {
6728                         if(sign)
6729                                 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6730                         else
6731                                 emitCLRC;
6732                         emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6733                         emitpcode(POC_RRF,popGet(AOP(result),offr));
6734                 }
6735                 break;
6736         case 4:
6737         case 5:
6738                 if(same) {
6739                         
6740                         emitpcode(POC_MOVLW, popGetLit(0xf0));
6741                         emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6742                         emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6743                         
6744                         emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6745                         emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6746                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6747                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6748                 } else {
6749                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6750                         emitpcode(POC_ANDLW, popGetLit(0x0f));
6751                         emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6752                         
6753                         emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6754                         emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6755                         emitpcode(POC_ANDLW, popGetLit(0xf0));
6756                         emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6757                         emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6758                 }
6759                 
6760                 if(shCount >=5) {
6761                         emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6762                         emitpcode(POC_RRF, popGet(AOP(result),offr));
6763                 }
6764                 
6765                 if(sign) {
6766                         emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6767                         emitpcode(POC_BTFSC, 
6768                                 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6769                         emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6770                 }
6771                 
6772                 break;
6773                 
6774         case 6:
6775                 if(same) {
6776                         
6777                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6778                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6779                         
6780                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6781                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6782                         emitpcode(POC_RLFW, popGet(AOP(result),offr));
6783                         emitpcode(POC_ANDLW,popGetLit(0x03));
6784                         if(sign) {
6785                                 emitpcode(POC_BTFSC, 
6786                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6787                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6788                         }
6789                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6790                         emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6791                         emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6792                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6793                 } else {
6794                         emitpcode(POC_RLFW, popGet(AOP(left),offl));
6795                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6796                         emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6797                         emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6798                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6799                         emitpcode(POC_RLF,  popGet(AOP(result),offr));
6800                         emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6801                         emitpcode(POC_ANDLW,popGetLit(0x03));
6802                         if(sign) {
6803                                 emitpcode(POC_BTFSC, 
6804                                         newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6805                                 emitpcode(POC_IORLW,popGetLit(0xfc));
6806                         }
6807                         emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6808                         //emitpcode(POC_RLF,  popGet(AOP(result),offr));
6809                         
6810                         
6811                 }
6812                 
6813                 break;
6814         case 7:
6815                 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6816                 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6817                 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6818                 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6819                 if(sign) {
6820                         emitSKPNC;
6821                         emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6822                 } else 
6823                         emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16));
6824   }
6825 }
6826
6827
6828 /*-----------------------------------------------------------------*/
6829 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6830 /*-----------------------------------------------------------------*/
6831 static void shiftLLeftOrResult (operand *left, int offl,
6832                                                                 operand *result, int offr, int shCount)
6833 {
6834         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6835         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6836         /* shift left accumulator */
6837         AccLsh(shCount);
6838         /* or with result */
6839         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6840         /* back to result */
6841         aopPut(AOP(result),"a",offr);
6842 }
6843
6844 /*-----------------------------------------------------------------*/
6845 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6846 /*-----------------------------------------------------------------*/
6847 static void shiftRLeftOrResult (operand *left, int offl,
6848                                                                 operand *result, int offr, int shCount)
6849 {
6850         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6851         MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6852         /* shift right accumulator */
6853         AccRsh(shCount);
6854         /* or with result */
6855         pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6856         /* back to result */
6857         aopPut(AOP(result),"a",offr);
6858 }
6859
6860 /*-----------------------------------------------------------------*/
6861 /* genlshOne - left shift a one byte quantity by known count       */
6862 /*-----------------------------------------------------------------*/
6863 static void genlshOne (operand *result, operand *left, int shCount)
6864 {       
6865         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6866         shiftL1Left2Result(left, LSB, result, LSB, shCount);
6867 }
6868
6869 /*-----------------------------------------------------------------*/
6870 /* genlshTwo - left shift two bytes by known amount != 0           */
6871 /*-----------------------------------------------------------------*/
6872 static void genlshTwo (operand *result,operand *left, int shCount)
6873 {
6874         int size;
6875         
6876         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6877         size = pic14_getDataSize(result);
6878         
6879         /* if shCount >= 8 */
6880         if (shCount >= 8) {
6881                 shCount -= 8 ;
6882                 
6883                 if (size > 1){
6884                         if (shCount)
6885                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6886                         else 
6887                                 movLeft2Result(left, LSB, result, MSB16);
6888                 }
6889                 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6890         }
6891         
6892         /*  1 <= shCount <= 7 */
6893         else {  
6894                 if(size == 1)
6895                         shiftL1Left2Result(left, LSB, result, LSB, shCount); 
6896                 else 
6897                         shiftL2Left2Result(left, LSB, result, LSB, shCount);
6898         }
6899 }
6900
6901 /*-----------------------------------------------------------------*/
6902 /* shiftLLong - shift left one long from left to result            */
6903 /* offl = LSB or MSB16                                             */
6904 /*-----------------------------------------------------------------*/
6905 static void shiftLLong (operand *left, operand *result, int offr )
6906 {
6907         char *l;
6908         int size = AOP_SIZE(result);
6909         
6910         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6911         if(size >= LSB+offr){
6912                 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6913                 MOVA(l);
6914                 pic14_emitcode("add","a,acc");
6915                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6916                         size >= MSB16+offr && offr != LSB )
6917                         pic14_emitcode("xch","a,%s",
6918                         aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6919                 else      
6920                         aopPut(AOP(result),"a",LSB+offr);
6921         }
6922         
6923         if(size >= MSB16+offr){
6924                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6925                         l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6926                         MOVA(l);
6927                 }
6928                 pic14_emitcode("rlc","a");
6929                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6930                         size >= MSB24+offr && offr != LSB)
6931                         pic14_emitcode("xch","a,%s",
6932                         aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6933                 else      
6934                         aopPut(AOP(result),"a",MSB16+offr);
6935         }
6936         
6937         if(size >= MSB24+offr){
6938                 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6939                         l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6940                         MOVA(l);
6941                 }
6942                 pic14_emitcode("rlc","a");
6943                 if (pic14_sameRegs(AOP(left),AOP(result)) && 
6944                         size >= MSB32+offr && offr != LSB )
6945                         pic14_emitcode("xch","a,%s",
6946                         aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6947                 else      
6948                         aopPut(AOP(result),"a",MSB24+offr);
6949         }
6950         
6951         if(size > MSB32+offr){
6952                 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6953                         l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6954                         MOVA(l);  
6955                 }
6956                 pic14_emitcode("rlc","a");
6957                 aopPut(AOP(result),"a",MSB32+offr);
6958         }
6959         if(offr != LSB)
6960                 aopPut(AOP(result),zero,LSB);       
6961 }
6962
6963 /*-----------------------------------------------------------------*/
6964 /* genlshFour - shift four byte by a known amount != 0             */
6965 /*-----------------------------------------------------------------*/
6966 static void genlshFour (operand *result, operand *left, int shCount)
6967 {
6968         int size;
6969         
6970         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
6971         size = AOP_SIZE(result);
6972         
6973         /* if shifting more that 3 bytes */
6974         if (shCount >= 24 ) {
6975                 shCount -= 24;
6976                 if (shCount)
6977                 /* lowest order of left goes to the highest
6978                 order of the destination */
6979                 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6980                 else
6981                         movLeft2Result(left, LSB, result, MSB32);
6982                 aopPut(AOP(result),zero,LSB);
6983                 aopPut(AOP(result),zero,MSB16);
6984                 aopPut(AOP(result),zero,MSB32);
6985                 return;
6986         }
6987         
6988         /* more than two bytes */
6989         else if ( shCount >= 16 ) {
6990                 /* lower order two bytes goes to higher order two bytes */
6991                 shCount -= 16;
6992                 /* if some more remaining */
6993                 if (shCount)
6994                         shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6995                 else {
6996                         movLeft2Result(left, MSB16, result, MSB32);
6997                         movLeft2Result(left, LSB, result, MSB24);
6998                 }
6999                 aopPut(AOP(result),zero,MSB16);
7000                 aopPut(AOP(result),zero,LSB);
7001                 return;
7002         }    
7003         
7004         /* if more than 1 byte */
7005         else if ( shCount >= 8 ) {
7006                 /* lower order three bytes goes to higher order  three bytes */
7007                 shCount -= 8;
7008                 if(size == 2){
7009                         if(shCount)
7010                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7011                         else
7012                                 movLeft2Result(left, LSB, result, MSB16);
7013                 }
7014                 else{   /* size = 4 */
7015                         if(shCount == 0){
7016                                 movLeft2Result(left, MSB24, result, MSB32);
7017                                 movLeft2Result(left, MSB16, result, MSB24);
7018                                 movLeft2Result(left, LSB, result, MSB16);
7019                                 aopPut(AOP(result),zero,LSB);
7020                         }
7021                         else if(shCount == 1)
7022                                 shiftLLong(left, result, MSB16);
7023                         else{
7024                                 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7025                                 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7026                                 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7027                                 aopPut(AOP(result),zero,LSB);
7028                         }
7029                 }
7030         }
7031         
7032         /* 1 <= shCount <= 7 */
7033         else if(shCount <= 2){
7034                 shiftLLong(left, result, LSB);
7035                 if(shCount == 2)
7036                         shiftLLong(result, result, LSB);
7037         }
7038         /* 3 <= shCount <= 7, optimize */
7039         else{
7040                 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7041                 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7042                 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7043         }
7044 }
7045
7046 /*-----------------------------------------------------------------*/
7047 /* genLeftShiftLiteral - left shifting by known count              */
7048 /*-----------------------------------------------------------------*/
7049 static void genLeftShiftLiteral (operand *left,
7050                                                                  operand *right,
7051                                                                  operand *result,
7052                                                                  iCode *ic)
7053 {    
7054         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7055         int size;
7056         
7057         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7058         freeAsmop(right,NULL,ic,TRUE);
7059         
7060         aopOp(left,ic,FALSE);
7061         aopOp(result,ic,FALSE);
7062         
7063         size = getSize(operandType(result));
7064         
7065 #if VIEW_SIZE
7066         pic14_emitcode("; shift left ","result %d, left %d",size,
7067                 AOP_SIZE(left));
7068 #endif
7069         
7070         /* I suppose that the left size >= result size */
7071         if(shCount == 0){
7072                 while(size--){
7073                         movLeft2Result(left, size, result, size);
7074                 }
7075         }
7076         
7077         else if(shCount >= (size * 8))
7078                 while(size--)
7079                         aopPut(AOP(result),zero,size);
7080                 else{
7081                         switch (size) {
7082                         case 1:
7083                                 genlshOne (result,left,shCount);
7084                                 break;
7085                                 
7086                         case 2:
7087                         case 3:
7088                                 genlshTwo (result,left,shCount);
7089                                 break;
7090                                 
7091                         case 4:
7092                                 genlshFour (result,left,shCount);
7093                                 break;
7094                         }
7095                 }
7096                 freeAsmop(left,NULL,ic,TRUE);
7097                 freeAsmop(result,NULL,ic,TRUE);
7098 }
7099
7100 /*-----------------------------------------------------------------*
7101 * genMultiAsm - repeat assembly instruction for size of register.
7102 * if endian == 1, then the high byte (i.e base address + size of 
7103 * register) is used first else the low byte is used first;
7104 *-----------------------------------------------------------------*/
7105 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7106 {
7107         
7108         int offset = 0;
7109         
7110         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7111         
7112         if(!reg)
7113                 return;
7114         
7115         if(!endian) {
7116                 endian = 1;
7117         } else {
7118                 endian = -1;
7119                 offset = size-1;
7120         }
7121         
7122         while(size--) {
7123                 emitpcode(poc,    popGet(AOP(reg),offset));
7124                 offset += endian;
7125         }
7126         
7127 }
7128 /*-----------------------------------------------------------------*/
7129 /* genLeftShift - generates code for left shifting                 */
7130 /*-----------------------------------------------------------------*/
7131 static void genLeftShift (iCode *ic)
7132 {
7133         operand *left,*right, *result;
7134         int size, offset;
7135         char *l;
7136         symbol *tlbl , *tlbl1;
7137         pCodeOp *pctemp;
7138         
7139         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7140         
7141         right = IC_RIGHT(ic);
7142         left  = IC_LEFT(ic);
7143         result = IC_RESULT(ic);
7144         
7145         aopOp(right,ic,FALSE);
7146         
7147         /* if the shift count is known then do it 
7148         as efficiently as possible */
7149         if (AOP_TYPE(right) == AOP_LIT) {
7150                 genLeftShiftLiteral (left,right,result,ic);
7151                 return ;
7152         }
7153         
7154         /* shift count is unknown then we have to form 
7155         a loop get the loop count in B : Note: we take
7156         only the lower order byte since shifting
7157         more that 32 bits make no sense anyway, ( the
7158         largest size of an object can be only 32 bits ) */  
7159         
7160         
7161         aopOp(left,ic,FALSE);
7162         aopOp(result,ic,FALSE);
7163         
7164         /* now move the left to the result if they are not the
7165         same */
7166         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7167                 AOP_SIZE(result) > 1) {
7168                 
7169                 size = AOP_SIZE(result);
7170                 offset=0;
7171                 while (size--) {
7172                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7173                         if (*l == '@' && (IS_AOP_PREG(result))) {
7174                                 
7175                                 pic14_emitcode("mov","a,%s",l);
7176                                 aopPut(AOP(result),"a",offset);
7177                         } else {
7178                                 emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7179                                 emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7180                                 //aopPut(AOP(result),l,offset);
7181                         }
7182                         offset++;
7183                 }
7184         }
7185         
7186         size = AOP_SIZE(result);
7187         
7188         /* if it is only one byte then */
7189         if (size == 1) {
7190                 if(optimized_for_speed) {
7191                         emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7192                         emitpcode(POC_ANDLW,  popGetLit(0xf0));
7193                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7194                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7195                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7196                         emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7197                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7198                         emitpcode(POC_RLFW,   popGet(AOP(result),0));
7199                         emitpcode(POC_ANDLW,  popGetLit(0xfe));
7200                         emitpcode(POC_ADDFW,  popGet(AOP(result),0));
7201                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7202                         emitpcode(POC_ADDWF,  popGet(AOP(result),0));
7203                 } else {
7204                         
7205                         tlbl = newiTempLabel(NULL);
7206                         if (!pic14_sameRegs(AOP(left),AOP(result))) {
7207                                 emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7208                                 emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7209                         }
7210                         
7211                         emitpcode(POC_COMFW,  popGet(AOP(right),0));
7212                         emitpcode(POC_RRF,    popGet(AOP(result),0));
7213                         emitpLabel(tlbl->key);
7214                         emitpcode(POC_RLF,    popGet(AOP(result),0));
7215                         emitpcode(POC_ADDLW,  popGetLit(1));
7216                         emitSKPC;
7217                         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7218                 }
7219                 goto release ;
7220         }
7221         
7222         if (pic14_sameRegs(AOP(left),AOP(result))) {
7223                 
7224                 tlbl = newiTempLabel(NULL);
7225                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7226                 genMultiAsm(POC_RRF, result, size,1);
7227                 emitpLabel(tlbl->key);
7228                 genMultiAsm(POC_RLF, result, size,0);
7229                 emitpcode(POC_ADDLW,  popGetLit(1));
7230                 emitSKPC;
7231                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7232                 goto release;
7233         }
7234         
7235         //tlbl = newiTempLabel(NULL);
7236         //offset = 0 ;   
7237         //tlbl1 = newiTempLabel(NULL);
7238         
7239         //reAdjustPreg(AOP(result));    
7240         
7241         //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
7242         //pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7243         //l = aopGet(AOP(result),offset,FALSE,FALSE);
7244         //MOVA(l);
7245         //pic14_emitcode("add","a,acc");         
7246         //aopPut(AOP(result),"a",offset++);
7247         //while (--size) {
7248         //  l = aopGet(AOP(result),offset,FALSE,FALSE);
7249         //  MOVA(l);
7250         //  pic14_emitcode("rlc","a");         
7251         //  aopPut(AOP(result),"a",offset++);
7252         //}
7253         //reAdjustPreg(AOP(result));
7254         
7255         //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7256         //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7257         
7258         
7259         tlbl = newiTempLabel(NULL);
7260         tlbl1= newiTempLabel(NULL);
7261         
7262         size = AOP_SIZE(result);
7263         offset = 1;
7264         
7265         pctemp = popGetTempReg();  /* grab a temporary working register. */
7266         
7267         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7268         
7269         /* offset should be 0, 1 or 3 */
7270         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7271         emitSKPNZ;
7272         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7273         
7274         emitpcode(POC_MOVWF, pctemp);
7275         
7276         
7277         emitpLabel(tlbl->key);
7278         
7279         emitCLRC;
7280         emitpcode(POC_RLF,  popGet(AOP(result),0));
7281         while(--size)
7282                 emitpcode(POC_RLF,   popGet(AOP(result),offset++));
7283         
7284         emitpcode(POC_DECFSZ,  pctemp);
7285         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7286         emitpLabel(tlbl1->key);
7287         
7288         popReleaseTempReg(pctemp);
7289         
7290         
7291 release:
7292         freeAsmop (right,NULL,ic,TRUE);
7293         freeAsmop(left,NULL,ic,TRUE);
7294         freeAsmop(result,NULL,ic,TRUE);
7295 }
7296
7297 /*-----------------------------------------------------------------*/
7298 /* genrshOne - right shift a one byte quantity by known count      */
7299 /*-----------------------------------------------------------------*/
7300 static void genrshOne (operand *result, operand *left,
7301                                            int shCount, int sign)
7302 {
7303         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7304         shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7305 }
7306
7307 /*-----------------------------------------------------------------*/
7308 /* genrshTwo - right shift two bytes by known amount != 0          */
7309 /*-----------------------------------------------------------------*/
7310 static void genrshTwo (operand *result,operand *left,
7311                                            int shCount, int sign)
7312 {
7313         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7314         /* if shCount >= 8 */
7315         if (shCount >= 8) {
7316                 shCount -= 8 ;
7317                 if (shCount)
7318                         shiftR1Left2Result(left, MSB16, result, LSB,
7319                         shCount, sign);
7320                 else
7321                         movLeft2Result(left, MSB16, result, LSB);
7322                 
7323                 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7324                 
7325                 if(sign) {
7326                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7327                         emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7328                 }
7329         }
7330         
7331         /*  1 <= shCount <= 7 */
7332         else
7333                 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
7334 }
7335
7336 /*-----------------------------------------------------------------*/
7337 /* shiftRLong - shift right one long from left to result           */
7338 /* offl = LSB or MSB16                                             */
7339 /*-----------------------------------------------------------------*/
7340 static void shiftRLong (operand *left, int offl,
7341                                                 operand *result, int sign)
7342 {
7343         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7344         if(!sign)
7345                 pic14_emitcode("clr","c");
7346         MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7347         if(sign)
7348                 pic14_emitcode("mov","c,acc.7");
7349         pic14_emitcode("rrc","a");
7350         aopPut(AOP(result),"a",MSB32-offl);
7351         if(offl == MSB16)
7352                 /* add sign of "a" */
7353                 addSign(result, MSB32, sign);
7354         
7355         MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7356         pic14_emitcode("rrc","a");
7357         aopPut(AOP(result),"a",MSB24-offl);
7358         
7359         MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7360         pic14_emitcode("rrc","a");
7361         aopPut(AOP(result),"a",MSB16-offl);
7362         
7363         if(offl == LSB){
7364                 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7365                 pic14_emitcode("rrc","a");
7366                 aopPut(AOP(result),"a",LSB);
7367         }
7368 }
7369
7370 /*-----------------------------------------------------------------*/
7371 /* genrshFour - shift four byte by a known amount != 0             */
7372 /*-----------------------------------------------------------------*/
7373 static void genrshFour (operand *result, operand *left,
7374                                                 int shCount, int sign)
7375 {
7376         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7377         /* if shifting more that 3 bytes */
7378         if(shCount >= 24 ) {
7379                 shCount -= 24;
7380                 if(shCount)
7381                         shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7382                 else
7383                         movLeft2Result(left, MSB32, result, LSB);
7384                 
7385                 addSign(result, MSB16, sign);
7386         }
7387         else if(shCount >= 16){
7388                 shCount -= 16;
7389                 if(shCount)
7390                         shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7391                 else{
7392                         movLeft2Result(left, MSB24, result, LSB);
7393                         movLeft2Result(left, MSB32, result, MSB16);
7394                 }
7395                 addSign(result, MSB24, sign);
7396         }
7397         else if(shCount >= 8){
7398                 shCount -= 8;
7399                 if(shCount == 1)
7400                         shiftRLong(left, MSB16, result, sign);
7401                 else if(shCount == 0){
7402                         movLeft2Result(left, MSB16, result, LSB);
7403                         movLeft2Result(left, MSB24, result, MSB16);
7404                         movLeft2Result(left, MSB32, result, MSB24);
7405                         addSign(result, MSB32, sign);
7406                 }
7407                 else{
7408                         shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7409                         shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7410                         /* the last shift is signed */
7411                         shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7412                         addSign(result, MSB32, sign);
7413                 }
7414         }
7415         else{   /* 1 <= shCount <= 7 */
7416                 if(shCount <= 2){
7417                         shiftRLong(left, LSB, result, sign);
7418                         if(shCount == 2)
7419                                 shiftRLong(result, LSB, result, sign);
7420                 }
7421                 else{
7422                         shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7423                         shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7424                         shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7425                 }
7426         }
7427 }
7428
7429 /*-----------------------------------------------------------------*/
7430 /* genRightShiftLiteral - right shifting by known count            */
7431 /*-----------------------------------------------------------------*/
7432 static void genRightShiftLiteral (operand *left,
7433                                                                   operand *right,
7434                                                                   operand *result,
7435                                                                   iCode *ic,
7436                                                                   int sign)
7437 {    
7438         int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7439         int lsize,res_size;
7440         
7441         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7442         freeAsmop(right,NULL,ic,TRUE);
7443         
7444         aopOp(left,ic,FALSE);
7445         aopOp(result,ic,FALSE);
7446         
7447 #if VIEW_SIZE
7448         pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7449                 AOP_SIZE(left));
7450 #endif
7451         
7452         lsize = pic14_getDataSize(left);
7453         res_size = pic14_getDataSize(result);
7454         /* test the LEFT size !!! */
7455         
7456         /* I suppose that the left size >= result size */
7457         if(shCount == 0){
7458                 while(res_size--)
7459                         movLeft2Result(left, lsize, result, res_size);
7460         }
7461         
7462         else if(shCount >= (lsize * 8)){
7463                 
7464                 if(res_size == 1) {
7465                         emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7466                         if(sign) {
7467                                 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7468                                 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7469                         }
7470                 } else {
7471                         
7472                         if(sign) {
7473                                 emitpcode(POC_MOVLW, popGetLit(0));
7474                                 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7475                                 emitpcode(POC_MOVLW, popGetLit(0xff));
7476                                 while(res_size--)
7477                                         emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7478                                 
7479                         } else {
7480                                 
7481                                 while(res_size--)
7482                                         emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7483                         }
7484                 }
7485         } else {
7486                 
7487                 switch (res_size) {
7488                 case 1:
7489                         genrshOne (result,left,shCount,sign);
7490                         break;
7491                         
7492                 case 2:
7493                         genrshTwo (result,left,shCount,sign);
7494                         break;
7495                         
7496                 case 4:
7497                         genrshFour (result,left,shCount,sign);
7498                         break;
7499                 default :
7500                         break;
7501                 }
7502                 
7503         }
7504         
7505         freeAsmop(left,NULL,ic,TRUE);
7506         freeAsmop(result,NULL,ic,TRUE);
7507 }
7508
7509 /*-----------------------------------------------------------------*/
7510 /* genSignedRightShift - right shift of signed number              */
7511 /*-----------------------------------------------------------------*/
7512 static void genSignedRightShift (iCode *ic)
7513 {
7514         operand *right, *left, *result;
7515         int size, offset;
7516         //  char *l;
7517         symbol *tlbl, *tlbl1 ;
7518         pCodeOp *pctemp;
7519         
7520         //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7521         
7522         /* we do it the hard way put the shift count in b
7523         and loop thru preserving the sign */
7524         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7525         
7526         right = IC_RIGHT(ic);
7527         left  = IC_LEFT(ic);
7528         result = IC_RESULT(ic);
7529         
7530         aopOp(right,ic,FALSE);  
7531         aopOp(left,ic,FALSE);
7532         aopOp(result,ic,FALSE);
7533         
7534         
7535         if ( AOP_TYPE(right) == AOP_LIT) {
7536                 genRightShiftLiteral (left,right,result,ic,1);
7537                 return ;
7538         }
7539         /* shift count is unknown then we have to form 
7540         a loop get the loop count in B : Note: we take
7541         only the lower order byte since shifting
7542         more that 32 bits make no sense anyway, ( the
7543         largest size of an object can be only 32 bits ) */  
7544         
7545         //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7546         //pic14_emitcode("inc","b");
7547         //freeAsmop (right,NULL,ic,TRUE);
7548         //aopOp(left,ic,FALSE);
7549         //aopOp(result,ic,FALSE);
7550         
7551         /* now move the left to the result if they are not the
7552         same */
7553         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7554                 AOP_SIZE(result) > 1) {
7555                 
7556                 size = AOP_SIZE(result);
7557                 offset=0;
7558                 while (size--) { 
7559                 /*
7560                 l = aopGet(AOP(left),offset,FALSE,TRUE);
7561                 if (*l == '@' && IS_AOP_PREG(result)) {
7562                 
7563                   pic14_emitcode("mov","a,%s",l);
7564                   aopPut(AOP(result),"a",offset);
7565                   } else
7566                   aopPut(AOP(result),l,offset);
7567                         */
7568                         emitpcode(POC_MOVFW,  popGet(AOP(left),offset));
7569                         emitpcode(POC_MOVWF,  popGet(AOP(result),offset));
7570                         
7571                         offset++;
7572                 }
7573         }
7574         
7575         /* mov the highest order bit to OVR */    
7576         tlbl = newiTempLabel(NULL);
7577         tlbl1= newiTempLabel(NULL);
7578         
7579         size = AOP_SIZE(result);
7580         offset = size - 1;
7581         
7582         pctemp = popGetTempReg();  /* grab a temporary working register. */
7583         
7584         emitpcode(POC_MOVFW, popGet(AOP(right),0));
7585         
7586         /* offset should be 0, 1 or 3 */
7587         emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7588         emitSKPNZ;
7589         emitpcode(POC_GOTO,  popGetLabel(tlbl1->key));
7590         
7591         emitpcode(POC_MOVWF, pctemp);
7592         
7593         
7594         emitpLabel(tlbl->key);
7595         
7596         emitpcode(POC_RLFW,  popGet(AOP(result),offset));
7597         emitpcode(POC_RRF,   popGet(AOP(result),offset));
7598         
7599         while(--size) {
7600                 emitpcode(POC_RRF,   popGet(AOP(result),--offset));
7601         }
7602         
7603         emitpcode(POC_DECFSZ,  pctemp);
7604         emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7605         emitpLabel(tlbl1->key);
7606         
7607         popReleaseTempReg(pctemp);
7608 #if 0
7609         size = AOP_SIZE(result);
7610         offset = size - 1;
7611         pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7612         pic14_emitcode("rlc","a");
7613         pic14_emitcode("mov","ov,c");
7614         /* if it is only one byte then */
7615         if (size == 1) {
7616                 l = aopGet(AOP(left),0,FALSE,FALSE);
7617                 MOVA(l);
7618                 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7619                 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7620                 pic14_emitcode("mov","c,ov");
7621                 pic14_emitcode("rrc","a");
7622                 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7623                 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7624                 aopPut(AOP(result),"a",0);
7625                 goto release ;
7626         }
7627         
7628         reAdjustPreg(AOP(result));
7629         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7630         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7631         pic14_emitcode("mov","c,ov");
7632         while (size--) {
7633                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7634                 MOVA(l);
7635                 pic14_emitcode("rrc","a");         
7636                 aopPut(AOP(result),"a",offset--);
7637         }
7638         reAdjustPreg(AOP(result));
7639         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7640         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7641         
7642 release:
7643 #endif
7644         
7645         freeAsmop(left,NULL,ic,TRUE);
7646         freeAsmop(result,NULL,ic,TRUE);
7647         freeAsmop(right,NULL,ic,TRUE);
7648 }
7649
7650 /*-----------------------------------------------------------------*/
7651 /* genRightShift - generate code for right shifting                */
7652 /*-----------------------------------------------------------------*/
7653 static void genRightShift (iCode *ic)
7654 {
7655         operand *right, *left, *result;
7656         sym_link *retype ;
7657         int size, offset;
7658         char *l;
7659         symbol *tlbl, *tlbl1 ;
7660         
7661         /* if signed then we do it the hard way preserve the
7662         sign bit moving it inwards */
7663         retype = getSpec(operandType(IC_RESULT(ic)));
7664         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7665         
7666         if (!SPEC_USIGN(retype)) {
7667                 genSignedRightShift (ic);
7668                 return ;
7669         }
7670         
7671         /* signed & unsigned types are treated the same : i.e. the
7672         signed is NOT propagated inwards : quoting from the
7673         ANSI - standard : "for E1 >> E2, is equivalent to division
7674         by 2**E2 if unsigned or if it has a non-negative value,
7675         otherwise the result is implementation defined ", MY definition
7676         is that the sign does not get propagated */
7677         
7678         right = IC_RIGHT(ic);
7679         left  = IC_LEFT(ic);
7680         result = IC_RESULT(ic);
7681         
7682         aopOp(right,ic,FALSE);
7683         
7684         /* if the shift count is known then do it 
7685         as efficiently as possible */
7686         if (AOP_TYPE(right) == AOP_LIT) {
7687                 genRightShiftLiteral (left,right,result,ic, 0);
7688                 return ;
7689         }
7690         
7691         /* shift count is unknown then we have to form 
7692         a loop get the loop count in B : Note: we take
7693         only the lower order byte since shifting
7694         more that 32 bits make no sense anyway, ( the
7695         largest size of an object can be only 32 bits ) */  
7696         
7697         pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7698         pic14_emitcode("inc","b");
7699         aopOp(left,ic,FALSE);
7700         aopOp(result,ic,FALSE);
7701         
7702         /* now move the left to the result if they are not the
7703         same */
7704         if (!pic14_sameRegs(AOP(left),AOP(result)) && 
7705                 AOP_SIZE(result) > 1) {
7706                 
7707                 size = AOP_SIZE(result);
7708                 offset=0;
7709                 while (size--) {
7710                         l = aopGet(AOP(left),offset,FALSE,TRUE);
7711                         if (*l == '@' && IS_AOP_PREG(result)) {
7712                                 
7713                                 pic14_emitcode("mov","a,%s",l);
7714                                 aopPut(AOP(result),"a",offset);
7715                         } else
7716                                 aopPut(AOP(result),l,offset);
7717                         offset++;
7718                 }
7719         }
7720         
7721         tlbl = newiTempLabel(NULL);
7722         tlbl1= newiTempLabel(NULL);
7723         size = AOP_SIZE(result);
7724         offset = size - 1;
7725         
7726         /* if it is only one byte then */
7727         if (size == 1) {
7728                 
7729                 tlbl = newiTempLabel(NULL);
7730                 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7731                         emitpcode(POC_MOVFW,  popGet(AOP(left),0));
7732                         emitpcode(POC_MOVWF,  popGet(AOP(result),0));
7733                 }
7734                 
7735                 emitpcode(POC_COMFW,  popGet(AOP(right),0));
7736                 emitpcode(POC_RLF,    popGet(AOP(result),0));
7737                 emitpLabel(tlbl->key);
7738                 emitpcode(POC_RRF,    popGet(AOP(result),0));
7739                 emitpcode(POC_ADDLW,  popGetLit(1));
7740                 emitSKPC;
7741                 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7742                 
7743                 goto release ;
7744         }
7745         
7746         reAdjustPreg(AOP(result));
7747         pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7748         pic14_emitcode("","%05d_DS_:",tlbl->key+100);    
7749         CLRC;
7750         while (size--) {
7751                 l = aopGet(AOP(result),offset,FALSE,FALSE);
7752                 MOVA(l);
7753                 pic14_emitcode("rrc","a");         
7754                 aopPut(AOP(result),"a",offset--);
7755         }
7756         reAdjustPreg(AOP(result));
7757         
7758         pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7759         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7760         
7761 release:
7762         freeAsmop(left,NULL,ic,TRUE);
7763         freeAsmop (right,NULL,ic,TRUE);
7764         freeAsmop(result,NULL,ic,TRUE);
7765 }
7766
7767 /*-----------------------------------------------------------------*/
7768 /* genUnpackBits - generates code for unpacking bits               */
7769 /*-----------------------------------------------------------------*/
7770 static void genUnpackBits (operand *result, char *rname, int ptype)
7771 {    
7772         int shCnt ;
7773         int rlen = 0 ;
7774         sym_link *etype;
7775         int offset = 0 ;
7776         
7777         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7778         etype = getSpec(operandType(result));
7779         
7780         /* read the first byte  */
7781         switch (ptype) {
7782                 
7783         case POINTER:
7784         case IPOINTER:
7785                 pic14_emitcode("mov","a,@%s",rname);
7786                 break;
7787                 
7788         case PPOINTER:
7789                 pic14_emitcode("movx","a,@%s",rname);
7790                 break;
7791                 
7792         case FPOINTER:
7793                 pic14_emitcode("movx","a,@dptr");
7794                 break;
7795                 
7796         case CPOINTER:
7797                 pic14_emitcode("clr","a");
7798                 pic14_emitcode("movc","a","@a+dptr");
7799                 break;
7800                 
7801         case GPOINTER:
7802                 pic14_emitcode("lcall","__gptrget");
7803                 break;
7804         }
7805         
7806         /* if we have bitdisplacement then it fits   */
7807         /* into this byte completely or if length is */
7808         /* less than a byte                          */
7809         if ((shCnt = SPEC_BSTR(etype)) || 
7810                 (SPEC_BLEN(etype) <= 8))  {
7811                 
7812                 /* shift right acc */
7813                 AccRsh(shCnt);
7814                 
7815                 pic14_emitcode("anl","a,#0x%02x",
7816                         ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7817                 aopPut(AOP(result),"a",offset);
7818                 return ;
7819         }
7820         
7821         /* bit field did not fit in a byte  */
7822         rlen = SPEC_BLEN(etype) - 8;
7823         aopPut(AOP(result),"a",offset++);
7824         
7825         while (1)  {
7826                 
7827                 switch (ptype) {
7828                 case POINTER:
7829                 case IPOINTER:
7830                         pic14_emitcode("inc","%s",rname);
7831                         pic14_emitcode("mov","a,@%s",rname);
7832                         break;
7833                         
7834                 case PPOINTER:
7835                         pic14_emitcode("inc","%s",rname);
7836                         pic14_emitcode("movx","a,@%s",rname);
7837                         break;
7838                         
7839                 case FPOINTER:
7840                         pic14_emitcode("inc","dptr");
7841                         pic14_emitcode("movx","a,@dptr");
7842                         break;
7843                         
7844                 case CPOINTER:
7845                         pic14_emitcode("clr","a");
7846                         pic14_emitcode("inc","dptr");
7847                         pic14_emitcode("movc","a","@a+dptr");
7848                         break;
7849                         
7850                 case GPOINTER:
7851                         pic14_emitcode("inc","dptr");
7852                         pic14_emitcode("lcall","__gptrget");
7853                         break;
7854                 }
7855                 
7856                 rlen -= 8;            
7857                 /* if we are done */
7858                 if ( rlen <= 0 )
7859                         break ;
7860                 
7861                 aopPut(AOP(result),"a",offset++);
7862                 
7863         }
7864         
7865         if (rlen) {
7866                 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7867                 aopPut(AOP(result),"a",offset);        
7868         }
7869         
7870         return ;
7871 }
7872
7873 #if 0
7874 /*-----------------------------------------------------------------*/
7875 /* genDataPointerGet - generates code when ptr offset is known     */
7876 /*-----------------------------------------------------------------*/
7877 static void genDataPointerGet (operand *left, 
7878                                                            operand *result, 
7879                                                            iCode *ic)
7880 {
7881         int size , offset = 0;
7882         
7883         
7884         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7885         
7886         
7887         /* optimization - most of the time, left and result are the same
7888         * address, but different types. for the pic code, we could omit
7889         * the following
7890         */
7891         
7892         aopOp(result,ic,TRUE);
7893         
7894         DEBUGpic14_AopType(__LINE__,left,NULL,result);
7895         
7896         emitpcode(POC_MOVFW, popGet(AOP(left),0));
7897         
7898         size = AOP_SIZE(result);
7899         
7900         while (size--) {
7901                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7902                 offset++;
7903         }
7904         
7905         freeAsmop(left,NULL,ic,TRUE);
7906         freeAsmop(result,NULL,ic,TRUE);
7907 }
7908 #endif
7909 /*-----------------------------------------------------------------*/
7910 /* genNearPointerGet - pic14_emitcode for near pointer fetch             */
7911 /*-----------------------------------------------------------------*/
7912 static void genNearPointerGet (operand *left, 
7913                                                            operand *result, 
7914                                                            iCode *ic)
7915 {
7916         asmop *aop = NULL;
7917         //regs *preg = NULL ;
7918         char *rname ;
7919         sym_link *rtype, *retype;
7920         sym_link *ltype = operandType(left);    
7921         //char buffer[80];
7922         
7923         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7924         
7925         rtype = operandType(result);
7926         retype= getSpec(rtype);
7927         
7928         aopOp(left,ic,FALSE);
7929         
7930         /* if left is rematerialisable and
7931         result is not bit variable type and
7932         the left is pointer to data space i.e
7933         lower 128 bytes of space */
7934         if (AOP_TYPE(left) == AOP_PCODE &&  //AOP_TYPE(left) == AOP_IMMD &&
7935                 !IS_BITVAR(retype)         &&
7936                 DCL_TYPE(ltype) == POINTER) {
7937                 //genDataPointerGet (left,result,ic);
7938                 return ;
7939         }
7940         
7941         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7942         
7943         /* if the value is already in a pointer register
7944         then don't need anything more */
7945         if (!AOP_INPREG(AOP(left))) {
7946                 /* otherwise get a free pointer register */
7947                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7948                 /*
7949                 aop = newAsmop(0);
7950                 preg = getFreePtr(ic,&aop,FALSE);
7951                 pic14_emitcode("mov","%s,%s",
7952                 preg->name,
7953                 aopGet(AOP(left),0,FALSE,TRUE));
7954                 rname = preg->name ;
7955                 */
7956                 rname ="BAD";
7957         } else
7958                 rname = aopGet(AOP(left),0,FALSE,FALSE);
7959         
7960         aopOp (result,ic,FALSE);
7961         
7962         /* if bitfield then unpack the bits */
7963         if (IS_BITFIELD(retype)) 
7964                 genUnpackBits (result,rname,POINTER);
7965         else {
7966                 /* we have can just get the values */
7967                 int size = AOP_SIZE(result);
7968                 int offset = 0 ;  
7969                 
7970                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
7971                 
7972                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7973                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7974                 while(size--) {
7975                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7976                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7977                         if(size)
7978                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7979                 }
7980                 /*
7981                 while (size--) {
7982                 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7983                 
7984                   pic14_emitcode("mov","a,@%s",rname);
7985                   aopPut(AOP(result),"a",offset);
7986                   } else {
7987                   sprintf(buffer,"@%s",rname);
7988                   aopPut(AOP(result),buffer,offset);
7989                   }
7990                   offset++ ;
7991                   if (size)
7992                   pic14_emitcode("inc","%s",rname);
7993                   }
7994                 */
7995         }
7996         
7997         /* now some housekeeping stuff */
7998         if (aop) {
7999                 /* we had to allocate for this iCode */
8000                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8001                 freeAsmop(NULL,aop,ic,TRUE);
8002         } else { 
8003         /* we did not allocate which means left
8004         already in a pointer register, then
8005         if size > 0 && this could be used again
8006         we have to point it back to where it 
8007                 belongs */
8008                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8009                 if (AOP_SIZE(result) > 1 &&
8010                         !OP_SYMBOL(left)->remat &&
8011                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8012                         ic->depth )) {
8013                         int size = AOP_SIZE(result) - 1;
8014                         while (size--)
8015                                 pic14_emitcode("dec","%s",rname);
8016                 }
8017         }
8018         
8019         /* done */
8020         freeAsmop(left,NULL,ic,TRUE);
8021         freeAsmop(result,NULL,ic,TRUE);
8022         
8023 }
8024
8025 /*-----------------------------------------------------------------*/
8026 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch           */
8027 /*-----------------------------------------------------------------*/
8028 static void genPagedPointerGet (operand *left, 
8029                                                                 operand *result, 
8030                                                                 iCode *ic)
8031 {
8032         asmop *aop = NULL;
8033         regs *preg = NULL ;
8034         char *rname ;
8035         sym_link *rtype, *retype;    
8036         
8037         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8038         
8039         rtype = operandType(result);
8040         retype= getSpec(rtype);
8041         
8042         aopOp(left,ic,FALSE);
8043         
8044         /* if the value is already in a pointer register
8045         then don't need anything more */
8046         if (!AOP_INPREG(AOP(left))) {
8047                 /* otherwise get a free pointer register */
8048                 aop = newAsmop(0);
8049                 preg = getFreePtr(ic,&aop,FALSE);
8050                 pic14_emitcode("mov","%s,%s",
8051                         preg->name,
8052                         aopGet(AOP(left),0,FALSE,TRUE));
8053                 rname = preg->name ;
8054         } else
8055                 rname = aopGet(AOP(left),0,FALSE,FALSE);
8056         
8057         freeAsmop(left,NULL,ic,TRUE);
8058         aopOp (result,ic,FALSE);
8059         
8060         /* if bitfield then unpack the bits */
8061         if (IS_BITFIELD(retype)) 
8062                 genUnpackBits (result,rname,PPOINTER);
8063         else {
8064                 /* we have can just get the values */
8065                 int size = AOP_SIZE(result);
8066                 int offset = 0 ;  
8067                 
8068                 while (size--) {
8069                         
8070                         pic14_emitcode("movx","a,@%s",rname);
8071                         aopPut(AOP(result),"a",offset);
8072                         
8073                         offset++ ;
8074                         
8075                         if (size)
8076                                 pic14_emitcode("inc","%s",rname);
8077                 }
8078         }
8079         
8080         /* now some housekeeping stuff */
8081         if (aop) {
8082                 /* we had to allocate for this iCode */
8083                 freeAsmop(NULL,aop,ic,TRUE);
8084         } else { 
8085         /* we did not allocate which means left
8086         already in a pointer register, then
8087         if size > 0 && this could be used again
8088         we have to point it back to where it 
8089                 belongs */
8090                 if (AOP_SIZE(result) > 1 &&
8091                         !OP_SYMBOL(left)->remat &&
8092                         ( OP_SYMBOL(left)->liveTo > ic->seq ||
8093                         ic->depth )) {
8094                         int size = AOP_SIZE(result) - 1;
8095                         while (size--)
8096                                 pic14_emitcode("dec","%s",rname);
8097                 }
8098         }
8099         
8100         /* done */
8101         freeAsmop(result,NULL,ic,TRUE);
8102         
8103         
8104 }
8105
8106 /*-----------------------------------------------------------------*/
8107 /* genFarPointerGet - gget value from far space                    */
8108 /*-----------------------------------------------------------------*/
8109 static void genFarPointerGet (operand *left,
8110                                                           operand *result, iCode *ic)
8111 {
8112         int size, offset ;
8113         sym_link *retype = getSpec(operandType(result));
8114         
8115         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8116         
8117         aopOp(left,ic,FALSE);
8118         
8119         /* if the operand is already in dptr 
8120         then we do nothing else we move the value to dptr */
8121         if (AOP_TYPE(left) != AOP_STR) {
8122                 /* if this is remateriazable */
8123                 if (AOP_TYPE(left) == AOP_IMMD)
8124                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8125                 else { /* we need to get it byte by byte */
8126                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8127                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8128                         if (options.model == MODEL_FLAT24)
8129                         {
8130                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8131                         }
8132                 }
8133         }
8134         /* so dptr know contains the address */
8135         freeAsmop(left,NULL,ic,TRUE);
8136         aopOp(result,ic,FALSE);
8137         
8138         /* if bit then unpack */
8139         if (IS_BITFIELD(retype)) 
8140                 genUnpackBits(result,"dptr",FPOINTER);
8141         else {
8142                 size = AOP_SIZE(result);
8143                 offset = 0 ;
8144                 
8145                 while (size--) {
8146                         pic14_emitcode("movx","a,@dptr");
8147                         aopPut(AOP(result),"a",offset++);
8148                         if (size)
8149                                 pic14_emitcode("inc","dptr");
8150                 }
8151         }
8152         
8153         freeAsmop(result,NULL,ic,TRUE);
8154 }
8155 #if 0
8156 /*-----------------------------------------------------------------*/
8157 /* genCodePointerGet - get value from code space                  */
8158 /*-----------------------------------------------------------------*/
8159 static void genCodePointerGet (operand *left,
8160                                                            operand *result, iCode *ic)
8161 {
8162         int size, offset ;
8163         sym_link *retype = getSpec(operandType(result));
8164         
8165         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8166         
8167         aopOp(left,ic,FALSE);
8168         
8169         /* if the operand is already in dptr 
8170         then we do nothing else we move the value to dptr */
8171         if (AOP_TYPE(left) != AOP_STR) {
8172                 /* if this is remateriazable */
8173                 if (AOP_TYPE(left) == AOP_IMMD)
8174                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8175                 else { /* we need to get it byte by byte */
8176                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8177                         pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8178                         if (options.model == MODEL_FLAT24)
8179                         {
8180                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8181                         }
8182                 }
8183         }
8184         /* so dptr know contains the address */
8185         freeAsmop(left,NULL,ic,TRUE);
8186         aopOp(result,ic,FALSE);
8187         
8188         /* if bit then unpack */
8189         if (IS_BITFIELD(retype)) 
8190                 genUnpackBits(result,"dptr",CPOINTER);
8191         else {
8192                 size = AOP_SIZE(result);
8193                 offset = 0 ;
8194                 
8195                 while (size--) {
8196                         pic14_emitcode("clr","a");
8197                         pic14_emitcode("movc","a,@a+dptr");
8198                         aopPut(AOP(result),"a",offset++);
8199                         if (size)
8200                                 pic14_emitcode("inc","dptr");
8201                 }
8202         }
8203         
8204         freeAsmop(result,NULL,ic,TRUE);
8205 }
8206 #endif
8207 /*-----------------------------------------------------------------*/
8208 /* genGenPointerGet - gget value from generic pointer space        */
8209 /*-----------------------------------------------------------------*/
8210 static void genGenPointerGet (operand *left,
8211                                                           operand *result, iCode *ic)
8212 {
8213         int size, offset ;
8214         sym_link *retype = getSpec(operandType(result));
8215         
8216         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8217         aopOp(left,ic,FALSE);
8218         aopOp(result,ic,FALSE);
8219         
8220         
8221         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8222         
8223         /* if the operand is already in dptr 
8224         then we do nothing else we move the value to dptr */
8225         //  if (AOP_TYPE(left) != AOP_STR) {
8226         /* if this is remateriazable */
8227         if (AOP_TYPE(left) == AOP_IMMD) {
8228                 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8229                 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8230         }
8231         else { /* we need to get it byte by byte */
8232                 
8233                 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8234                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8235                 
8236                 size = AOP_SIZE(result);
8237                 offset = 0 ;
8238                 
8239                 while(size--) {
8240                         emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8241                         emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8242                         if(size)
8243                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8244                 }
8245                 goto release;
8246         }
8247         //}
8248         /* so dptr know contains the address */
8249         
8250         /* if bit then unpack */
8251         //if (IS_BITFIELD(retype)) 
8252         //  genUnpackBits(result,"dptr",GPOINTER);
8253         
8254 release:
8255         freeAsmop(left,NULL,ic,TRUE);
8256         freeAsmop(result,NULL,ic,TRUE);
8257         
8258 }
8259
8260 /*-----------------------------------------------------------------*/
8261 /* genConstPointerGet - get value from const generic pointer space */
8262 /*-----------------------------------------------------------------*/
8263 static void genConstPointerGet (operand *left,
8264                                                                 operand *result, iCode *ic)
8265 {
8266         //sym_link *retype = getSpec(operandType(result));
8267         symbol *albl = newiTempLabel(NULL);
8268         symbol *blbl = newiTempLabel(NULL);
8269         PIC_OPCODE poc;
8270         pCodeOp *pcop;
8271         
8272         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8273         aopOp(left,ic,FALSE);
8274         aopOp(result,ic,FALSE);
8275         
8276         
8277         DEBUGpic14_AopType(__LINE__,left,NULL,result);
8278         
8279         DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8280         
8281         emitpcode(POC_CALL,popGetLabel(albl->key));
8282         pcop = popGetLabel(blbl->key);
8283         emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8284         emitpcode(POC_GOTO,pcop);
8285         emitpLabel(albl->key);
8286         
8287         poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8288         
8289         emitpcode(poc,popGet(AOP(left),1));
8290         emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8291         emitpcode(poc,popGet(AOP(left),0));
8292         emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8293         
8294         emitpLabel(blbl->key);
8295         
8296         emitpcode(POC_MOVWF,popGet(AOP(result),0));
8297         
8298         
8299         freeAsmop(left,NULL,ic,TRUE);
8300         freeAsmop(result,NULL,ic,TRUE);
8301         
8302 }
8303 /*-----------------------------------------------------------------*/
8304 /* genPointerGet - generate code for pointer get                   */
8305 /*-----------------------------------------------------------------*/
8306 static void genPointerGet (iCode *ic)
8307 {
8308         operand *left, *result ;
8309         sym_link *type, *etype;
8310         int p_type;
8311         
8312         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8313         
8314         left = IC_LEFT(ic);
8315         result = IC_RESULT(ic) ;
8316         
8317         /* depending on the type of pointer we need to
8318         move it to the correct pointer register */
8319         type = operandType(left);
8320         etype = getSpec(type);
8321         
8322         if (IS_PTR_CONST(type))
8323                 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8324         
8325         /* if left is of type of pointer then it is simple */
8326         if (IS_PTR(type) && !IS_FUNC(type->next)) 
8327                 p_type = DCL_TYPE(type);
8328         else {
8329                 /* we have to go by the storage class */
8330                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8331                 
8332                 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8333                 
8334                 if (SPEC_OCLS(etype)->codesp ) {
8335                         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8336                         //p_type = CPOINTER ; 
8337                 }
8338                 else
8339                         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8340                                 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8341                         /*p_type = FPOINTER ;*/ 
8342                         else
8343                                 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8344                                         DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8345                                 /*        p_type = PPOINTER; */
8346                                 else
8347                                         if (SPEC_OCLS(etype) == idata )
8348                                                 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8349                                         /*      p_type = IPOINTER; */
8350                                         else
8351                                                 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8352                                         /*      p_type = POINTER ; */
8353         }
8354         
8355         /* now that we have the pointer type we assign
8356         the pointer values */
8357         switch (p_type) {
8358                 
8359         case POINTER: 
8360         case IPOINTER:
8361                 genNearPointerGet (left,result,ic);
8362                 break;
8363                 
8364         case PPOINTER:
8365                 genPagedPointerGet(left,result,ic);
8366                 break;
8367                 
8368         case FPOINTER:
8369                 genFarPointerGet (left,result,ic);
8370                 break;
8371                 
8372         case CPOINTER:
8373                 genConstPointerGet (left,result,ic);
8374                 //pic14_emitcodePointerGet (left,result,ic);
8375                 break;
8376                 
8377         case GPOINTER:
8378                 if (IS_PTR_CONST(type))
8379                         genConstPointerGet (left,result,ic);
8380                 else
8381                         genGenPointerGet (left,result,ic);
8382                 break;
8383         }
8384         
8385 }
8386
8387 /*-----------------------------------------------------------------*/
8388 /* genPackBits - generates code for packed bit storage             */
8389 /*-----------------------------------------------------------------*/
8390 static void genPackBits (sym_link    *etype ,
8391                                                  operand *right ,
8392                                                  char *rname, int p_type)
8393 {
8394         int shCount = 0 ;
8395         int offset = 0  ;
8396         int rLen = 0 ;
8397         int blen, bstr ;   
8398         char *l ;
8399         
8400         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8401         blen = SPEC_BLEN(etype);
8402         bstr = SPEC_BSTR(etype);
8403         
8404         l = aopGet(AOP(right),offset++,FALSE,FALSE);
8405         MOVA(l);   
8406         
8407         /* if the bit lenth is less than or    */
8408         /* it exactly fits a byte then         */
8409         if (SPEC_BLEN(etype) <= 8 )  {
8410                 shCount = SPEC_BSTR(etype) ;
8411                 
8412                 /* shift left acc */
8413                 AccLsh(shCount);
8414                 
8415                 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8416                         
8417                         
8418                         switch (p_type) {
8419                         case POINTER:
8420                                 pic14_emitcode ("mov","b,a");
8421                                 pic14_emitcode("mov","a,@%s",rname);
8422                                 break;
8423                                 
8424                         case FPOINTER:
8425                                 pic14_emitcode ("mov","b,a");
8426                                 pic14_emitcode("movx","a,@dptr");
8427                                 break;
8428                                 
8429                         case GPOINTER:
8430                                 pic14_emitcode ("push","b");
8431                                 pic14_emitcode ("push","acc");
8432                                 pic14_emitcode ("lcall","__gptrget");
8433                                 pic14_emitcode ("pop","b");
8434                                 break;
8435                         }
8436                         
8437                         pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8438                                 ((unsigned char)(0xFF << (blen+bstr)) | 
8439                                 (unsigned char)(0xFF >> (8-bstr)) ) );
8440                         pic14_emitcode ("orl","a,b");
8441                         if (p_type == GPOINTER)
8442                                 pic14_emitcode("pop","b");
8443                 }
8444         }
8445         
8446         switch (p_type) {
8447         case POINTER:
8448                 pic14_emitcode("mov","@%s,a",rname);
8449                 break;
8450                 
8451         case FPOINTER:
8452                 pic14_emitcode("movx","@dptr,a");
8453                 break;
8454                 
8455         case GPOINTER:
8456                 DEBUGpic14_emitcode(";lcall","__gptrput");
8457                 break;
8458         }
8459         
8460         /* if we r done */
8461         if ( SPEC_BLEN(etype) <= 8 )
8462                 return ;
8463         
8464         pic14_emitcode("inc","%s",rname);
8465         rLen = SPEC_BLEN(etype) ;     
8466         
8467         /* now generate for lengths greater than one byte */
8468         while (1) {
8469                 
8470                 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8471                 
8472                 rLen -= 8 ;
8473                 if (rLen <= 0 )
8474                         break ;
8475                 
8476                 switch (p_type) {
8477                 case POINTER:
8478                         if (*l == '@') {
8479                                 MOVA(l);
8480                                 pic14_emitcode("mov","@%s,a",rname);
8481                         } else
8482                                 pic14_emitcode("mov","@%s,%s",rname,l);
8483                         break;
8484                         
8485                 case FPOINTER:
8486                         MOVA(l);
8487                         pic14_emitcode("movx","@dptr,a");
8488                         break;
8489                         
8490                 case GPOINTER:
8491                         MOVA(l);
8492                         DEBUGpic14_emitcode(";lcall","__gptrput");
8493                         break;  
8494                 }   
8495                 pic14_emitcode ("inc","%s",rname);
8496         }
8497         
8498         MOVA(l);
8499         
8500         /* last last was not complete */
8501         if (rLen)   {
8502                 /* save the byte & read byte */
8503                 switch (p_type) {
8504                 case POINTER:
8505                         pic14_emitcode ("mov","b,a");
8506                         pic14_emitcode("mov","a,@%s",rname);
8507                         break;
8508                         
8509                 case FPOINTER:
8510                         pic14_emitcode ("mov","b,a");
8511                         pic14_emitcode("movx","a,@dptr");
8512                         break;
8513                         
8514                 case GPOINTER:
8515                         pic14_emitcode ("push","b");
8516                         pic14_emitcode ("push","acc");
8517                         pic14_emitcode ("lcall","__gptrget");
8518                         pic14_emitcode ("pop","b");
8519                         break;
8520                 }
8521                 
8522                 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8523                 pic14_emitcode ("orl","a,b");
8524         }
8525         
8526         if (p_type == GPOINTER)
8527                 pic14_emitcode("pop","b");
8528         
8529         switch (p_type) {
8530                 
8531         case POINTER:
8532                 pic14_emitcode("mov","@%s,a",rname);
8533                 break;
8534                 
8535         case FPOINTER:
8536                 pic14_emitcode("movx","@dptr,a");
8537                 break;
8538                 
8539         case GPOINTER:
8540                 DEBUGpic14_emitcode(";lcall","__gptrput");
8541                 break;      
8542         }
8543 }
8544 /*-----------------------------------------------------------------*/
8545 /* genDataPointerSet - remat pointer to data space                 */
8546 /*-----------------------------------------------------------------*/
8547 static void genDataPointerSet(operand *right,
8548                                                           operand *result,
8549                                                           iCode *ic)
8550 {
8551         int size, offset = 0 ;
8552         char *l, buffer[256];
8553         
8554         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8555         aopOp(right,ic,FALSE);
8556         
8557         l = aopGet(AOP(result),0,FALSE,TRUE);
8558         size = AOP_SIZE(right);
8559         /*
8560         if ( AOP_TYPE(result) == AOP_PCODE) {
8561         fprintf(stderr,"genDataPointerSet   %s, %d\n",
8562         AOP(result)->aopu.pcop->name,
8563         PCOI(AOP(result)->aopu.pcop)->offset);
8564         }
8565         */
8566         
8567         // tsd, was l+1 - the underline `_' prefix was being stripped
8568         while (size--) {
8569                 if (offset) {
8570                         sprintf(buffer,"(%s + %d)",l,offset);
8571                         fprintf(stderr,"oops  %s\n",buffer);
8572                 } else
8573                         sprintf(buffer,"%s",l);
8574                 
8575                 if (AOP_TYPE(right) == AOP_LIT) {
8576                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8577                         lit = lit >> (8*offset);
8578                         if(lit&0xff) {
8579                                 pic14_emitcode("movlw","%d",lit);
8580                                 pic14_emitcode("movwf","%s",buffer);
8581                                 
8582                                 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8583                                 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8584                                 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8585                                 
8586                         } else {
8587                                 pic14_emitcode("clrf","%s",buffer);
8588                                 //emitpcode(POC_CLRF, popRegFromString(buffer));
8589                                 emitpcode(POC_CLRF, popGet(AOP(result),0));
8590                         }
8591                 }else {
8592                         pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8593                         pic14_emitcode("movwf","%s",buffer);
8594                         
8595                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8596                         //emitpcode(POC_MOVWF, popRegFromString(buffer));
8597                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
8598                         
8599                 }
8600                 
8601                 offset++;
8602         }
8603         
8604         freeAsmop(right,NULL,ic,TRUE);
8605         freeAsmop(result,NULL,ic,TRUE);
8606 }
8607
8608 /*-----------------------------------------------------------------*/
8609 /* genNearPointerSet - pic14_emitcode for near pointer put                */
8610 /*-----------------------------------------------------------------*/
8611 static void genNearPointerSet (operand *right,
8612                                                            operand *result, 
8613                                                            iCode *ic)
8614 {
8615         asmop *aop = NULL;
8616         char *l;
8617         sym_link *retype;
8618         sym_link *ptype = operandType(result);
8619         
8620         
8621         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8622         retype= getSpec(operandType(right));
8623         
8624         aopOp(result,ic,FALSE);
8625         
8626         
8627         /* if the result is rematerializable &
8628         in data space & not a bit variable */
8629         //if (AOP_TYPE(result) == AOP_IMMD &&
8630         if (AOP_TYPE(result) == AOP_PCODE &&  //AOP_TYPE(result) == AOP_IMMD &&
8631                 DCL_TYPE(ptype) == POINTER   &&
8632                 !IS_BITFIELD(retype)) {
8633                 genDataPointerSet (right,result,ic);
8634                 freeAsmop(result,NULL,ic,TRUE);
8635                 return;
8636         }
8637         
8638         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8639         aopOp(right,ic,FALSE);
8640         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8641         
8642         /* if the value is already in a pointer register
8643         then don't need anything more */
8644         if (!AOP_INPREG(AOP(result))) {
8645                 /* otherwise get a free pointer register */
8646                 //aop = newAsmop(0);
8647                 //preg = getFreePtr(ic,&aop,FALSE);
8648                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8649                 //pic14_emitcode("mov","%s,%s",
8650                 //         preg->name,
8651                 //         aopGet(AOP(result),0,FALSE,TRUE));
8652                 //rname = preg->name ;
8653                 //pic14_emitcode("movwf","fsr");
8654                 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8655                 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8656                 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8657                 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8658                 goto release;
8659                 
8660         }// else
8661         //   rname = aopGet(AOP(result),0,FALSE,FALSE);
8662         
8663         
8664         /* if bitfield then unpack the bits */
8665         if (IS_BITFIELD(retype)) {
8666                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8667                         "The programmer is obviously confused");
8668                 //genPackBits (retype,right,rname,POINTER);
8669                 exit(1);
8670         }
8671         else {
8672                 /* we have can just get the values */
8673                 int size = AOP_SIZE(right);
8674                 int offset = 0 ;    
8675                 
8676                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8677                 while (size--) {
8678                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8679                         if (*l == '@' ) {
8680                                 //MOVA(l);
8681                                 //pic14_emitcode("mov","@%s,a",rname);
8682                                 pic14_emitcode("movf","indf,w ;1");
8683                         } else {
8684                                 
8685                                 if (AOP_TYPE(right) == AOP_LIT) {
8686                                         unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8687                                         if(lit) {
8688                                                 pic14_emitcode("movlw","%s",l);
8689                                                 pic14_emitcode("movwf","indf ;2");
8690                                         } else 
8691                                                 pic14_emitcode("clrf","indf");
8692                                 }else {
8693                                         pic14_emitcode("movf","%s,w",l);
8694                                         pic14_emitcode("movwf","indf ;2");
8695                                 }
8696                                 //pic14_emitcode("mov","@%s,%s",rname,l);
8697                         }
8698                         if (size)
8699                                 pic14_emitcode("incf","fsr,f ;3");
8700                         //pic14_emitcode("inc","%s",rname);
8701                         offset++;
8702                 }
8703         }
8704         
8705         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8706         /* now some housekeeping stuff */
8707         if (aop) {
8708                 /* we had to allocate for this iCode */
8709                 freeAsmop(NULL,aop,ic,TRUE);
8710         } else { 
8711         /* we did not allocate which means left
8712         already in a pointer register, then
8713         if size > 0 && this could be used again
8714         we have to point it back to where it 
8715                 belongs */
8716                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8717                 if (AOP_SIZE(right) > 1 &&
8718                         !OP_SYMBOL(result)->remat &&
8719                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8720                         ic->depth )) {
8721                         int size = AOP_SIZE(right) - 1;
8722                         while (size--)
8723                                 pic14_emitcode("decf","fsr,f");
8724                         //pic14_emitcode("dec","%s",rname);
8725                 }
8726         }
8727         
8728         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8729         /* done */
8730 release:
8731         freeAsmop(right,NULL,ic,TRUE);
8732         freeAsmop(result,NULL,ic,TRUE);
8733 }
8734
8735 /*-----------------------------------------------------------------*/
8736 /* genPagedPointerSet - pic14_emitcode for Paged pointer put             */
8737 /*-----------------------------------------------------------------*/
8738 static void genPagedPointerSet (operand *right,
8739                                                                 operand *result, 
8740                                                                 iCode *ic)
8741 {
8742         asmop *aop = NULL;
8743         regs *preg = NULL ;
8744         char *rname , *l;
8745         sym_link *retype;
8746         
8747         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8748         
8749         retype= getSpec(operandType(right));
8750         
8751         aopOp(result,ic,FALSE);
8752         
8753         /* if the value is already in a pointer register
8754         then don't need anything more */
8755         if (!AOP_INPREG(AOP(result))) {
8756                 /* otherwise get a free pointer register */
8757                 aop = newAsmop(0);
8758                 preg = getFreePtr(ic,&aop,FALSE);
8759                 pic14_emitcode("mov","%s,%s",
8760                         preg->name,
8761                         aopGet(AOP(result),0,FALSE,TRUE));
8762                 rname = preg->name ;
8763         } else
8764                 rname = aopGet(AOP(result),0,FALSE,FALSE);
8765         
8766         freeAsmop(result,NULL,ic,TRUE);
8767         aopOp (right,ic,FALSE);
8768         
8769         /* if bitfield then unpack the bits */
8770         if (IS_BITFIELD(retype)) 
8771                 genPackBits (retype,right,rname,PPOINTER);
8772         else {
8773                 /* we have can just get the values */
8774                 int size = AOP_SIZE(right);
8775                 int offset = 0 ;  
8776                 
8777                 while (size--) {
8778                         l = aopGet(AOP(right),offset,FALSE,TRUE);
8779                         
8780                         MOVA(l);
8781                         pic14_emitcode("movx","@%s,a",rname);
8782                         
8783                         if (size)
8784                                 pic14_emitcode("inc","%s",rname);
8785                         
8786                         offset++;
8787                 }
8788         }
8789         
8790         /* now some housekeeping stuff */
8791         if (aop) {
8792                 /* we had to allocate for this iCode */
8793                 freeAsmop(NULL,aop,ic,TRUE);
8794         } else { 
8795         /* we did not allocate which means left
8796         already in a pointer register, then
8797         if size > 0 && this could be used again
8798         we have to point it back to where it 
8799                 belongs */
8800                 if (AOP_SIZE(right) > 1 &&
8801                         !OP_SYMBOL(result)->remat &&
8802                         ( OP_SYMBOL(result)->liveTo > ic->seq ||
8803                         ic->depth )) {
8804                         int size = AOP_SIZE(right) - 1;
8805                         while (size--)
8806                                 pic14_emitcode("dec","%s",rname);
8807                 }
8808         }
8809         
8810         /* done */
8811         freeAsmop(right,NULL,ic,TRUE);
8812         
8813         
8814 }
8815
8816 /*-----------------------------------------------------------------*/
8817 /* genFarPointerSet - set value from far space                     */
8818 /*-----------------------------------------------------------------*/
8819 static void genFarPointerSet (operand *right,
8820                                                           operand *result, iCode *ic)
8821 {
8822         int size, offset ;
8823         sym_link *retype = getSpec(operandType(right));
8824         
8825         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8826         aopOp(result,ic,FALSE);
8827         
8828         /* if the operand is already in dptr 
8829         then we do nothing else we move the value to dptr */
8830         if (AOP_TYPE(result) != AOP_STR) {
8831                 /* if this is remateriazable */
8832                 if (AOP_TYPE(result) == AOP_IMMD)
8833                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8834                 else { /* we need to get it byte by byte */
8835                         pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8836                         pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8837                         if (options.model == MODEL_FLAT24)
8838                         {
8839                                 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8840                         }
8841                 }
8842         }
8843         /* so dptr know contains the address */
8844         freeAsmop(result,NULL,ic,TRUE);
8845         aopOp(right,ic,FALSE);
8846         
8847         /* if bit then unpack */
8848         if (IS_BITFIELD(retype)) 
8849                 genPackBits(retype,right,"dptr",FPOINTER);
8850         else {
8851                 size = AOP_SIZE(right);
8852                 offset = 0 ;
8853                 
8854                 while (size--) {
8855                         char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8856                         MOVA(l);
8857                         pic14_emitcode("movx","@dptr,a");
8858                         if (size)
8859                                 pic14_emitcode("inc","dptr");
8860                 }
8861         }
8862         
8863         freeAsmop(right,NULL,ic,TRUE);
8864 }
8865
8866 /*-----------------------------------------------------------------*/
8867 /* genGenPointerSet - set value from generic pointer space         */
8868 /*-----------------------------------------------------------------*/
8869 static void genGenPointerSet (operand *right,
8870                                                           operand *result, iCode *ic)
8871 {
8872         int size, offset ;
8873         sym_link *retype = getSpec(operandType(right));
8874         
8875         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8876         
8877         aopOp(result,ic,FALSE);
8878         aopOp(right,ic,FALSE);
8879         size = AOP_SIZE(right);
8880         
8881         DEBUGpic14_AopType(__LINE__,NULL,right,result);
8882         
8883         /* if the operand is already in dptr 
8884         then we do nothing else we move the value to dptr */
8885         if (AOP_TYPE(result) != AOP_STR) {
8886                 /* if this is remateriazable */
8887                 if (AOP_TYPE(result) == AOP_IMMD) {
8888                         pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8889                         pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8890                 }
8891                 else { /* we need to get it byte by byte */
8892                         //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8893                         size = AOP_SIZE(right);
8894                         offset = 0 ;
8895                         
8896                         /* hack hack! see if this the FSR. If so don't load W */
8897                         if(AOP_TYPE(right) != AOP_ACC) {
8898                                 
8899                                 
8900                                 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8901                                 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8902                                 
8903                                 if(AOP_SIZE(result) > 1) {
8904                                         emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8905                                         emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8906                                         emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8907                                         
8908                                 }
8909                                 
8910                                 //if(size==2)
8911                                 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8912                                 //if(size==4) {
8913                                 //  emitpcode(POC_MOVLW,popGetLit(0xfd));
8914                                 //  emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8915                                 //}
8916                                 
8917                                 while(size--) {
8918                                         emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8919                                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8920                                         
8921                                         if(size)
8922                                                 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8923                                 }
8924                                 
8925                                 
8926                                 goto release;
8927                         } 
8928                         
8929                         if(aopIdx(AOP(result),0) != 4) {
8930                                 
8931                                 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8932                                 goto release;
8933                         }
8934                         
8935                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8936                         goto release;
8937                         
8938                 }
8939         }
8940         /* so dptr know contains the address */
8941         
8942         
8943         /* if bit then unpack */
8944         if (IS_BITFIELD(retype)) 
8945                 genPackBits(retype,right,"dptr",GPOINTER);
8946         else {
8947                 size = AOP_SIZE(right);
8948                 offset = 0 ;
8949                 
8950                 DEBUGpic14_emitcode ("; ***","%s  %d size=%d",__FUNCTION__,__LINE__,size);
8951                 
8952                 while (size--) {
8953                         
8954                         emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8955                         emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8956                         
8957                         if (AOP_TYPE(right) == AOP_LIT) 
8958                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8959                         else
8960                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8961                         
8962                         emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8963                         
8964                         offset++;
8965                 }
8966         }
8967         
8968 release:
8969         freeAsmop(right,NULL,ic,TRUE);
8970         freeAsmop(result,NULL,ic,TRUE);
8971 }
8972
8973 /*-----------------------------------------------------------------*/
8974 /* genPointerSet - stores the value into a pointer location        */
8975 /*-----------------------------------------------------------------*/
8976 static void genPointerSet (iCode *ic)
8977 {    
8978         operand *right, *result ;
8979         sym_link *type, *etype;
8980         int p_type;
8981         
8982         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
8983         
8984         right = IC_RIGHT(ic);
8985         result = IC_RESULT(ic) ;
8986         
8987         /* depending on the type of pointer we need to
8988         move it to the correct pointer register */
8989         type = operandType(result);
8990         etype = getSpec(type);
8991         /* if left is of type of pointer then it is simple */
8992         if (IS_PTR(type) && !IS_FUNC(type->next)) {
8993                 p_type = DCL_TYPE(type);
8994         }
8995         else {
8996                 /* we have to go by the storage class */
8997                 p_type = PTR_TYPE(SPEC_OCLS(etype));
8998                 
8999                 /*  if (SPEC_OCLS(etype)->codesp ) { */
9000                 /*      p_type = CPOINTER ;  */
9001                 /*  } */
9002                 /*  else */
9003                 /*      if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9004                 /*    p_type = FPOINTER ; */
9005                 /*      else */
9006                 /*    if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9007                 /*        p_type = PPOINTER ; */
9008                 /*    else */
9009                 /*        if (SPEC_OCLS(etype) == idata ) */
9010                 /*      p_type = IPOINTER ; */
9011                 /*        else */
9012                 /*      p_type = POINTER ; */
9013         }
9014         
9015         /* now that we have the pointer type we assign
9016         the pointer values */
9017         switch (p_type) {
9018                 
9019         case POINTER:
9020         case IPOINTER:
9021                 genNearPointerSet (right,result,ic);
9022                 break;
9023                 
9024         case PPOINTER:
9025                 genPagedPointerSet (right,result,ic);
9026                 break;
9027                 
9028         case FPOINTER:
9029                 genFarPointerSet (right,result,ic);
9030                 break;
9031                 
9032         case GPOINTER:
9033                 genGenPointerSet (right,result,ic);
9034                 break;
9035                 
9036         default:
9037                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
9038                         "genPointerSet: illegal pointer type");
9039         }
9040 }
9041
9042 /*-----------------------------------------------------------------*/
9043 /* genIfx - generate code for Ifx statement                        */
9044 /*-----------------------------------------------------------------*/
9045 static void genIfx (iCode *ic, iCode *popIc)
9046 {
9047         operand *cond = IC_COND(ic);
9048         int isbit =0;
9049         
9050         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9051         
9052         aopOp(cond,ic,FALSE);
9053         
9054         /* get the value into acc */
9055         if (AOP_TYPE(cond) != AOP_CRY)
9056                 pic14_toBoolean(cond);
9057         else
9058                 isbit = 1;
9059         /* the result is now in the accumulator */
9060         freeAsmop(cond,NULL,ic,TRUE);
9061         
9062         /* if there was something to be popped then do it */
9063         if (popIc)
9064                 genIpop(popIc);
9065         
9066         /* if the condition is  a bit variable */
9067         if (isbit && IS_ITEMP(cond) && 
9068                 SPIL_LOC(cond)) {
9069                 genIfxJump(ic,SPIL_LOC(cond)->rname);
9070                 DEBUGpic14_emitcode ("; isbit  SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9071         }
9072         else {
9073                 if (isbit && !IS_ITEMP(cond))
9074                         genIfxJump(ic,OP_SYMBOL(cond)->rname);
9075                 else
9076                         genIfxJump(ic,"a");
9077         }
9078         ic->generated = 1;
9079         
9080 }
9081
9082 /*-----------------------------------------------------------------*/
9083 /* genAddrOf - generates code for address of                       */
9084 /*-----------------------------------------------------------------*/
9085 static void genAddrOf (iCode *ic)
9086 {
9087         operand *right, *result, *left;
9088         int size, offset ;
9089         
9090         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9091         
9092         
9093         //aopOp(IC_RESULT(ic),ic,FALSE);
9094         
9095         aopOp((left=IC_LEFT(ic)),ic,FALSE);
9096         aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9097         aopOp((result=IC_RESULT(ic)),ic,TRUE);
9098         
9099         DEBUGpic14_AopType(__LINE__,left,right,result);
9100         
9101         size = AOP_SIZE(IC_RESULT(ic));
9102         offset = 0;
9103         
9104         while (size--) {
9105                 /* fixing bug #863624, reported from (errolv) */
9106                 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9107                 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9108                 
9109 #if 0
9110                 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9111                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9112 #endif
9113                 offset++;
9114         }
9115         
9116         freeAsmop(left,NULL,ic,FALSE);
9117         freeAsmop(result,NULL,ic,TRUE);
9118         
9119 }
9120
9121 #if 0
9122 /*-----------------------------------------------------------------*/
9123 /* genFarFarAssign - assignment when both are in far space         */
9124 /*-----------------------------------------------------------------*/
9125 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9126 {
9127         int size = AOP_SIZE(right);
9128         int offset = 0;
9129         char *l ;
9130         /* first push the right side on to the stack */
9131         while (size--) {
9132                 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9133                 MOVA(l);
9134                 pic14_emitcode ("push","acc");
9135         }
9136         
9137         freeAsmop(right,NULL,ic,FALSE);
9138         /* now assign DPTR to result */
9139         aopOp(result,ic,FALSE);
9140         size = AOP_SIZE(result);
9141         while (size--) {
9142                 pic14_emitcode ("pop","acc");
9143                 aopPut(AOP(result),"a",--offset);
9144         }
9145         freeAsmop(result,NULL,ic,FALSE);
9146         
9147 }
9148 #endif
9149
9150 /*-----------------------------------------------------------------*/
9151 /* genAssign - generate code for assignment                        */
9152 /*-----------------------------------------------------------------*/
9153 static void genAssign (iCode *ic)
9154 {
9155         operand *result, *right;
9156         int size, offset,know_W;
9157         unsigned long lit = 0L;
9158         
9159         result = IC_RESULT(ic);
9160         right  = IC_RIGHT(ic) ;
9161         
9162         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9163         
9164         /* if they are the same */
9165         if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9166                 return ;
9167         
9168         aopOp(right,ic,FALSE);
9169         aopOp(result,ic,TRUE);
9170         
9171         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9172         
9173         /* if they are the same registers */
9174         if (pic14_sameRegs(AOP(right),AOP(result)))
9175                 goto release;
9176         
9177         /* if the result is a bit */
9178         if (AOP_TYPE(result) == AOP_CRY) {
9179                 
9180         /* if the right size is a literal then
9181                 we know what the value is */
9182                 if (AOP_TYPE(right) == AOP_LIT) {
9183                         
9184                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9185                                 popGet(AOP(result),0));
9186                         
9187                         if (((int) operandLitValue(right))) 
9188                                 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9189                                 AOP(result)->aopu.aop_dir,
9190                                 AOP(result)->aopu.aop_dir);
9191                         else
9192                                 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9193                                 AOP(result)->aopu.aop_dir,
9194                                 AOP(result)->aopu.aop_dir);
9195                         goto release;
9196                 }
9197                 
9198                 /* the right is also a bit variable */
9199                 if (AOP_TYPE(right) == AOP_CRY) {
9200                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9201                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9202                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9203                         
9204                         pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9205                                 AOP(result)->aopu.aop_dir,
9206                                 AOP(result)->aopu.aop_dir);
9207                         pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9208                                 AOP(right)->aopu.aop_dir,
9209                                 AOP(right)->aopu.aop_dir);
9210                         pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9211                                 AOP(result)->aopu.aop_dir,
9212                                 AOP(result)->aopu.aop_dir);
9213                         goto release ;
9214                 }
9215                 
9216                 /* we need to or */
9217                 emitpcode(POC_BCF,    popGet(AOP(result),0));
9218                 pic14_toBoolean(right);
9219                 emitSKPZ;
9220                 emitpcode(POC_BSF,    popGet(AOP(result),0));
9221                 //aopPut(AOP(result),"a",0);
9222                 goto release ;
9223         }
9224         
9225         /* bit variables done */
9226         /* general case */
9227         size = AOP_SIZE(result);
9228         offset = 0 ;
9229         if(AOP_TYPE(right) == AOP_LIT)
9230                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9231         
9232         if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
9233                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9234                 if(aopIdx(AOP(result),0) == 4) {
9235                         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9236                         emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9237                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9238                         goto release;
9239                 } else
9240                         DEBUGpic14_emitcode ("; WARNING","%s  %d ignoring register storage",__FUNCTION__,__LINE__);
9241         }
9242         
9243         know_W=-1;
9244         while (size--) {
9245                 DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9246                 if(AOP_TYPE(right) == AOP_LIT) {
9247                         if(lit&0xff) {
9248                                 if(know_W != (int)(lit&0xff))
9249                                         emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9250                                 know_W = lit&0xff;
9251                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9252                         } else
9253                                 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9254                         
9255                         lit >>= 8;
9256                         
9257                 } else if (AOP_TYPE(right) == AOP_CRY) {
9258                         emitpcode(POC_CLRF, popGet(AOP(result),offset));
9259                         if(offset == 0) {
9260                                 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9261                                 emitpcode(POC_INCF, popGet(AOP(result),0));
9262                         }
9263                 } else {
9264                         mov2w (AOP(right), offset);
9265                         emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9266                 }
9267                 
9268                 offset++;
9269         }
9270         
9271         
9272 release:
9273         freeAsmop (right,NULL,ic,FALSE);
9274         freeAsmop (result,NULL,ic,TRUE);
9275 }   
9276
9277 /*-----------------------------------------------------------------*/
9278 /* genJumpTab - genrates code for jump table                       */
9279 /*-----------------------------------------------------------------*/
9280 static void genJumpTab (iCode *ic)
9281 {
9282         symbol *jtab;
9283         char *l;
9284         
9285         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9286         
9287         aopOp(IC_JTCOND(ic),ic,FALSE);
9288         /* get the condition into accumulator */
9289         l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9290         MOVA(l);
9291         /* multiply by three */
9292         pic14_emitcode("add","a,acc");
9293         pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9294         
9295         jtab = newiTempLabel(NULL);
9296         pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9297         pic14_emitcode("jmp","@a+dptr");
9298         pic14_emitcode("","%05d_DS_:",jtab->key+100);
9299         
9300         emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9301         emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9302         emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9303         emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9304         emitSKPNC;
9305         emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9306         emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9307         emitpLabel(jtab->key);
9308         
9309         freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9310         
9311         /* now generate the jump labels */
9312         for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9313         jtab = setNextItem(IC_JTLABELS(ic))) {
9314                 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9315                 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9316                 
9317         }
9318         
9319 }
9320
9321 /*-----------------------------------------------------------------*/
9322 /* genMixedOperation - gen code for operators between mixed types  */
9323 /*-----------------------------------------------------------------*/
9324 /*
9325 TSD - Written for the PIC port - but this unfortunately is buggy.
9326 This routine is good in that it is able to efficiently promote 
9327 types to different (larger) sizes. Unfortunately, the temporary
9328 variables that are optimized out by this routine are sometimes
9329 used in other places. So until I know how to really parse the 
9330 iCode tree, I'm going to not be using this routine :(.
9331 */
9332 static int genMixedOperation (iCode *ic)
9333 {
9334 #if 0
9335         operand *result = IC_RESULT(ic);
9336         sym_link *ctype = operandType(IC_LEFT(ic));
9337         operand *right = IC_RIGHT(ic);
9338         int ret = 0;
9339         int big,small;
9340         int offset;
9341         
9342         iCode *nextic;
9343         operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9344         
9345         pic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9346         
9347         nextic = ic->next;
9348         if(!nextic)
9349                 return 0;
9350         
9351         nextright = IC_RIGHT(nextic);
9352         nextleft  = IC_LEFT(nextic);
9353         nextresult = IC_RESULT(nextic);
9354         
9355         aopOp(right,ic,FALSE);
9356         aopOp(result,ic,FALSE);
9357         aopOp(nextright,  nextic, FALSE);
9358         aopOp(nextleft,   nextic, FALSE);
9359         aopOp(nextresult, nextic, FALSE);
9360         
9361         if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9362                 
9363                 operand *t = right;
9364                 right = nextright;
9365                 nextright = t; 
9366                 
9367                 pic14_emitcode(";remove right +","");
9368                 
9369         } else   if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9370         /*
9371         operand *t = right;
9372         right = nextleft;
9373         nextleft = t; 
9374                 */
9375                 pic14_emitcode(";remove left +","");
9376         } else
9377                 return 0;
9378         
9379         big = AOP_SIZE(nextleft);
9380         small = AOP_SIZE(nextright);
9381         
9382         switch(nextic->op) {
9383                 
9384         case '+':
9385                 pic14_emitcode(";optimize a +","");
9386                 /* if unsigned or not an integral type */
9387                 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9388                         pic14_emitcode(";add a bit to something","");
9389                 } else {
9390                         
9391                         pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9392                         
9393                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9394                                 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9395                                 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9396                         } else
9397                                 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9398                         
9399                         offset = 0;
9400                         while(--big) {
9401                                 
9402                                 offset++;
9403                                 
9404                                 if(--small) {
9405                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9406                                                 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9407                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9408                                         }
9409                                         
9410                                         pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9411                                         emitSKPNC;
9412                                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9413                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9414                                                 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9415                                         pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9416                                         pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9417                                         
9418                                 } else {
9419                                         pic14_emitcode("rlf","known_zero,w");
9420                                         
9421                                         /*
9422                                         if right is signed
9423                                         btfsc  right,7
9424                                         addlw ff
9425                                         */
9426                                         if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9427                                                 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428                                                 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9429                                         } else {
9430                                                 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9431                                         }
9432                                 }
9433                         }
9434                         ret = 1;
9435                 }
9436         }
9437         ret = 1;
9438         
9439 release:
9440         freeAsmop(right,NULL,ic,TRUE);
9441         freeAsmop(result,NULL,ic,TRUE);
9442         freeAsmop(nextright,NULL,ic,TRUE);
9443         freeAsmop(nextleft,NULL,ic,TRUE);
9444         if(ret)
9445                 nextic->generated = 1;
9446         
9447         return ret;
9448 #else
9449         return 0;
9450 #endif
9451 }
9452 /*-----------------------------------------------------------------*/
9453 /* genCast - gen code for casting                                  */
9454 /*-----------------------------------------------------------------*/
9455 static void genCast (iCode *ic)
9456 {
9457         operand *result = IC_RESULT(ic);
9458         sym_link *ctype = operandType(IC_LEFT(ic));
9459         sym_link *rtype = operandType(IC_RIGHT(ic));
9460         operand *right = IC_RIGHT(ic);
9461         int size, offset ;
9462         
9463         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9464         /* if they are equivalent then do nothing */
9465         if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9466                 return ;
9467         
9468         aopOp(right,ic,FALSE) ;
9469         aopOp(result,ic,FALSE);
9470         
9471         DEBUGpic14_AopType(__LINE__,NULL,right,result);
9472         
9473         /* if the result is a bit */
9474         if (AOP_TYPE(result) == AOP_CRY) {
9475         /* if the right size is a literal then
9476                 we know what the value is */
9477                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9478                 if (AOP_TYPE(right) == AOP_LIT) {
9479                         
9480                         emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9481                                 popGet(AOP(result),0));
9482                         
9483                         if (((int) operandLitValue(right))) 
9484                                 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9485                                 AOP(result)->aopu.aop_dir,
9486                                 AOP(result)->aopu.aop_dir);
9487                         else
9488                                 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9489                                 AOP(result)->aopu.aop_dir,
9490                                 AOP(result)->aopu.aop_dir);
9491                         
9492                         goto release;
9493                 }
9494                 
9495                 /* the right is also a bit variable */
9496                 if (AOP_TYPE(right) == AOP_CRY) {
9497                         
9498                         emitCLRC;
9499                         emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9500                         
9501                         pic14_emitcode("clrc","");
9502                         pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9503                                 AOP(right)->aopu.aop_dir,
9504                                 AOP(right)->aopu.aop_dir);
9505                         aopPut(AOP(result),"c",0);
9506                         goto release ;
9507                 }
9508                 
9509                 /* we need to or */
9510                 if (AOP_TYPE(right) == AOP_REG) {
9511                         emitpcode(POC_BCF,    popGet(AOP(result),0));
9512                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9513                         emitpcode(POC_BSF,    popGet(AOP(result),0));
9514                 }
9515                 pic14_toBoolean(right);
9516                 aopPut(AOP(result),"a",0);
9517                 goto release ;
9518         }
9519         
9520         if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9521                 int offset = 1;
9522                 size = AOP_SIZE(result);
9523                 
9524                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9525                 
9526                 emitpcode(POC_CLRF,   popGet(AOP(result),0));
9527                 emitpcode(POC_BTFSC,  popGet(AOP(right),0));
9528                 emitpcode(POC_INCF,   popGet(AOP(result),0));
9529                 
9530                 while (size--)
9531                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9532                 
9533                 goto release;
9534         }
9535         
9536         /* if they are the same size : or less */
9537         if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9538                 
9539                 /* if they are in the same place */
9540                 if (pic14_sameRegs(AOP(right),AOP(result)))
9541                         goto release;
9542                 
9543                 DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9544                 if (IS_PTR_CONST(rtype))
9545                         DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9546                 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9547                         DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9548                 
9549                 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9550                         emitpcode(POC_MOVLW, popGet(AOP(right),0));
9551                         emitpcode(POC_MOVWF, popGet(AOP(result),0));
9552                         emitpcode(POC_MOVLW, popGet(AOP(right),1));
9553                         emitpcode(POC_MOVWF, popGet(AOP(result),1));
9554                         if(AOP_SIZE(result) <2)
9555                                 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9556                         
9557                 } else {
9558                         
9559                         /* if they in different places then copy */
9560                         size = AOP_SIZE(result);
9561                         offset = 0 ;
9562                         while (size--) {
9563                                 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9564                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9565                                 
9566                                 //aopPut(AOP(result),
9567                                 // aopGet(AOP(right),offset,FALSE,FALSE),
9568                                 // offset);
9569                                 
9570                                 offset++;
9571                         }
9572                 }
9573                 goto release;
9574         }
9575         
9576         
9577         /* if the result is of type pointer */
9578         if (IS_PTR(ctype)) {
9579                 
9580                 int p_type;
9581                 sym_link *type = operandType(right);
9582                 sym_link *etype = getSpec(type);
9583                 DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
9584                 
9585                 /* pointer to generic pointer */
9586                 if (IS_GENPTR(ctype)) {
9587                         char *l = zero;
9588                         
9589                         if (IS_PTR(type)) 
9590                                 p_type = DCL_TYPE(type);
9591                         else {
9592                                 /* we have to go by the storage class */
9593                                 p_type = PTR_TYPE(SPEC_OCLS(etype));
9594                                 
9595                                 /*    if (SPEC_OCLS(etype)->codesp )  */
9596                                 /*        p_type = CPOINTER ;  */
9597                                 /*    else */
9598                                 /*        if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9599                                 /*      p_type = FPOINTER ; */
9600                                 /*        else */
9601                                 /*      if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9602                                 /*          p_type = PPOINTER; */
9603                                 /*      else */
9604                                 /*          if (SPEC_OCLS(etype) == idata ) */
9605                                 /*        p_type = IPOINTER ; */
9606                                 /*          else */
9607                                 /*        p_type = POINTER ; */
9608                         }
9609                         
9610                         /* the first two bytes are known */
9611                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast2",__FUNCTION__,__LINE__);
9612                         size = GPTRSIZE - 1; 
9613                         offset = 0 ;
9614                         while (size--) {
9615                                 if(offset < AOP_SIZE(right)) {
9616                                         DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
9617                                         if ((AOP_TYPE(right) == AOP_PCODE) && 
9618                                                 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9619                                                 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9620                                                 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9621                                         } else { 
9622                                                 aopPut(AOP(result),
9623                                                         aopGet(AOP(right),offset,FALSE,FALSE),
9624                                                         offset);
9625                                         }
9626                                 } else 
9627                                         emitpcode(POC_CLRF,popGet(AOP(result),offset));
9628                                 offset++;
9629                         }
9630                         /* the last byte depending on type */
9631                         switch (p_type) {
9632                         case IPOINTER:
9633                         case POINTER:
9634                                 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9635                                 break;
9636                         case FPOINTER:
9637                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9638                                 l = one;
9639                                 break;
9640                         case CPOINTER:
9641                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9642                                 l = "#0x02";
9643                                 break;        
9644                         case PPOINTER:
9645                                 pic14_emitcode(";BUG!? ","%d",__LINE__);
9646                                 l = "#0x03";
9647                                 break;
9648                                 
9649                         default:
9650                                 /* this should never happen */
9651                                 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9652                                         "got unknown pointer type");
9653                                 exit(1);
9654                         }
9655                         //aopPut(AOP(result),l, GPTRSIZE - 1);      
9656                         goto release ;
9657                 }
9658                 
9659                 /* just copy the pointers */
9660                 size = AOP_SIZE(result);
9661                 offset = 0 ;
9662                 while (size--) {
9663                         aopPut(AOP(result),
9664                                 aopGet(AOP(right),offset,FALSE,FALSE),
9665                                 offset);
9666                         offset++;
9667                 }
9668                 goto release ;
9669         }
9670         
9671         
9672         
9673         /* so we now know that the size of destination is greater
9674         than the size of the source.
9675         Now, if the next iCode is an operator then we might be
9676         able to optimize the operation without performing a cast.
9677         */
9678         if(genMixedOperation(ic))
9679                 goto release;
9680         
9681         DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
9682         
9683         /* we move to result for the size of source */
9684         size = AOP_SIZE(right);
9685         offset = 0 ;
9686         while (size--) {
9687                 emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
9688                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
9689                 offset++;
9690         }
9691         
9692         /* now depending on the sign of the destination */
9693         size = AOP_SIZE(result) - AOP_SIZE(right);
9694         /* if unsigned or not an integral type */
9695         if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9696                 while (size--)
9697                         emitpcode(POC_CLRF,   popGet(AOP(result),offset++));
9698         } else {
9699                 /* we need to extend the sign :{ */
9700                 
9701                 if(size == 1) {
9702                         /* Save one instruction of casting char to int */
9703                         emitpcode(POC_CLRF,   popGet(AOP(result),offset));
9704                         emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9705                         emitpcode(POC_DECF,   popGet(AOP(result),offset));
9706                 } else {
9707                         emitpcodeNULLop(POC_CLRW);
9708                         
9709                         if(offset)
9710                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9711                         else
9712                                 emitpcode(POC_BTFSC,   newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9713                         
9714                         emitpcode(POC_MOVLW,   popGetLit(0xff));
9715                         
9716                         while (size--)
9717                                 emitpcode(POC_MOVWF,   popGet(AOP(result),offset++));
9718                 }
9719         }
9720         
9721 release:
9722         freeAsmop(right,NULL,ic,TRUE);
9723         freeAsmop(result,NULL,ic,TRUE);
9724         
9725 }
9726
9727 /*-----------------------------------------------------------------*/
9728 /* genDjnz - generate decrement & jump if not zero instrucion      */
9729 /*-----------------------------------------------------------------*/
9730 static int genDjnz (iCode *ic, iCode *ifx)
9731 {
9732         symbol *lbl, *lbl1;
9733         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9734         
9735         if (!ifx)
9736                 return 0;
9737         
9738                 /* if the if condition has a false label
9739         then we cannot save */
9740         if (IC_FALSE(ifx))
9741                 return 0;
9742         
9743                 /* if the minus is not of the form 
9744         a = a - 1 */
9745         if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9746                 !IS_OP_LITERAL(IC_RIGHT(ic)))
9747                 return 0;
9748         
9749         if (operandLitValue(IC_RIGHT(ic)) != 1)
9750                 return 0;
9751         
9752                 /* if the size of this greater than one then no
9753         saving */
9754         if (getSize(operandType(IC_RESULT(ic))) > 1)
9755                 return 0;
9756         
9757         /* otherwise we can save BIG */
9758         lbl = newiTempLabel(NULL);
9759         lbl1= newiTempLabel(NULL);
9760         
9761         aopOp(IC_RESULT(ic),ic,FALSE);
9762         
9763         if (IS_AOP_PREG(IC_RESULT(ic))) {
9764                 pic14_emitcode("dec","%s",
9765                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9766                 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9767                 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9768         } else {  
9769                 
9770                 
9771                 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9772                 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9773                 
9774                 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9775                 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9776                 
9777         }
9778         /*     pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9779         /*     pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9780         /*     pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9781         /*     pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9782         
9783         
9784         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9785         ifx->generated = 1;
9786         return 1;
9787 }
9788
9789 /*-----------------------------------------------------------------*/
9790 /* genReceive - generate code for a receive iCode                  */
9791 /*-----------------------------------------------------------------*/
9792 static void genReceive (iCode *ic)
9793 {
9794         DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
9795         
9796         if (isOperandInFarSpace(IC_RESULT(ic)) &&
9797                 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9798                 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9799                 
9800                 int size = getSize(operandType(IC_RESULT(ic)));
9801                 int offset =  fReturnSizePic - size;
9802                 while (size--) {
9803                         pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9804                                 fReturn[fReturnSizePic - offset - 1] : "acc"));
9805                         offset++;
9806                 }
9807                 aopOp(IC_RESULT(ic),ic,FALSE);
9808                 size = AOP_SIZE(IC_RESULT(ic));
9809                 offset = 0;
9810                 while (size--) {
9811                         pic14_emitcode ("pop","acc");
9812                         aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9813                 }
9814                 
9815         } else {
9816                 _G.accInUse++;
9817                 aopOp(IC_RESULT(ic),ic,FALSE);
9818                 _G.accInUse--;
9819                 assignResultValue(IC_RESULT(ic));
9820         }
9821         
9822         freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9823 }
9824
9825 /*-----------------------------------------------------------------*/
9826 /* genDummyRead - generate code for dummy read of volatiles        */
9827 /*-----------------------------------------------------------------*/
9828 static void
9829 genDummyRead (iCode * ic)
9830 {
9831         pic14_emitcode ("; genDummyRead","");
9832         pic14_emitcode ("; not implemented","");
9833         
9834         ic = ic;
9835 }
9836
9837 /*-----------------------------------------------------------------*/
9838 /* genpic14Code - generate code for pic14 based controllers        */
9839 /*-----------------------------------------------------------------*/
9840 /*
9841 * At this point, ralloc.c has gone through the iCode and attempted
9842 * to optimize in a way suitable for a PIC. Now we've got to generate
9843 * PIC instructions that correspond to the iCode.
9844 *
9845 * Once the instructions are generated, we'll pass through both the
9846 * peep hole optimizer and the pCode optimizer.
9847 *-----------------------------------------------------------------*/
9848
9849 void genpic14Code (iCode *lic)
9850 {
9851         iCode *ic;
9852         int cln = 0;
9853         
9854         lineHead = lineCurr = NULL;
9855         
9856         pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9857         addpBlock(pb);
9858         
9859         /* if debug information required */
9860         if (options.debug && currFunc) { 
9861                 if (currFunc) {
9862                         debugFile->writeFunction (currFunc, lic);
9863                 }
9864         }
9865         
9866         
9867         for (ic = lic ; ic ; ic = ic->next ) {
9868                 
9869                 DEBUGpic14_emitcode(";ic","");
9870                 if ( cln != ic->lineno ) {
9871                         if ( options.debug ) {
9872                                 debugFile->writeCLine (ic);
9873                         }
9874                         /*
9875                         pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9876                         pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
9877                         printCLine(ic->filename, ic->lineno));
9878                         */
9879                         if (!options.noCcodeInAsm) {
9880                                 addpCode2pBlock(pb,
9881                                         newpCodeCSource(ic->lineno, 
9882                                         ic->filename, 
9883                                         printCLine(ic->filename, ic->lineno)));
9884                         }
9885                         
9886                         cln = ic->lineno ;
9887                 }
9888                 
9889                 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9890                 
9891                 /* if the result is marked as
9892                 spilt and rematerializable or code for
9893                 this has already been generated then
9894                 do nothing */
9895                 if (resultRemat(ic) || ic->generated ) 
9896                         continue ;
9897                 
9898                 /* depending on the operation */
9899                 switch (ic->op) {
9900                 case '!' :
9901                         genNot(ic);
9902                         break;
9903                         
9904                 case '~' :
9905                         genCpl(ic);
9906                         break;
9907                         
9908                 case UNARYMINUS:
9909                         genUminus (ic);
9910                         break;
9911                         
9912                 case IPUSH:
9913                         genIpush (ic);
9914                         break;
9915                         
9916                 case IPOP:
9917                 /* IPOP happens only when trying to restore a 
9918                 spilt live range, if there is an ifx statement
9919                 following this pop then the if statement might
9920                 be using some of the registers being popped which
9921                 would destory the contents of the register so
9922                 we need to check for this condition and handle it */
9923                         if (ic->next            && 
9924                                 ic->next->op == IFX &&
9925                                 regsInCommon(IC_LEFT(ic),IC_COND(ic->next))) 
9926                                 genIfx (ic->next,ic);
9927                         else
9928                                 genIpop (ic);
9929                         break; 
9930                         
9931                 case CALL:
9932                         genCall (ic);
9933                         break;
9934                         
9935                 case PCALL:
9936                         genPcall (ic);
9937                         break;
9938                         
9939                 case FUNCTION:
9940                         genFunction (ic);
9941                         break;
9942                         
9943                 case ENDFUNCTION:
9944                         genEndFunction (ic);
9945                         break;
9946                         
9947                 case RETURN:
9948                         genRet (ic);
9949                         break;
9950                         
9951                 case LABEL:
9952                         genLabel (ic);
9953                         break;
9954                         
9955                 case GOTO:
9956                         genGoto (ic);
9957                         break;
9958                         
9959                 case '+' :
9960                         genPlus (ic) ;
9961                         break;
9962                         
9963                 case '-' :
9964                         if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9965                                 genMinus (ic);
9966                         break;
9967                         
9968                 case '*' :
9969                         genMult (ic);
9970                         break;
9971                         
9972                 case '/' :
9973                         genDiv (ic) ;
9974                         break;
9975                         
9976                 case '%' :
9977                         genMod (ic);
9978                         break;
9979                         
9980                 case '>' :
9981                         genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));         
9982                         break;
9983                         
9984                 case '<' :
9985                         genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9986                         break;
9987                         
9988                 case LE_OP:
9989                 case GE_OP:
9990                 case NE_OP:
9991                         
9992                 /* note these two are xlated by algebraic equivalence
9993                         during parsing SDCC.y */
9994                         werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9995                                 "got '>=' or '<=' shouldn't have come here");
9996                         break;  
9997                         
9998                 case EQ_OP:
9999                         genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10000                         break;      
10001                         
10002                 case AND_OP:
10003                         genAndOp (ic);
10004                         break;
10005                         
10006                 case OR_OP:
10007                         genOrOp (ic);
10008                         break;
10009                         
10010                 case '^' :
10011                         genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10012                         break;
10013                         
10014                 case '|' :
10015                         genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10016                         break;
10017                         
10018                 case BITWISEAND:
10019                         genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10020                         break;
10021                         
10022                 case INLINEASM:
10023                         genInline (ic);
10024                         break;
10025                         
10026                 case RRC:
10027                         genRRC (ic);
10028                         break;
10029                         
10030                 case RLC:
10031                         genRLC (ic);
10032                         break;
10033                         
10034                 case GETHBIT:
10035                         genGetHbit (ic);
10036                         break;
10037                         
10038                 case LEFT_OP:
10039                         genLeftShift (ic);
10040                         break;
10041                         
10042                 case RIGHT_OP:
10043                         genRightShift (ic);
10044                         break;
10045                         
10046                 case GET_VALUE_AT_ADDRESS:
10047                         genPointerGet(ic);
10048                         break;
10049                         
10050                 case '=' :
10051                         if (POINTER_SET(ic))
10052                                 genPointerSet(ic);
10053                         else
10054                                 genAssign(ic);
10055                         break;
10056                         
10057                 case IFX:
10058                         genIfx (ic,NULL);
10059                         break;
10060                         
10061                 case ADDRESS_OF:
10062                         genAddrOf (ic);
10063                         break;
10064                         
10065                 case JUMPTABLE:
10066                         genJumpTab (ic);
10067                         break;
10068                         
10069                 case CAST:
10070                         genCast (ic);
10071                         break;
10072                         
10073                 case RECEIVE:
10074                         genReceive(ic);
10075                         break;
10076                         
10077                 case SEND:
10078                         addSet(&_G.sendSet,ic);
10079                         break;
10080                         
10081                 case DUMMY_READ_VOLATILE:
10082                         genDummyRead (ic);
10083                         break;
10084                         
10085                 default :
10086                         ic = ic;
10087                 }
10088         }
10089
10090         
10091         /* now we are ready to call the
10092         peep hole optimizer */
10093         if (!options.nopeep) {
10094                 peepHole (&lineHead);
10095         }
10096         /* now do the actual printing */
10097         printLine (lineHead,codeOutFile);
10098         
10099 #ifdef PCODE_DEBUG
10100         DFPRINTF((stderr,"printing pBlock\n\n"));
10101         printpBlock(stdout,pb);
10102 #endif
10103         
10104         return;
10105 }