1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
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)
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
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.
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.
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!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
67 static int labelOffset=0;
68 static int debug_verbose=1;
69 static int optimized_for_speed = 0;
71 /* max_key keeps track of the largest label number used in
72 a function. This is then used to adjust the label offset
73 for the next function.
76 static int GpsuedoStkPtr=0;
78 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
79 unsigned int pic14aopLiteral (value *val, int offset);
80 const char *AopType(short type);
81 static iCode *ifxForOp ( operand *op, iCode *ic );
83 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
85 /* this is the down and dirty file with all kinds of
86 kludgy & hacky stuff. This is what it is all about
87 CODE GENERATION for a specific MCU . some of the
88 routines may be reusable, will have to see */
90 static char *zero = "#0x00";
91 static char *one = "#0x01";
92 static char *spname = "sp";
94 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
95 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
96 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
97 static char **fReturn = fReturnpic14;
99 static char *accUse[] = {"a","b"};
101 //static short rbank = -1;
113 /* Resolved ifx structure. This structure stores information
114 about an iCode ifx that makes it easier to generate code.
116 typedef struct resolvedIfx {
117 symbol *lbl; /* pointer to a label */
118 int condition; /* true or false ifx */
119 int generated; /* set true when the code associated with the ifx
123 extern int pic14_ptrRegReq ;
124 extern int pic14_nRegs;
125 extern FILE *codeOutFile;
126 static void saverbank (int, iCode *,bool);
128 static lineNode *lineHead = NULL;
129 static lineNode *lineCurr = NULL;
131 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
132 0xE0, 0xC0, 0x80, 0x00};
133 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
134 0x07, 0x03, 0x01, 0x00};
138 /*-----------------------------------------------------------------*/
139 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
140 /* exponent of 2 is returned, otherwise -1 is */
142 /* note that this is similar to the function `powof2' in SDCCsymt */
146 /*-----------------------------------------------------------------*/
147 static int my_powof2 (unsigned long num)
150 if( (num & (num-1)) == 0) {
163 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
174 ((result) ? AOP_SIZE(result) : 0));
178 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
183 ((result) ? AopType(AOP_TYPE(result)) : "-"),
184 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
185 ((left) ? AopType(AOP_TYPE(left)) : "-"),
186 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
187 ((right) ? AopType(AOP_TYPE(right)) : "-"),
188 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
192 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 char lb[INITIAL_INLINEASM];
205 sprintf(lb,"%s\t",inst);
207 sprintf(lb,"%s",inst);
208 vsprintf(lb+(strlen(lb)),fmt,ap);
212 while (isspace(*lbp)) lbp++;
215 lineCurr = (lineCurr ?
216 connectLine(lineCurr,newLineNode(lb)) :
217 (lineHead = newLineNode(lb)));
218 lineCurr->isInline = _G.inLine;
219 lineCurr->isDebug = _G.debugLine;
221 addpCode2pBlock(pb,newpCodeCharP(lb));
227 void emitpLabel(int key)
229 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
236 addpCode2pBlock(pb,newpCode(poc,pcop));
238 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
241 void emitpcodeNULLop(PIC_OPCODE poc)
244 addpCode2pBlock(pb,newpCode(poc,NULL));
248 /*-----------------------------------------------------------------*/
249 /* pic14_emitcode - writes the code into a file : for now it is simple */
250 /*-----------------------------------------------------------------*/
251 void pic14_emitcode (char *inst,char *fmt, ...)
254 char lb[INITIAL_INLINEASM];
261 sprintf(lb,"%s\t",inst);
263 sprintf(lb,"%s",inst);
264 vsprintf(lb+(strlen(lb)),fmt,ap);
268 while (isspace(*lbp)) lbp++;
271 lineCurr = (lineCurr ?
272 connectLine(lineCurr,newLineNode(lb)) :
273 (lineHead = newLineNode(lb)));
274 lineCurr->isInline = _G.inLine;
275 lineCurr->isDebug = _G.debugLine;
278 addpCode2pBlock(pb,newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 /* the logic: if r0 & r1 used in the instruction
293 then we are in trouble otherwise */
295 /* first check if r0 & r1 are used by this
296 instruction, in which case we are in trouble */
297 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
298 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
303 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
304 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
306 /* if no usage of r0 then return it */
307 if (!r0iu && !r0ou) {
308 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
309 (*aopp)->type = AOP_R0;
311 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314 /* if no usage of r1 then return it */
315 if (!r1iu && !r1ou) {
316 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
317 (*aopp)->type = AOP_R1;
319 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322 /* now we know they both have usage */
323 /* if r0 not used in this instruction */
325 /* push it if not already pushed */
327 //pic14_emitcode ("push","%s",
328 // pic14_regWithIdx(R0_IDX)->dname);
332 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
333 (*aopp)->type = AOP_R0;
335 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338 /* if r1 not used then */
341 /* push it if not already pushed */
343 //pic14_emitcode ("push","%s",
344 // pic14_regWithIdx(R1_IDX)->dname);
348 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349 (*aopp)->type = AOP_R1;
350 return pic14_regWithIdx(R1_IDX);
354 /* I said end of world but not quite end of world yet */
355 /* if this is a result then we can push it on the stack*/
357 (*aopp)->type = AOP_STK;
361 /* other wise this is true end of the world */
362 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
363 "getFreePtr should never reach here");
367 /*-----------------------------------------------------------------*/
368 /* newAsmop - creates a new asmOp */
369 /*-----------------------------------------------------------------*/
370 asmop *newAsmop (short type)
374 aop = Safe_calloc(1,sizeof(asmop));
379 static void genSetDPTR(int n)
383 pic14_emitcode(";", "Select standard DPTR");
384 pic14_emitcode("mov", "dps, #0x00");
388 pic14_emitcode(";", "Select alternate DPTR");
389 pic14_emitcode("mov", "dps, #0x01");
393 /*-----------------------------------------------------------------*/
394 /* resolveIfx - converts an iCode ifx into a form more useful for */
395 /* generating code */
396 /*-----------------------------------------------------------------*/
397 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
402 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
404 resIfx->condition = 1; /* assume that the ifx is true */
405 resIfx->generated = 0; /* indicate that the ifx has not been used */
408 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
409 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
410 __FUNCTION__,__LINE__,resIfx->lbl->key);
413 resIfx->lbl = IC_TRUE(ifx);
415 resIfx->lbl = IC_FALSE(ifx);
416 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
424 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
433 return PTR_TYPE(SPEC_OCLS(etype));
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
443 memmap *space= SPEC_OCLS(sym->etype);
445 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446 /* if already has one */
450 /* assign depending on the storage class */
451 /* if it is on the stack or indirectly addressable */
452 /* space we need to assign either r0 or r1 to it */
453 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454 sym->aop = aop = newAsmop(0);
455 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456 aop->size = getSize(sym->type);
458 /* now assign the address of the variable to
459 the pointer register */
460 if (aop->type != AOP_STK) {
464 pic14_emitcode("push","acc");
466 pic14_emitcode("mov","a,_bp");
467 pic14_emitcode("add","a,#0x%02x",
469 ((char)(sym->stack - _G.nRegsSaved )) :
470 ((char)sym->stack)) & 0xff);
471 pic14_emitcode("mov","%s,a",
472 aop->aopu.aop_ptr->name);
475 pic14_emitcode("pop","acc");
477 pic14_emitcode("mov","%s,#%s",
478 aop->aopu.aop_ptr->name,
480 aop->paged = space->paged;
482 aop->aopu.aop_stk = sym->stack;
486 if (sym->onStack && options.stack10bit)
488 /* It's on the 10 bit stack, which is located in
492 //DEBUGpic14_emitcode(";","%d",__LINE__);
495 pic14_emitcode("push","acc");
497 pic14_emitcode("mov","a,_bp");
498 pic14_emitcode("add","a,#0x%02x",
500 ((char)(sym->stack - _G.nRegsSaved )) :
501 ((char)sym->stack)) & 0xff);
504 pic14_emitcode ("mov","dpx1,#0x40");
505 pic14_emitcode ("mov","dph1,#0x00");
506 pic14_emitcode ("mov","dpl1, a");
510 pic14_emitcode("pop","acc");
512 sym->aop = aop = newAsmop(AOP_DPTR2);
513 aop->size = getSize(sym->type);
517 //DEBUGpic14_emitcode(";","%d",__LINE__);
518 /* if in bit space */
519 if (IN_BITSPACE(space)) {
520 sym->aop = aop = newAsmop (AOP_CRY);
521 aop->aopu.aop_dir = sym->rname ;
522 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
526 /* if it is in direct space */
527 if (IN_DIRSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_DIR);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
535 /* special case for a function */
536 if (IS_FUNC(sym->type)) {
537 sym->aop = aop = newAsmop(AOP_IMMD);
538 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
539 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
540 strcpy(aop->aopu.aop_immd,sym->rname);
541 aop->size = FPTRSIZE;
542 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
547 /* only remaining is far space */
548 /* in which case DPTR gets the address */
549 sym->aop = aop = newAsmop(AOP_PCODE);
551 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
552 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
553 PCOI(aop->aopu.pcop)->index = 0;
555 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
556 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
558 allocDirReg (IC_LEFT(ic));
560 aop->size = FPTRSIZE;
562 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
563 sym->aop = aop = newAsmop(AOP_DPTR);
564 pic14_emitcode ("mov","dptr,#%s", sym->rname);
565 aop->size = getSize(sym->type);
567 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
570 /* if it is in code space */
571 if (IN_CODESPACE(space))
577 /*-----------------------------------------------------------------*/
578 /* aopForRemat - rematerialzes an object */
579 /*-----------------------------------------------------------------*/
580 static asmop *aopForRemat (operand *op) // x symbol *sym)
582 symbol *sym = OP_SYMBOL(op);
584 asmop *aop = newAsmop(AOP_PCODE);
588 ic = sym->rematiCode;
590 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
591 if(IS_OP_POINTER(op)) {
592 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
596 val += (int) operandLitValue(IC_RIGHT(ic));
597 } else if (ic->op == '-') {
598 val -= (int) operandLitValue(IC_RIGHT(ic));
602 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
605 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
606 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
607 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
608 PCOI(aop->aopu.pcop)->index = val;
610 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
611 OP_SYMBOL(IC_LEFT(ic))->rname,
612 val, IS_PTR_CONST(operandType(op)));
614 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
616 allocDirReg (IC_LEFT(ic));
621 int aopIdx (asmop *aop, int offset)
626 if(aop->type != AOP_REG)
629 return aop->aopu.aop_reg[offset]->rIdx;
632 /*-----------------------------------------------------------------*/
633 /* regsInCommon - two operands have some registers in common */
634 /*-----------------------------------------------------------------*/
635 static bool regsInCommon (operand *op1, operand *op2)
640 /* if they have registers in common */
641 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
644 sym1 = OP_SYMBOL(op1);
645 sym2 = OP_SYMBOL(op2);
647 if (sym1->nRegs == 0 || sym2->nRegs == 0)
650 for (i = 0 ; i < sym1->nRegs ; i++) {
655 for (j = 0 ; j < sym2->nRegs ;j++ ) {
659 if (sym2->regs[j] == sym1->regs[i])
667 /*-----------------------------------------------------------------*/
668 /* operandsEqu - equivalent */
669 /*-----------------------------------------------------------------*/
670 static bool operandsEqu ( operand *op1, operand *op2)
674 /* if they not symbols */
675 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
678 sym1 = OP_SYMBOL(op1);
679 sym2 = OP_SYMBOL(op2);
681 /* if both are itemps & one is spilt
682 and the other is not then false */
683 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
684 sym1->isspilt != sym2->isspilt )
687 /* if they are the same */
691 if (strcmp(sym1->rname,sym2->rname) == 0)
695 /* if left is a tmp & right is not */
699 (sym1->usl.spillLoc == sym2))
706 (sym2->usl.spillLoc == sym1))
712 /*-----------------------------------------------------------------*/
713 /* pic14_sameRegs - two asmops have the same registers */
714 /*-----------------------------------------------------------------*/
715 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 if (aop1->type != AOP_REG ||
723 aop2->type != AOP_REG )
726 if (aop1->size != aop2->size )
729 for (i = 0 ; i < aop1->size ; i++ )
730 if (aop1->aopu.aop_reg[i] !=
731 aop2->aopu.aop_reg[i] )
737 /*-----------------------------------------------------------------*/
738 /* aopOp - allocates an asmop for an operand : */
739 /*-----------------------------------------------------------------*/
740 void aopOp (operand *op, iCode *ic, bool result)
749 // DEBUGpic14_emitcode(";","%d",__LINE__);
750 /* if this a literal */
751 if (IS_OP_LITERAL(op)) {
752 op->aop = aop = newAsmop(AOP_LIT);
753 aop->aopu.aop_lit = op->operand.valOperand;
754 aop->size = getSize(operandType(op));
759 sym_link *type = operandType(op);
760 if(IS_PTR_CONST(type))
761 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
764 /* if already has a asmop then continue */
768 /* if the underlying symbol has a aop */
769 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
770 DEBUGpic14_emitcode(";","%d",__LINE__);
771 op->aop = OP_SYMBOL(op)->aop;
775 /* if this is a true symbol */
776 if (IS_TRUE_SYMOP(op)) {
777 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
778 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
782 /* this is a temporary : this has
788 e) can be a return use only */
793 /* if the type is a conditional */
794 if (sym->regType == REG_CND) {
795 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
800 /* if it is spilt then two situations
802 b) has a spill location */
803 if (sym->isspilt || sym->nRegs == 0) {
805 DEBUGpic14_emitcode(";","%d",__LINE__);
806 /* rematerialize it NOW */
809 sym->aop = op->aop = aop =
811 aop->size = getSize(sym->type);
812 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
818 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
819 aop->size = getSize(sym->type);
820 for ( i = 0 ; i < 2 ; i++ )
821 aop->aopu.aop_str[i] = accUse[i];
822 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
828 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
829 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
830 //allocDirReg (IC_LEFT(ic));
831 aop->size = getSize(sym->type);
836 aop = op->aop = sym->aop = newAsmop(AOP_STR);
837 aop->size = getSize(sym->type);
838 for ( i = 0 ; i < fReturnSizePic ; i++ )
839 aop->aopu.aop_str[i] = fReturn[i];
841 DEBUGpic14_emitcode(";","%d",__LINE__);
845 /* else spill location */
846 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
847 /* force a new aop if sizes differ */
848 sym->usl.spillLoc->aop = NULL;
850 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
851 __FUNCTION__,__LINE__,
852 sym->usl.spillLoc->rname,
853 sym->rname, sym->usl.spillLoc->offset);
855 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
856 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
857 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
859 sym->usl.spillLoc->offset);
860 aop->size = getSize(sym->type);
866 sym_link *type = operandType(op);
867 if(IS_PTR_CONST(type))
868 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
871 /* must be in a register */
872 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
873 sym->aop = op->aop = aop = newAsmop(AOP_REG);
874 aop->size = sym->nRegs;
875 for ( i = 0 ; i < sym->nRegs ;i++)
876 aop->aopu.aop_reg[i] = sym->regs[i];
879 /*-----------------------------------------------------------------*/
880 /* freeAsmop - free up the asmop given to an operand */
881 /*----------------------------------------------------------------*/
882 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
899 /* depending on the asmop type only three cases need work AOP_RO
900 , AOP_R1 && AOP_STK */
906 pic14_emitcode ("pop","ar0");
910 bitVectUnSetBit(ic->rUsed,R0_IDX);
916 pic14_emitcode ("pop","ar1");
920 bitVectUnSetBit(ic->rUsed,R1_IDX);
926 int stk = aop->aopu.aop_stk + aop->size;
927 bitVectUnSetBit(ic->rUsed,R0_IDX);
928 bitVectUnSetBit(ic->rUsed,R1_IDX);
930 getFreePtr(ic,&aop,FALSE);
932 if (options.stack10bit)
934 /* I'm not sure what to do here yet... */
937 "*** Warning: probably generating bad code for "
938 "10 bit stack mode.\n");
942 pic14_emitcode ("mov","a,_bp");
943 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
944 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
946 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
950 pic14_emitcode("pop","acc");
951 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
953 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
956 freeAsmop(op,NULL,ic,TRUE);
958 pic14_emitcode("pop","ar0");
963 pic14_emitcode("pop","ar1");
971 /* all other cases just dealloc */
975 OP_SYMBOL(op)->aop = NULL;
976 /* if the symbol has a spill */
978 SPIL_LOC(op)->aop = NULL;
983 /*-----------------------------------------------------------------*/
984 /* aopGet - for fetching value of the aop */
985 /*-----------------------------------------------------------------*/
986 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
991 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
992 /* offset is greater than
994 if (offset > (aop->size - 1) &&
995 aop->type != AOP_LIT)
998 /* depending on type */
1003 DEBUGpic14_emitcode(";","%d",__LINE__);
1004 /* if we need to increment it */
1005 while (offset > aop->coff) {
1006 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1010 while (offset < aop->coff) {
1011 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1015 aop->coff = offset ;
1017 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1018 return (dname ? "acc" : "a");
1020 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1021 rs = Safe_calloc(1,strlen(s)+1);
1027 DEBUGpic14_emitcode(";","%d",__LINE__);
1028 if (aop->type == AOP_DPTR2)
1033 while (offset > aop->coff) {
1034 pic14_emitcode ("inc","dptr");
1038 while (offset < aop->coff) {
1039 pic14_emitcode("lcall","__decdptr");
1045 pic14_emitcode("clr","a");
1046 pic14_emitcode("movc","a,@a+dptr");
1049 pic14_emitcode("movx","a,@dptr");
1052 if (aop->type == AOP_DPTR2)
1057 return (dname ? "acc" : "a");
1062 sprintf (s,"%s",aop->aopu.aop_immd);
1065 sprintf(s,"(%s >> %d)",
1070 aop->aopu.aop_immd);
1071 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1072 rs = Safe_calloc(1,strlen(s)+1);
1078 sprintf(s,"(%s + %d)",
1081 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1083 sprintf(s,"%s",aop->aopu.aop_dir);
1084 rs = Safe_calloc(1,strlen(s)+1);
1090 // return aop->aopu.aop_reg[offset]->dname;
1092 return aop->aopu.aop_reg[offset]->name;
1095 //pic14_emitcode(";","%d",__LINE__);
1096 return aop->aopu.aop_dir;
1099 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1100 return "AOP_accumulator_bug";
1103 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1104 rs = Safe_calloc(1,strlen(s)+1);
1109 DEBUGpic14_emitcode(";","%d",__LINE__);
1110 aop->coff = offset ;
1111 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1115 return aop->aopu.aop_str[offset];
1119 pCodeOp *pcop = aop->aopu.pcop;
1120 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1122 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1123 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1124 sprintf(s,"%s", pcop->name);
1126 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1129 rs = Safe_calloc(1,strlen(s)+1);
1135 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1136 "aopget got unsupported aop->type");
1141 /*-----------------------------------------------------------------*/
1142 /* popGetTempReg - create a new temporary pCodeOp */
1143 /*-----------------------------------------------------------------*/
1144 pCodeOp *popGetTempReg(void)
1149 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1150 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1151 PCOR(pcop)->r->wasUsed=1;
1152 PCOR(pcop)->r->isFree=0;
1158 /*-----------------------------------------------------------------*/
1159 /* popGetTempReg - create a new temporary pCodeOp */
1160 /*-----------------------------------------------------------------*/
1161 void popReleaseTempReg(pCodeOp *pcop)
1164 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1165 PCOR(pcop)->r->isFree = 1;
1168 /*-----------------------------------------------------------------*/
1169 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1170 /*-----------------------------------------------------------------*/
1171 pCodeOp *popGetLabel(unsigned int key)
1174 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1179 return newpCodeOpLabel(NULL,key+100+labelOffset);
1182 /*-----------------------------------------------------------------*/
1183 /* popCopyReg - copy a pcode operator */
1184 /*-----------------------------------------------------------------*/
1185 pCodeOp *popCopyReg(pCodeOpReg *pc)
1189 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1190 pcor->pcop.type = pc->pcop.type;
1192 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1193 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1195 pcor->pcop.name = NULL;
1198 pcor->rIdx = pc->rIdx;
1201 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1205 /*-----------------------------------------------------------------*/
1206 /* popGet - asm operator to pcode operator conversion */
1207 /*-----------------------------------------------------------------*/
1208 pCodeOp *popGetLit(unsigned int lit)
1211 return newpCodeOpLit(lit);
1215 /*-----------------------------------------------------------------*/
1216 /* popGetImmd - asm operator to pcode immediate conversion */
1217 /*-----------------------------------------------------------------*/
1218 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1221 return newpCodeOpImmd(name, offset,index, 0);
1225 /*-----------------------------------------------------------------*/
1226 /* popGet - asm operator to pcode operator conversion */
1227 /*-----------------------------------------------------------------*/
1228 pCodeOp *popGetWithString(char *str)
1234 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1238 pcop = newpCodeOp(str,PO_STR);
1243 /*-----------------------------------------------------------------*/
1244 /* popRegFromString - */
1245 /*-----------------------------------------------------------------*/
1246 pCodeOp *popRegFromString(char *str, int size, int offset)
1249 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1250 pcop->type = PO_DIR;
1252 DEBUGpic14_emitcode(";","%d",__LINE__);
1257 pcop->name = Safe_calloc(1,strlen(str)+1);
1258 strcpy(pcop->name,str);
1260 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1262 PCOR(pcop)->r = dirregWithName(pcop->name);
1263 if(PCOR(pcop)->r == NULL) {
1264 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1265 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1266 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1268 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1270 PCOR(pcop)->instance = offset;
1275 pCodeOp *popRegFromIdx(int rIdx)
1279 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1280 __FUNCTION__,__LINE__,rIdx);
1282 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1284 PCOR(pcop)->rIdx = rIdx;
1285 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1286 PCOR(pcop)->r->isFree = 0;
1287 PCOR(pcop)->r->wasUsed = 1;
1289 pcop->type = PCOR(pcop)->r->pc_type;
1294 /*-----------------------------------------------------------------*/
1295 /* popGet - asm operator to pcode operator conversion */
1296 /*-----------------------------------------------------------------*/
1297 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1299 //char *s = buffer ;
1304 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1305 /* offset is greater than
1308 if (offset > (aop->size - 1) &&
1309 aop->type != AOP_LIT)
1310 return NULL; //zero;
1312 /* depending on type */
1313 switch (aop->type) {
1320 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1324 DEBUGpic14_emitcode(";","%d",__LINE__);
1325 return popGetImmd(aop->aopu.aop_immd,offset,0);
1328 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1330 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1331 pcop->type = PO_DIR;
1335 sprintf(s,"(%s + %d)",
1339 sprintf(s,"%s",aop->aopu.aop_dir);
1340 pcop->name = Safe_calloc(1,strlen(s)+1);
1341 strcpy(pcop->name,s);
1343 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1344 strcpy(pcop->name,aop->aopu.aop_dir);
1345 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1346 if(PCOR(pcop)->r == NULL) {
1347 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1348 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1349 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1351 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1353 PCOR(pcop)->instance = offset;
1360 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1362 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1363 PCOR(pcop)->rIdx = rIdx;
1364 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1365 PCOR(pcop)->r->wasUsed=1;
1366 PCOR(pcop)->r->isFree=0;
1368 PCOR(pcop)->instance = offset;
1369 pcop->type = PCOR(pcop)->r->pc_type;
1370 //rs = aop->aopu.aop_reg[offset]->name;
1371 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1376 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1377 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1378 //if(PCOR(pcop)->r == NULL)
1379 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1383 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1386 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1387 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1389 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1390 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1391 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1392 pcop->type = PCOR(pcop)->r->pc_type;
1393 pcop->name = PCOR(pcop)->r->name;
1399 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1401 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1402 pcop = pCodeOpCopy(aop->aopu.pcop);
1403 PCOI(pcop)->offset = offset;
1407 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1408 "popGet got unsupported aop->type");
1411 /*-----------------------------------------------------------------*/
1412 /* aopPut - puts a string for a aop */
1413 /*-----------------------------------------------------------------*/
1414 void aopPut (asmop *aop, char *s, int offset)
1419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1421 if (aop->size && offset > ( aop->size - 1)) {
1422 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1423 "aopPut got offset > aop->size");
1427 /* will assign value to value */
1428 /* depending on where it is ofcourse */
1429 switch (aop->type) {
1432 sprintf(d,"(%s + %d)",
1433 aop->aopu.aop_dir,offset);
1434 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1437 sprintf(d,"%s",aop->aopu.aop_dir);
1440 DEBUGpic14_emitcode(";","%d",__LINE__);
1442 pic14_emitcode("movf","%s,w",s);
1443 pic14_emitcode("movwf","%s",d);
1446 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1447 if(offset >= aop->size) {
1448 emitpcode(POC_CLRF,popGet(aop,offset));
1451 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1454 emitpcode(POC_MOVWF,popGet(aop,offset));
1461 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1462 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1465 strcmp(s,"r0") == 0 ||
1466 strcmp(s,"r1") == 0 ||
1467 strcmp(s,"r2") == 0 ||
1468 strcmp(s,"r3") == 0 ||
1469 strcmp(s,"r4") == 0 ||
1470 strcmp(s,"r5") == 0 ||
1471 strcmp(s,"r6") == 0 ||
1472 strcmp(s,"r7") == 0 )
1473 pic14_emitcode("mov","%s,%s ; %d",
1474 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1478 if(strcmp(s,"W")==0 )
1479 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1481 pic14_emitcode("movwf","%s",
1482 aop->aopu.aop_reg[offset]->name);
1484 if(strcmp(s,zero)==0) {
1485 emitpcode(POC_CLRF,popGet(aop,offset));
1487 } else if(strcmp(s,"W")==0) {
1488 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1489 pcop->type = PO_GPR_REGISTER;
1491 PCOR(pcop)->rIdx = -1;
1492 PCOR(pcop)->r = NULL;
1494 DEBUGpic14_emitcode(";","%d",__LINE__);
1495 pcop->name = Safe_strdup(s);
1496 emitpcode(POC_MOVFW,pcop);
1497 emitpcode(POC_MOVWF,popGet(aop,offset));
1498 } else if(strcmp(s,one)==0) {
1499 emitpcode(POC_CLRF,popGet(aop,offset));
1500 emitpcode(POC_INCF,popGet(aop,offset));
1502 emitpcode(POC_MOVWF,popGet(aop,offset));
1510 if (aop->type == AOP_DPTR2)
1516 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1517 "aopPut writting to code space");
1521 while (offset > aop->coff) {
1523 pic14_emitcode ("inc","dptr");
1526 while (offset < aop->coff) {
1528 pic14_emitcode("lcall","__decdptr");
1533 /* if not in accumulater */
1536 pic14_emitcode ("movx","@dptr,a");
1538 if (aop->type == AOP_DPTR2)
1546 while (offset > aop->coff) {
1548 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1550 while (offset < aop->coff) {
1552 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1558 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1563 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1565 if (strcmp(s,"r0") == 0 ||
1566 strcmp(s,"r1") == 0 ||
1567 strcmp(s,"r2") == 0 ||
1568 strcmp(s,"r3") == 0 ||
1569 strcmp(s,"r4") == 0 ||
1570 strcmp(s,"r5") == 0 ||
1571 strcmp(s,"r6") == 0 ||
1572 strcmp(s,"r7") == 0 ) {
1574 sprintf(buffer,"a%s",s);
1575 pic14_emitcode("mov","@%s,%s",
1576 aop->aopu.aop_ptr->name,buffer);
1578 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1583 if (strcmp(s,"a") == 0)
1584 pic14_emitcode("push","acc");
1586 pic14_emitcode("push","%s",s);
1591 /* if bit variable */
1592 if (!aop->aopu.aop_dir) {
1593 pic14_emitcode("clr","a");
1594 pic14_emitcode("rlc","a");
1597 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1600 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1603 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1605 lbl = newiTempLabel(NULL);
1607 if (strcmp(s,"a")) {
1610 pic14_emitcode("clr","c");
1611 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1612 pic14_emitcode("cpl","c");
1613 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1614 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1621 if (strcmp(aop->aopu.aop_str[offset],s))
1622 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1627 if (!offset && (strcmp(s,"acc") == 0))
1630 if (strcmp(aop->aopu.aop_str[offset],s))
1631 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1635 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1636 "aopPut got unsupported aop->type");
1642 /*-----------------------------------------------------------------*/
1643 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1644 /*-----------------------------------------------------------------*/
1645 void mov2w (asmop *aop, int offset)
1651 if ( aop->type == AOP_PCODE ||
1652 aop->type == AOP_LIT )
1653 emitpcode(POC_MOVLW,popGet(aop,offset));
1655 emitpcode(POC_MOVFW,popGet(aop,offset));
1659 /*-----------------------------------------------------------------*/
1660 /* reAdjustPreg - points a register back to where it should */
1661 /*-----------------------------------------------------------------*/
1662 static void reAdjustPreg (asmop *aop)
1666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1668 if ((size = aop->size) <= 1)
1671 switch (aop->type) {
1675 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1679 if (aop->type == AOP_DPTR2)
1685 pic14_emitcode("lcall","__decdptr");
1688 if (aop->type == AOP_DPTR2)
1698 /*-----------------------------------------------------------------*/
1699 /* genNotFloat - generates not for float operations */
1700 /*-----------------------------------------------------------------*/
1701 static void genNotFloat (operand *op, operand *res)
1707 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1708 /* we will put 127 in the first byte of
1710 aopPut(AOP(res),"#127",0);
1711 size = AOP_SIZE(op) - 1;
1714 l = aopGet(op->aop,offset++,FALSE,FALSE);
1718 pic14_emitcode("orl","a,%s",
1720 offset++,FALSE,FALSE));
1722 tlbl = newiTempLabel(NULL);
1724 tlbl = newiTempLabel(NULL);
1725 aopPut(res->aop,one,1);
1726 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1727 aopPut(res->aop,zero,1);
1728 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1730 size = res->aop->size - 2;
1732 /* put zeros in the rest */
1734 aopPut(res->aop,zero,offset++);
1738 /*-----------------------------------------------------------------*/
1739 /* opIsGptr: returns non-zero if the passed operand is */
1740 /* a generic pointer type. */
1741 /*-----------------------------------------------------------------*/
1742 static int opIsGptr(operand *op)
1744 sym_link *type = operandType(op);
1746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1747 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1755 /*-----------------------------------------------------------------*/
1756 /* pic14_getDataSize - get the operand data size */
1757 /*-----------------------------------------------------------------*/
1758 int pic14_getDataSize(operand *op)
1760 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1763 return AOP_SIZE(op);
1765 // tsd- in the pic port, the genptr size is 1, so this code here
1766 // fails. ( in the 8051 port, the size was 4).
1769 size = AOP_SIZE(op);
1770 if (size == GPTRSIZE)
1772 sym_link *type = operandType(op);
1773 if (IS_GENPTR(type))
1775 /* generic pointer; arithmetic operations
1776 * should ignore the high byte (pointer type).
1779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1786 /*-----------------------------------------------------------------*/
1787 /* pic14_outAcc - output Acc */
1788 /*-----------------------------------------------------------------*/
1789 void pic14_outAcc(operand *result)
1792 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1793 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1796 size = pic14_getDataSize(result);
1798 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1801 /* unsigned or positive */
1803 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1808 /*-----------------------------------------------------------------*/
1809 /* pic14_outBitC - output a bit C */
1810 /*-----------------------------------------------------------------*/
1811 void pic14_outBitC(operand *result)
1814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1815 /* if the result is bit */
1816 if (AOP_TYPE(result) == AOP_CRY)
1817 aopPut(AOP(result),"c",0);
1819 pic14_emitcode("clr","a ; %d", __LINE__);
1820 pic14_emitcode("rlc","a");
1821 pic14_outAcc(result);
1825 /*-----------------------------------------------------------------*/
1826 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1827 /*-----------------------------------------------------------------*/
1828 void pic14_toBoolean(operand *oper)
1830 int size = AOP_SIZE(oper) - 1;
1833 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1835 if ( AOP_TYPE(oper) != AOP_ACC) {
1836 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1839 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1844 /*-----------------------------------------------------------------*/
1845 /* genNot - generate code for ! operation */
1846 /*-----------------------------------------------------------------*/
1847 static void genNot (iCode *ic)
1850 sym_link *optype = operandType(IC_LEFT(ic));
1853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1854 /* assign asmOps to operand & result */
1855 aopOp (IC_LEFT(ic),ic,FALSE);
1856 aopOp (IC_RESULT(ic),ic,TRUE);
1858 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1859 /* if in bit space then a special case */
1860 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1861 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1862 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1863 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1865 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1866 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1867 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1872 /* if type float then do float */
1873 if (IS_FLOAT(optype)) {
1874 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1878 size = AOP_SIZE(IC_RESULT(ic));
1880 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1881 emitpcode(POC_ANDLW,popGetLit(1));
1882 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1885 pic14_toBoolean(IC_LEFT(ic));
1887 tlbl = newiTempLabel(NULL);
1888 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1889 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1890 pic14_outBitC(IC_RESULT(ic));
1893 /* release the aops */
1894 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1895 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1899 /*-----------------------------------------------------------------*/
1900 /* genCpl - generate code for complement */
1901 /*-----------------------------------------------------------------*/
1902 static void genCpl (iCode *ic)
1908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1909 /* assign asmOps to operand & result */
1910 aopOp (IC_LEFT(ic),ic,FALSE);
1911 aopOp (IC_RESULT(ic),ic,TRUE);
1913 /* if both are in bit space then
1915 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1916 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1918 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1919 pic14_emitcode("cpl","c");
1920 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1924 size = AOP_SIZE(IC_RESULT(ic));
1926 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1928 pic14_emitcode("cpl","a");
1929 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1934 /* release the aops */
1935 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1936 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1939 /*-----------------------------------------------------------------*/
1940 /* genUminusFloat - unary minus for floating points */
1941 /*-----------------------------------------------------------------*/
1942 static void genUminusFloat(operand *op,operand *result)
1944 int size ,offset =0 ;
1947 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1948 /* for this we just need to flip the
1949 first it then copy the rest in place */
1950 size = AOP_SIZE(op) - 1;
1951 l = aopGet(AOP(op),3,FALSE,FALSE);
1955 pic14_emitcode("cpl","acc.7");
1956 aopPut(AOP(result),"a",3);
1960 aopGet(AOP(op),offset,FALSE,FALSE),
1966 /*-----------------------------------------------------------------*/
1967 /* genUminus - unary minus code generation */
1968 /*-----------------------------------------------------------------*/
1969 static void genUminus (iCode *ic)
1972 sym_link *optype, *rtype;
1975 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1977 aopOp(IC_LEFT(ic),ic,FALSE);
1978 aopOp(IC_RESULT(ic),ic,TRUE);
1980 /* if both in bit space then special
1982 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1983 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1985 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1986 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1987 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1992 optype = operandType(IC_LEFT(ic));
1993 rtype = operandType(IC_RESULT(ic));
1995 /* if float then do float stuff */
1996 if (IS_FLOAT(optype)) {
1997 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2001 /* otherwise subtract from zero by taking the 2's complement */
2002 size = AOP_SIZE(IC_LEFT(ic));
2004 for(i=0; i<size; i++) {
2005 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2006 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2008 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2009 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2013 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2014 for(i=1; i<size; i++) {
2016 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2020 /* release the aops */
2021 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2022 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2025 /*-----------------------------------------------------------------*/
2026 /* saveRegisters - will look for a call and save the registers */
2027 /*-----------------------------------------------------------------*/
2028 static void saveRegisters(iCode *lic)
2035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2037 for (ic = lic ; ic ; ic = ic->next)
2038 if (ic->op == CALL || ic->op == PCALL)
2042 fprintf(stderr,"found parameter push with no function call\n");
2046 /* if the registers have been saved already then
2048 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2051 /* find the registers in use at this time
2052 and push them away to safety */
2053 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2057 if (options.useXstack) {
2058 if (bitVectBitValue(rsave,R0_IDX))
2059 pic14_emitcode("mov","b,r0");
2060 pic14_emitcode("mov","r0,%s",spname);
2061 for (i = 0 ; i < pic14_nRegs ; i++) {
2062 if (bitVectBitValue(rsave,i)) {
2064 pic14_emitcode("mov","a,b");
2066 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2067 pic14_emitcode("movx","@r0,a");
2068 pic14_emitcode("inc","r0");
2071 pic14_emitcode("mov","%s,r0",spname);
2072 if (bitVectBitValue(rsave,R0_IDX))
2073 pic14_emitcode("mov","r0,b");
2075 //for (i = 0 ; i < pic14_nRegs ; i++) {
2076 // if (bitVectBitValue(rsave,i))
2077 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2080 dtype = operandType(IC_LEFT(ic));
2081 if (currFunc && dtype &&
2082 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2083 IFFUNC_ISISR(currFunc->type) &&
2086 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2089 /*-----------------------------------------------------------------*/
2090 /* unsaveRegisters - pop the pushed registers */
2091 /*-----------------------------------------------------------------*/
2092 static void unsaveRegisters (iCode *ic)
2097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2098 /* find the registers in use at this time
2099 and push them away to safety */
2100 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2103 if (options.useXstack) {
2104 pic14_emitcode("mov","r0,%s",spname);
2105 for (i = pic14_nRegs ; i >= 0 ; i--) {
2106 if (bitVectBitValue(rsave,i)) {
2107 pic14_emitcode("dec","r0");
2108 pic14_emitcode("movx","a,@r0");
2110 pic14_emitcode("mov","b,a");
2112 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2116 pic14_emitcode("mov","%s,r0",spname);
2117 if (bitVectBitValue(rsave,R0_IDX))
2118 pic14_emitcode("mov","r0,b");
2120 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2121 // if (bitVectBitValue(rsave,i))
2122 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2128 /*-----------------------------------------------------------------*/
2130 /*-----------------------------------------------------------------*/
2131 static void pushSide(operand * oper, int size)
2135 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2137 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2138 if (AOP_TYPE(oper) != AOP_REG &&
2139 AOP_TYPE(oper) != AOP_DIR &&
2141 pic14_emitcode("mov","a,%s",l);
2142 pic14_emitcode("push","acc");
2144 pic14_emitcode("push","%s",l);
2149 /*-----------------------------------------------------------------*/
2150 /* assignResultValue - */
2151 /*-----------------------------------------------------------------*/
2152 static void assignResultValue(operand * oper)
2154 int size = AOP_SIZE(oper);
2156 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2158 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2160 if(!GpsuedoStkPtr) {
2161 /* The last byte in the assignment is in W */
2163 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2168 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2170 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2175 /*-----------------------------------------------------------------*/
2176 /* genIpush - genrate code for pushing this gets a little complex */
2177 /*-----------------------------------------------------------------*/
2178 static void genIpush (iCode *ic)
2181 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2183 int size, offset = 0 ;
2187 /* if this is not a parm push : ie. it is spill push
2188 and spill push is always done on the local stack */
2189 if (!ic->parmPush) {
2191 /* and the item is spilt then do nothing */
2192 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2195 aopOp(IC_LEFT(ic),ic,FALSE);
2196 size = AOP_SIZE(IC_LEFT(ic));
2197 /* push it on the stack */
2199 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2204 pic14_emitcode("push","%s",l);
2209 /* this is a paramter push: in this case we call
2210 the routine to find the call and save those
2211 registers that need to be saved */
2214 /* then do the push */
2215 aopOp(IC_LEFT(ic),ic,FALSE);
2218 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2219 size = AOP_SIZE(IC_LEFT(ic));
2222 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2223 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2224 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2226 pic14_emitcode("mov","a,%s",l);
2227 pic14_emitcode("push","acc");
2229 pic14_emitcode("push","%s",l);
2232 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2236 /*-----------------------------------------------------------------*/
2237 /* genIpop - recover the registers: can happen only for spilling */
2238 /*-----------------------------------------------------------------*/
2239 static void genIpop (iCode *ic)
2241 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2246 /* if the temp was not pushed then */
2247 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2250 aopOp(IC_LEFT(ic),ic,FALSE);
2251 size = AOP_SIZE(IC_LEFT(ic));
2254 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2257 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2261 /*-----------------------------------------------------------------*/
2262 /* unsaverbank - restores the resgister bank from stack */
2263 /*-----------------------------------------------------------------*/
2264 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2266 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2274 if (options.useXstack) {
2276 r = getFreePtr(ic,&aop,FALSE);
2279 pic14_emitcode("mov","%s,_spx",r->name);
2280 pic14_emitcode("movx","a,@%s",r->name);
2281 pic14_emitcode("mov","psw,a");
2282 pic14_emitcode("dec","%s",r->name);
2285 pic14_emitcode ("pop","psw");
2288 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2289 if (options.useXstack) {
2290 pic14_emitcode("movx","a,@%s",r->name);
2291 //pic14_emitcode("mov","(%s+%d),a",
2292 // regspic14[i].base,8*bank+regspic14[i].offset);
2293 pic14_emitcode("dec","%s",r->name);
2296 pic14_emitcode("pop",""); //"(%s+%d)",
2297 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2300 if (options.useXstack) {
2302 pic14_emitcode("mov","_spx,%s",r->name);
2303 freeAsmop(NULL,aop,ic,TRUE);
2309 /*-----------------------------------------------------------------*/
2310 /* saverbank - saves an entire register bank on the stack */
2311 /*-----------------------------------------------------------------*/
2312 static void saverbank (int bank, iCode *ic, bool pushPsw)
2314 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2321 if (options.useXstack) {
2324 r = getFreePtr(ic,&aop,FALSE);
2325 pic14_emitcode("mov","%s,_spx",r->name);
2329 for (i = 0 ; i < pic14_nRegs ;i++) {
2330 if (options.useXstack) {
2331 pic14_emitcode("inc","%s",r->name);
2332 //pic14_emitcode("mov","a,(%s+%d)",
2333 // regspic14[i].base,8*bank+regspic14[i].offset);
2334 pic14_emitcode("movx","@%s,a",r->name);
2336 pic14_emitcode("push","");// "(%s+%d)",
2337 //regspic14[i].base,8*bank+regspic14[i].offset);
2341 if (options.useXstack) {
2342 pic14_emitcode("mov","a,psw");
2343 pic14_emitcode("movx","@%s,a",r->name);
2344 pic14_emitcode("inc","%s",r->name);
2345 pic14_emitcode("mov","_spx,%s",r->name);
2346 freeAsmop (NULL,aop,ic,TRUE);
2349 pic14_emitcode("push","psw");
2351 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2357 /*-----------------------------------------------------------------*/
2358 /* genCall - generates a call statement */
2359 /*-----------------------------------------------------------------*/
2360 static void genCall (iCode *ic)
2364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2366 /* if caller saves & we have not saved then */
2370 /* if we are calling a function that is not using
2371 the same register bank then we need to save the
2372 destination registers on the stack */
2373 dtype = operandType(IC_LEFT(ic));
2374 if (currFunc && dtype &&
2375 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2376 IFFUNC_ISISR(currFunc->type) &&
2379 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2381 /* if send set is not empty the assign */
2384 /* For the Pic port, there is no data stack.
2385 * So parameters passed to functions are stored
2386 * in registers. (The pCode optimizer will get
2387 * rid of most of these :).
2389 int psuedoStkPtr=-1;
2390 int firstTimeThruLoop = 1;
2392 _G.sendSet = reverseSet(_G.sendSet);
2394 /* First figure how many parameters are getting passed */
2395 for (sic = setFirstItem(_G.sendSet) ; sic ;
2396 sic = setNextItem(_G.sendSet)) {
2398 aopOp(IC_LEFT(sic),sic,FALSE);
2399 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2400 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2403 for (sic = setFirstItem(_G.sendSet) ; sic ;
2404 sic = setNextItem(_G.sendSet)) {
2405 int size, offset = 0;
2407 aopOp(IC_LEFT(sic),sic,FALSE);
2408 size = AOP_SIZE(IC_LEFT(sic));
2411 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2412 AopType(AOP_TYPE(IC_LEFT(sic))));
2414 if(!firstTimeThruLoop) {
2415 /* If this is not the first time we've been through the loop
2416 * then we need to save the parameter in a temporary
2417 * register. The last byte of the last parameter is
2419 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2422 firstTimeThruLoop=0;
2424 //if (strcmp(l,fReturn[offset])) {
2425 mov2w (AOP(IC_LEFT(sic)), offset);
2427 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2428 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2429 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2431 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2436 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2441 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2442 OP_SYMBOL(IC_LEFT(ic))->rname :
2443 OP_SYMBOL(IC_LEFT(ic))->name));
2446 /* if we need assign a result value */
2447 if ((IS_ITEMP(IC_RESULT(ic)) &&
2448 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2449 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2450 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2453 aopOp(IC_RESULT(ic),ic,FALSE);
2456 assignResultValue(IC_RESULT(ic));
2458 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2459 AopType(AOP_TYPE(IC_RESULT(ic))));
2461 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2464 /* adjust the stack for parameters if
2466 if (ic->parmBytes) {
2468 if (ic->parmBytes > 3) {
2469 pic14_emitcode("mov","a,%s",spname);
2470 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2471 pic14_emitcode("mov","%s,a",spname);
2473 for ( i = 0 ; i < ic->parmBytes ;i++)
2474 pic14_emitcode("dec","%s",spname);
2478 /* if register bank was saved then pop them */
2480 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2482 /* if we hade saved some registers then unsave them */
2483 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2484 unsaveRegisters (ic);
2489 /*-----------------------------------------------------------------*/
2490 /* genPcall - generates a call by pointer statement */
2491 /*-----------------------------------------------------------------*/
2492 static void genPcall (iCode *ic)
2495 symbol *rlbl = newiTempLabel(NULL);
2498 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2499 /* if caller saves & we have not saved then */
2503 /* if we are calling a function that is not using
2504 the same register bank then we need to save the
2505 destination registers on the stack */
2506 dtype = operandType(IC_LEFT(ic));
2507 if (currFunc && dtype &&
2508 IFFUNC_ISISR(currFunc->type) &&
2509 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2510 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2513 /* push the return address on to the stack */
2514 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2515 pic14_emitcode("push","acc");
2516 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2517 pic14_emitcode("push","acc");
2519 if (options.model == MODEL_FLAT24)
2521 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2522 pic14_emitcode("push","acc");
2525 /* now push the calling address */
2526 aopOp(IC_LEFT(ic),ic,FALSE);
2528 pushSide(IC_LEFT(ic), FPTRSIZE);
2530 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2532 /* if send set is not empty the assign */
2536 for (sic = setFirstItem(_G.sendSet) ; sic ;
2537 sic = setNextItem(_G.sendSet)) {
2538 int size, offset = 0;
2539 aopOp(IC_LEFT(sic),sic,FALSE);
2540 size = AOP_SIZE(IC_LEFT(sic));
2542 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2544 if (strcmp(l,fReturn[offset]))
2545 pic14_emitcode("mov","%s,%s",
2550 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2555 pic14_emitcode("ret","");
2556 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2559 /* if we need assign a result value */
2560 if ((IS_ITEMP(IC_RESULT(ic)) &&
2561 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2562 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2563 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2566 aopOp(IC_RESULT(ic),ic,FALSE);
2569 assignResultValue(IC_RESULT(ic));
2571 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2574 /* adjust the stack for parameters if
2576 if (ic->parmBytes) {
2578 if (ic->parmBytes > 3) {
2579 pic14_emitcode("mov","a,%s",spname);
2580 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2581 pic14_emitcode("mov","%s,a",spname);
2583 for ( i = 0 ; i < ic->parmBytes ;i++)
2584 pic14_emitcode("dec","%s",spname);
2588 /* if register bank was saved then unsave them */
2589 if (currFunc && dtype &&
2590 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2591 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2593 /* if we hade saved some registers then
2596 unsaveRegisters (ic);
2600 /*-----------------------------------------------------------------*/
2601 /* resultRemat - result is rematerializable */
2602 /*-----------------------------------------------------------------*/
2603 static int resultRemat (iCode *ic)
2605 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2606 if (SKIP_IC(ic) || ic->op == IFX)
2609 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2610 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2611 if (sym->remat && !POINTER_SET(ic))
2618 #if defined(__BORLANDC__) || defined(_MSC_VER)
2619 #define STRCASECMP stricmp
2621 #define STRCASECMP strcasecmp
2625 /*-----------------------------------------------------------------*/
2626 /* inExcludeList - return 1 if the string is in exclude Reg list */
2627 /*-----------------------------------------------------------------*/
2628 static bool inExcludeList(char *s)
2630 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2634 if (options.excludeRegs[i] &&
2635 STRCASECMP(options.excludeRegs[i],"none") == 0)
2638 for ( i = 0 ; options.excludeRegs[i]; i++) {
2639 if (options.excludeRegs[i] &&
2640 STRCASECMP(s,options.excludeRegs[i]) == 0)
2647 /*-----------------------------------------------------------------*/
2648 /* genFunction - generated code for function entry */
2649 /*-----------------------------------------------------------------*/
2650 static void genFunction (iCode *ic)
2655 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2657 labelOffset += (max_key+4);
2661 /* create the function header */
2662 pic14_emitcode(";","-----------------------------------------");
2663 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2664 pic14_emitcode(";","-----------------------------------------");
2666 pic14_emitcode("","%s:",sym->rname);
2667 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2669 ftype = operandType(IC_LEFT(ic));
2671 /* if critical function then turn interrupts off */
2672 if (IFFUNC_ISCRITICAL(ftype))
2673 pic14_emitcode("clr","ea");
2675 /* here we need to generate the equates for the
2676 register bank if required */
2678 if (FUNC_REGBANK(ftype) != rbank) {
2681 rbank = FUNC_REGBANK(ftype);
2682 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2683 if (strcmp(regspic14[i].base,"0") == 0)
2684 pic14_emitcode("","%s = 0x%02x",
2686 8*rbank+regspic14[i].offset);
2688 pic14_emitcode ("","%s = %s + 0x%02x",
2691 8*rbank+regspic14[i].offset);
2696 /* if this is an interrupt service routine then
2697 save acc, b, dpl, dph */
2698 if (IFFUNC_ISISR(sym->type)) {
2699 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2700 emitpcodeNULLop(POC_NOP);
2701 emitpcodeNULLop(POC_NOP);
2702 emitpcodeNULLop(POC_NOP);
2703 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2704 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2705 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2706 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2708 pBlockConvert2ISR(pb);
2710 if (!inExcludeList("acc"))
2711 pic14_emitcode ("push","acc");
2712 if (!inExcludeList("b"))
2713 pic14_emitcode ("push","b");
2714 if (!inExcludeList("dpl"))
2715 pic14_emitcode ("push","dpl");
2716 if (!inExcludeList("dph"))
2717 pic14_emitcode ("push","dph");
2718 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2720 pic14_emitcode ("push", "dpx");
2721 /* Make sure we're using standard DPTR */
2722 pic14_emitcode ("push", "dps");
2723 pic14_emitcode ("mov", "dps, #0x00");
2724 if (options.stack10bit)
2726 /* This ISR could conceivably use DPTR2. Better save it. */
2727 pic14_emitcode ("push", "dpl1");
2728 pic14_emitcode ("push", "dph1");
2729 pic14_emitcode ("push", "dpx1");
2732 /* if this isr has no bank i.e. is going to
2733 run with bank 0 , then we need to save more
2735 if (!FUNC_REGBANK(sym->type)) {
2737 /* if this function does not call any other
2738 function then we can be economical and
2739 save only those registers that are used */
2740 if (! IFFUNC_HASFCALL(sym->type)) {
2743 /* if any registers used */
2744 if (sym->regsUsed) {
2745 /* save the registers used */
2746 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2747 if (bitVectBitValue(sym->regsUsed,i) ||
2748 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2749 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2754 /* this function has a function call cannot
2755 determines register usage so we will have the
2757 saverbank(0,ic,FALSE);
2762 /* if callee-save to be used for this function
2763 then save the registers being used in this function */
2764 if (IFFUNC_CALLEESAVES(sym->type)) {
2767 /* if any registers used */
2768 if (sym->regsUsed) {
2769 /* save the registers used */
2770 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2771 if (bitVectBitValue(sym->regsUsed,i) ||
2772 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2773 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2781 /* set the register bank to the desired value */
2782 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2783 pic14_emitcode("push","psw");
2784 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2787 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2789 if (options.useXstack) {
2790 pic14_emitcode("mov","r0,%s",spname);
2791 pic14_emitcode("mov","a,_bp");
2792 pic14_emitcode("movx","@r0,a");
2793 pic14_emitcode("inc","%s",spname);
2797 /* set up the stack */
2798 pic14_emitcode ("push","_bp"); /* save the callers stack */
2800 pic14_emitcode ("mov","_bp,%s",spname);
2803 /* adjust the stack for the function */
2808 werror(W_STACK_OVERFLOW,sym->name);
2810 if (i > 3 && sym->recvSize < 4) {
2812 pic14_emitcode ("mov","a,sp");
2813 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2814 pic14_emitcode ("mov","sp,a");
2819 pic14_emitcode("inc","sp");
2824 pic14_emitcode ("mov","a,_spx");
2825 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2826 pic14_emitcode ("mov","_spx,a");
2831 /*-----------------------------------------------------------------*/
2832 /* genEndFunction - generates epilogue for functions */
2833 /*-----------------------------------------------------------------*/
2834 static void genEndFunction (iCode *ic)
2836 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2838 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2840 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2842 pic14_emitcode ("mov","%s,_bp",spname);
2845 /* if use external stack but some variables were
2846 added to the local stack then decrement the
2848 if (options.useXstack && sym->stack) {
2849 pic14_emitcode("mov","a,sp");
2850 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2851 pic14_emitcode("mov","sp,a");
2855 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2856 if (options.useXstack) {
2857 pic14_emitcode("mov","r0,%s",spname);
2858 pic14_emitcode("movx","a,@r0");
2859 pic14_emitcode("mov","_bp,a");
2860 pic14_emitcode("dec","%s",spname);
2864 pic14_emitcode ("pop","_bp");
2868 /* restore the register bank */
2869 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2870 pic14_emitcode ("pop","psw");
2872 if (IFFUNC_ISISR(sym->type)) {
2874 /* now we need to restore the registers */
2875 /* if this isr has no bank i.e. is going to
2876 run with bank 0 , then we need to save more
2878 if (!FUNC_REGBANK(sym->type)) {
2880 /* if this function does not call any other
2881 function then we can be economical and
2882 save only those registers that are used */
2883 if (! IFFUNC_HASFCALL(sym->type)) {
2886 /* if any registers used */
2887 if (sym->regsUsed) {
2888 /* save the registers used */
2889 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2890 if (bitVectBitValue(sym->regsUsed,i) ||
2891 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2892 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2897 /* this function has a function call cannot
2898 determines register usage so we will have the
2900 unsaverbank(0,ic,FALSE);
2904 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2906 if (options.stack10bit)
2908 pic14_emitcode ("pop", "dpx1");
2909 pic14_emitcode ("pop", "dph1");
2910 pic14_emitcode ("pop", "dpl1");
2912 pic14_emitcode ("pop", "dps");
2913 pic14_emitcode ("pop", "dpx");
2915 if (!inExcludeList("dph"))
2916 pic14_emitcode ("pop","dph");
2917 if (!inExcludeList("dpl"))
2918 pic14_emitcode ("pop","dpl");
2919 if (!inExcludeList("b"))
2920 pic14_emitcode ("pop","b");
2921 if (!inExcludeList("acc"))
2922 pic14_emitcode ("pop","acc");
2924 if (IFFUNC_ISCRITICAL(sym->type))
2925 pic14_emitcode("setb","ea");
2928 /* if debug then send end of function */
2929 /* if (options.debug && currFunc) { */
2932 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2933 FileBaseName(ic->filename),currFunc->lastLine,
2934 ic->level,ic->block);
2935 if (IS_STATIC(currFunc->etype))
2936 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2938 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2942 pic14_emitcode ("reti","");
2944 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2945 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2946 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2947 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2948 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2949 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2951 emitpcodeNULLop(POC_RETFIE);
2955 if (IFFUNC_ISCRITICAL(sym->type))
2956 pic14_emitcode("setb","ea");
2958 if (IFFUNC_CALLEESAVES(sym->type)) {
2961 /* if any registers used */
2962 if (sym->regsUsed) {
2963 /* save the registers used */
2964 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2965 if (bitVectBitValue(sym->regsUsed,i) ||
2966 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2967 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2973 /* if debug then send end of function */
2976 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2977 FileBaseName(ic->filename),currFunc->lastLine,
2978 ic->level,ic->block);
2979 if (IS_STATIC(currFunc->etype))
2980 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2982 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2986 pic14_emitcode ("return","");
2987 emitpcodeNULLop(POC_RETURN);
2989 /* Mark the end of a function */
2990 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2995 /*-----------------------------------------------------------------*/
2996 /* genRet - generate code for return statement */
2997 /*-----------------------------------------------------------------*/
2998 static void genRet (iCode *ic)
3000 int size,offset = 0 , pushed = 0;
3002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3003 /* if we have no return value then
3004 just generate the "ret" */
3008 /* we have something to return then
3009 move the return value into place */
3010 aopOp(IC_LEFT(ic),ic,FALSE);
3011 size = AOP_SIZE(IC_LEFT(ic));
3015 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3017 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3019 pic14_emitcode("push","%s",l);
3022 l = aopGet(AOP(IC_LEFT(ic)),offset,
3024 if (strcmp(fReturn[offset],l)) {
3025 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3026 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3027 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3029 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3032 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3042 if (strcmp(fReturn[pushed],"a"))
3043 pic14_emitcode("pop",fReturn[pushed]);
3045 pic14_emitcode("pop","acc");
3048 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3051 /* generate a jump to the return label
3052 if the next is not the return statement */
3053 if (!(ic->next && ic->next->op == LABEL &&
3054 IC_LABEL(ic->next) == returnLabel)) {
3056 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3057 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3062 /*-----------------------------------------------------------------*/
3063 /* genLabel - generates a label */
3064 /*-----------------------------------------------------------------*/
3065 static void genLabel (iCode *ic)
3067 /* special case never generate */
3068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3069 if (IC_LABEL(ic) == entryLabel)
3072 emitpLabel(IC_LABEL(ic)->key);
3073 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3076 /*-----------------------------------------------------------------*/
3077 /* genGoto - generates a goto */
3078 /*-----------------------------------------------------------------*/
3080 static void genGoto (iCode *ic)
3082 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3083 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3087 /*-----------------------------------------------------------------*/
3088 /* genMultbits :- multiplication of bits */
3089 /*-----------------------------------------------------------------*/
3090 static void genMultbits (operand *left,
3094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3096 if(!pic14_sameRegs(AOP(result),AOP(right)))
3097 emitpcode(POC_BSF, popGet(AOP(result),0));
3099 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3100 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3101 emitpcode(POC_BCF, popGet(AOP(result),0));
3106 /*-----------------------------------------------------------------*/
3107 /* genMultOneByte : 8 bit multiplication & division */
3108 /*-----------------------------------------------------------------*/
3109 static void genMultOneByte (operand *left,
3113 sym_link *opetype = operandType(result);
3118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3119 DEBUGpic14_AopType(__LINE__,left,right,result);
3120 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3122 /* (if two literals, the value is computed before) */
3123 /* if one literal, literal on the right */
3124 if (AOP_TYPE(left) == AOP_LIT){
3130 size = AOP_SIZE(result);
3133 if (AOP_TYPE(right) == AOP_LIT){
3134 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3135 aopGet(AOP(right),0,FALSE,FALSE),
3136 aopGet(AOP(left),0,FALSE,FALSE),
3137 aopGet(AOP(result),0,FALSE,FALSE));
3138 pic14_emitcode("call","genMultLit");
3140 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3141 aopGet(AOP(right),0,FALSE,FALSE),
3142 aopGet(AOP(left),0,FALSE,FALSE),
3143 aopGet(AOP(result),0,FALSE,FALSE));
3144 pic14_emitcode("call","genMult8X8_8");
3147 genMult8X8_8 (left, right,result);
3150 /* signed or unsigned */
3151 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3152 //l = aopGet(AOP(left),0,FALSE,FALSE);
3154 //pic14_emitcode("mul","ab");
3155 /* if result size = 1, mul signed = mul unsigned */
3156 //aopPut(AOP(result),"a",0);
3158 } else { // (size > 1)
3160 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3161 aopGet(AOP(right),0,FALSE,FALSE),
3162 aopGet(AOP(left),0,FALSE,FALSE),
3163 aopGet(AOP(result),0,FALSE,FALSE));
3165 if (SPEC_USIGN(opetype)){
3166 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3167 genUMult8X8_16 (left, right, result, NULL);
3170 /* for filling the MSBs */
3171 emitpcode(POC_CLRF, popGet(AOP(result),2));
3172 emitpcode(POC_CLRF, popGet(AOP(result),3));
3176 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3178 pic14_emitcode("mov","a,b");
3180 /* adjust the MSB if left or right neg */
3182 /* if one literal */
3183 if (AOP_TYPE(right) == AOP_LIT){
3184 pic14_emitcode("multiply ","right is a lit");
3185 /* AND literal negative */
3186 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3187 /* adjust MSB (c==0 after mul) */
3188 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3192 genSMult8X8_16 (left, right, result, NULL);
3196 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3198 pic14_emitcode("rlc","a");
3199 pic14_emitcode("subb","a,acc");
3207 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3208 //aopPut(AOP(result),"a",offset++);
3212 /*-----------------------------------------------------------------*/
3213 /* genMult - generates code for multiplication */
3214 /*-----------------------------------------------------------------*/
3215 static void genMult (iCode *ic)
3217 operand *left = IC_LEFT(ic);
3218 operand *right = IC_RIGHT(ic);
3219 operand *result= IC_RESULT(ic);
3221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3222 /* assign the amsops */
3223 aopOp (left,ic,FALSE);
3224 aopOp (right,ic,FALSE);
3225 aopOp (result,ic,TRUE);
3227 DEBUGpic14_AopType(__LINE__,left,right,result);
3229 /* special cases first */
3231 if (AOP_TYPE(left) == AOP_CRY &&
3232 AOP_TYPE(right)== AOP_CRY) {
3233 genMultbits(left,right,result);
3237 /* if both are of size == 1 */
3238 if (AOP_SIZE(left) == 1 &&
3239 AOP_SIZE(right) == 1 ) {
3240 genMultOneByte(left,right,result);
3244 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3246 /* should have been converted to function call */
3250 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3251 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3252 freeAsmop(result,NULL,ic,TRUE);
3255 /*-----------------------------------------------------------------*/
3256 /* genDivbits :- division of bits */
3257 /*-----------------------------------------------------------------*/
3258 static void genDivbits (operand *left,
3265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3266 /* the result must be bit */
3267 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3268 l = aopGet(AOP(left),0,FALSE,FALSE);
3272 pic14_emitcode("div","ab");
3273 pic14_emitcode("rrc","a");
3274 aopPut(AOP(result),"c",0);
3277 /*-----------------------------------------------------------------*/
3278 /* genDivOneByte : 8 bit division */
3279 /*-----------------------------------------------------------------*/
3280 static void genDivOneByte (operand *left,
3284 sym_link *opetype = operandType(result);
3289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3290 size = AOP_SIZE(result) - 1;
3292 /* signed or unsigned */
3293 if (SPEC_USIGN(opetype)) {
3294 /* unsigned is easy */
3295 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3296 l = aopGet(AOP(left),0,FALSE,FALSE);
3298 pic14_emitcode("div","ab");
3299 aopPut(AOP(result),"a",0);
3301 aopPut(AOP(result),zero,offset++);
3305 /* signed is a little bit more difficult */
3307 /* save the signs of the operands */
3308 l = aopGet(AOP(left),0,FALSE,FALSE);
3310 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3311 pic14_emitcode("push","acc"); /* save it on the stack */
3313 /* now sign adjust for both left & right */
3314 l = aopGet(AOP(right),0,FALSE,FALSE);
3316 lbl = newiTempLabel(NULL);
3317 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3318 pic14_emitcode("cpl","a");
3319 pic14_emitcode("inc","a");
3320 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3321 pic14_emitcode("mov","b,a");
3323 /* sign adjust left side */
3324 l = aopGet(AOP(left),0,FALSE,FALSE);
3327 lbl = newiTempLabel(NULL);
3328 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3329 pic14_emitcode("cpl","a");
3330 pic14_emitcode("inc","a");
3331 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3333 /* now the division */
3334 pic14_emitcode("div","ab");
3335 /* we are interested in the lower order
3337 pic14_emitcode("mov","b,a");
3338 lbl = newiTempLabel(NULL);
3339 pic14_emitcode("pop","acc");
3340 /* if there was an over flow we don't
3341 adjust the sign of the result */
3342 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3343 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3345 pic14_emitcode("clr","a");
3346 pic14_emitcode("subb","a,b");
3347 pic14_emitcode("mov","b,a");
3348 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3350 /* now we are done */
3351 aopPut(AOP(result),"b",0);
3353 pic14_emitcode("mov","c,b.7");
3354 pic14_emitcode("subb","a,acc");
3357 aopPut(AOP(result),"a",offset++);
3361 /*-----------------------------------------------------------------*/
3362 /* genDiv - generates code for division */
3363 /*-----------------------------------------------------------------*/
3364 static void genDiv (iCode *ic)
3366 operand *left = IC_LEFT(ic);
3367 operand *right = IC_RIGHT(ic);
3368 operand *result= IC_RESULT(ic);
3370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3371 /* assign the amsops */
3372 aopOp (left,ic,FALSE);
3373 aopOp (right,ic,FALSE);
3374 aopOp (result,ic,TRUE);
3376 /* special cases first */
3378 if (AOP_TYPE(left) == AOP_CRY &&
3379 AOP_TYPE(right)== AOP_CRY) {
3380 genDivbits(left,right,result);
3384 /* if both are of size == 1 */
3385 if (AOP_SIZE(left) == 1 &&
3386 AOP_SIZE(right) == 1 ) {
3387 genDivOneByte(left,right,result);
3391 /* should have been converted to function call */
3394 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3395 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3396 freeAsmop(result,NULL,ic,TRUE);
3399 /*-----------------------------------------------------------------*/
3400 /* genModbits :- modulus of bits */
3401 /*-----------------------------------------------------------------*/
3402 static void genModbits (operand *left,
3409 /* the result must be bit */
3410 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3411 l = aopGet(AOP(left),0,FALSE,FALSE);
3415 pic14_emitcode("div","ab");
3416 pic14_emitcode("mov","a,b");
3417 pic14_emitcode("rrc","a");
3418 aopPut(AOP(result),"c",0);
3421 /*-----------------------------------------------------------------*/
3422 /* genModOneByte : 8 bit modulus */
3423 /*-----------------------------------------------------------------*/
3424 static void genModOneByte (operand *left,
3428 sym_link *opetype = operandType(result);
3432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3433 /* signed or unsigned */
3434 if (SPEC_USIGN(opetype)) {
3435 /* unsigned is easy */
3436 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3437 l = aopGet(AOP(left),0,FALSE,FALSE);
3439 pic14_emitcode("div","ab");
3440 aopPut(AOP(result),"b",0);
3444 /* signed is a little bit more difficult */
3446 /* save the signs of the operands */
3447 l = aopGet(AOP(left),0,FALSE,FALSE);
3450 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3451 pic14_emitcode("push","acc"); /* save it on the stack */
3453 /* now sign adjust for both left & right */
3454 l = aopGet(AOP(right),0,FALSE,FALSE);
3457 lbl = newiTempLabel(NULL);
3458 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3459 pic14_emitcode("cpl","a");
3460 pic14_emitcode("inc","a");
3461 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3462 pic14_emitcode("mov","b,a");
3464 /* sign adjust left side */
3465 l = aopGet(AOP(left),0,FALSE,FALSE);
3468 lbl = newiTempLabel(NULL);
3469 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3470 pic14_emitcode("cpl","a");
3471 pic14_emitcode("inc","a");
3472 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3474 /* now the multiplication */
3475 pic14_emitcode("div","ab");
3476 /* we are interested in the lower order
3478 lbl = newiTempLabel(NULL);
3479 pic14_emitcode("pop","acc");
3480 /* if there was an over flow we don't
3481 adjust the sign of the result */
3482 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3483 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3485 pic14_emitcode("clr","a");
3486 pic14_emitcode("subb","a,b");
3487 pic14_emitcode("mov","b,a");
3488 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3490 /* now we are done */
3491 aopPut(AOP(result),"b",0);
3495 /*-----------------------------------------------------------------*/
3496 /* genMod - generates code for division */
3497 /*-----------------------------------------------------------------*/
3498 static void genMod (iCode *ic)
3500 operand *left = IC_LEFT(ic);
3501 operand *right = IC_RIGHT(ic);
3502 operand *result= IC_RESULT(ic);
3504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3505 /* assign the amsops */
3506 aopOp (left,ic,FALSE);
3507 aopOp (right,ic,FALSE);
3508 aopOp (result,ic,TRUE);
3510 /* special cases first */
3512 if (AOP_TYPE(left) == AOP_CRY &&
3513 AOP_TYPE(right)== AOP_CRY) {
3514 genModbits(left,right,result);
3518 /* if both are of size == 1 */
3519 if (AOP_SIZE(left) == 1 &&
3520 AOP_SIZE(right) == 1 ) {
3521 genModOneByte(left,right,result);
3525 /* should have been converted to function call */
3529 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3530 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3531 freeAsmop(result,NULL,ic,TRUE);
3534 /*-----------------------------------------------------------------*/
3535 /* genIfxJump :- will create a jump depending on the ifx */
3536 /*-----------------------------------------------------------------*/
3538 note: May need to add parameter to indicate when a variable is in bit space.
3540 static void genIfxJump (iCode *ic, char *jval)
3543 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3544 /* if true label then we jump if condition
3546 if ( IC_TRUE(ic) ) {
3548 if(strcmp(jval,"a") == 0)
3550 else if (strcmp(jval,"c") == 0)
3553 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3554 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3557 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3558 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3562 /* false label is present */
3563 if(strcmp(jval,"a") == 0)
3565 else if (strcmp(jval,"c") == 0)
3568 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3569 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3572 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3573 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3578 /* mark the icode as generated */
3582 /*-----------------------------------------------------------------*/
3584 /*-----------------------------------------------------------------*/
3585 static void genSkip(iCode *ifx,int status_bit)
3590 if ( IC_TRUE(ifx) ) {
3591 switch(status_bit) {
3606 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3607 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3611 switch(status_bit) {
3625 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3626 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3632 /*-----------------------------------------------------------------*/
3634 /*-----------------------------------------------------------------*/
3635 static void genSkipc(resolvedIfx *rifx)
3645 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3646 rifx->generated = 1;
3649 /*-----------------------------------------------------------------*/
3651 /*-----------------------------------------------------------------*/
3652 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3657 if( (rifx->condition ^ invert_condition) & 1)
3662 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3663 rifx->generated = 1;
3666 /*-----------------------------------------------------------------*/
3668 /*-----------------------------------------------------------------*/
3669 static void genSkipz(iCode *ifx, int condition)
3680 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3682 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3685 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3687 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3690 /*-----------------------------------------------------------------*/
3692 /*-----------------------------------------------------------------*/
3693 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3699 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3701 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3704 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3705 rifx->generated = 1;
3709 /*-----------------------------------------------------------------*/
3710 /* genChkZeroes :- greater or less than comparison */
3711 /* For each byte in a literal that is zero, inclusive or the */
3712 /* the corresponding byte in the operand with W */
3713 /* returns true if any of the bytes are zero */
3714 /*-----------------------------------------------------------------*/
3715 static int genChkZeroes(operand *op, int lit, int size)
3722 i = (lit >> (size*8)) & 0xff;
3726 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3728 emitpcode(POC_IORFW, popGet(AOP(op),size));
3737 /*-----------------------------------------------------------------*/
3738 /* genCmp :- greater or less than comparison */
3739 /*-----------------------------------------------------------------*/
3740 static void genCmp (operand *left,operand *right,
3741 operand *result, iCode *ifx, int sign)
3743 int size; //, offset = 0 ;
3744 unsigned long lit = 0L,i = 0;
3745 resolvedIfx rFalseIfx;
3746 // resolvedIfx rTrueIfx;
3748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3750 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3751 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3755 resolveIfx(&rFalseIfx,ifx);
3756 truelbl = newiTempLabel(NULL);
3757 size = max(AOP_SIZE(left),AOP_SIZE(right));
3761 /* if literal is on the right then swap with left */
3762 if ((AOP_TYPE(right) == AOP_LIT)) {
3763 operand *tmp = right ;
3764 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3765 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3767 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
3768 lit = (lit - 1) & mask;
3769 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
3773 rFalseIfx.condition ^= 1;
3776 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3777 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3781 //if(IC_TRUE(ifx) == NULL)
3782 /* if left & right are bit variables */
3783 if (AOP_TYPE(left) == AOP_CRY &&
3784 AOP_TYPE(right) == AOP_CRY ) {
3785 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3786 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3788 /* subtract right from left if at the
3789 end the carry flag is set then we know that
3790 left is greater than right */
3794 symbol *lbl = newiTempLabel(NULL);
3797 if(AOP_TYPE(right) == AOP_LIT) {
3799 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3801 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3808 genSkipCond(&rFalseIfx,left,size-1,7);
3810 /* no need to compare to 0...*/
3811 /* NOTE: this is a de-generate compare that most certainly
3812 * creates some dead code. */
3813 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3815 if(ifx) ifx->generated = 1;
3822 //i = (lit >> (size*8)) & 0xff;
3823 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3825 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3827 i = ((0-lit) & 0xff);
3830 /* lit is 0x7f, all signed chars are less than
3831 * this except for 0x7f itself */
3832 emitpcode(POC_XORLW, popGetLit(0x7f));
3833 genSkipz2(&rFalseIfx,0);
3835 emitpcode(POC_ADDLW, popGetLit(0x80));
3836 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3837 genSkipc(&rFalseIfx);
3842 genSkipz2(&rFalseIfx,1);
3844 emitpcode(POC_ADDLW, popGetLit(i));
3845 genSkipc(&rFalseIfx);
3849 if(ifx) ifx->generated = 1;
3853 /* chars are out of the way. now do ints and longs */
3856 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3863 genSkipCond(&rFalseIfx,left,size,7);
3864 if(ifx) ifx->generated = 1;
3869 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3871 //rFalseIfx.condition ^= 1;
3872 //genSkipCond(&rFalseIfx,left,size,7);
3873 //rFalseIfx.condition ^= 1;
3875 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3876 if(rFalseIfx.condition)
3877 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3879 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3881 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3882 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3883 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3886 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3888 if(rFalseIfx.condition) {
3890 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3896 genSkipc(&rFalseIfx);
3897 emitpLabel(truelbl->key);
3898 if(ifx) ifx->generated = 1;
3905 if( (lit & 0xff) == 0) {
3906 /* lower byte is zero */
3907 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3908 i = ((lit >> 8) & 0xff) ^0x80;
3909 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3910 emitpcode(POC_ADDLW, popGetLit( 0x80));
3911 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3912 genSkipc(&rFalseIfx);
3915 if(ifx) ifx->generated = 1;
3920 /* Special cases for signed longs */
3921 if( (lit & 0xffffff) == 0) {
3922 /* lower byte is zero */
3923 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3924 i = ((lit >> 8*3) & 0xff) ^0x80;
3925 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3926 emitpcode(POC_ADDLW, popGetLit( 0x80));
3927 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3928 genSkipc(&rFalseIfx);
3931 if(ifx) ifx->generated = 1;
3939 if(lit & (0x80 << (size*8))) {
3940 /* lit is negative */
3941 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3943 //genSkipCond(&rFalseIfx,left,size,7);
3945 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3947 if(rFalseIfx.condition)
3948 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3950 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3954 /* lit is positive */
3955 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3956 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3957 if(rFalseIfx.condition)
3958 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3960 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3965 This works, but is only good for ints.
3966 It also requires a "known zero" register.
3967 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3968 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3969 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3970 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3971 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3972 genSkipc(&rFalseIfx);
3974 emitpLabel(truelbl->key);
3975 if(ifx) ifx->generated = 1;
3979 /* There are no more special cases, so perform a general compare */
3981 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3982 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3986 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3988 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3990 //rFalseIfx.condition ^= 1;
3991 genSkipc(&rFalseIfx);
3993 emitpLabel(truelbl->key);
3995 if(ifx) ifx->generated = 1;
4002 /* sign is out of the way. So now do an unsigned compare */
4003 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4006 /* General case - compare to an unsigned literal on the right.*/
4008 i = (lit >> (size*8)) & 0xff;
4009 emitpcode(POC_MOVLW, popGetLit(i));
4010 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4012 i = (lit >> (size*8)) & 0xff;
4015 emitpcode(POC_MOVLW, popGetLit(i));
4017 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4019 /* this byte of the lit is zero,
4020 *if it's not the last then OR in the variable */
4022 emitpcode(POC_IORFW, popGet(AOP(left),size));
4027 emitpLabel(lbl->key);
4028 //if(emitFinalCheck)
4029 genSkipc(&rFalseIfx);
4031 emitpLabel(truelbl->key);
4033 if(ifx) ifx->generated = 1;
4039 if(AOP_TYPE(left) == AOP_LIT) {
4040 //symbol *lbl = newiTempLabel(NULL);
4042 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4045 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4048 if((lit == 0) && (sign == 0)){
4051 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4053 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4055 genSkipz2(&rFalseIfx,0);
4056 if(ifx) ifx->generated = 1;
4063 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4064 /* degenerate compare can never be true */
4065 if(rFalseIfx.condition == 0)
4066 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4068 if(ifx) ifx->generated = 1;
4073 /* signed comparisons to a literal byte */
4075 int lp1 = (lit+1) & 0xff;
4077 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4080 rFalseIfx.condition ^= 1;
4081 genSkipCond(&rFalseIfx,right,0,7);
4084 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4085 emitpcode(POC_XORLW, popGetLit(0x7f));
4086 genSkipz2(&rFalseIfx,1);
4089 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4090 emitpcode(POC_ADDLW, popGetLit(0x80));
4091 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4092 rFalseIfx.condition ^= 1;
4093 genSkipc(&rFalseIfx);
4097 /* unsigned comparisons to a literal byte */
4099 switch(lit & 0xff ) {
4101 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4102 genSkipz2(&rFalseIfx,0);
4105 rFalseIfx.condition ^= 1;
4106 genSkipCond(&rFalseIfx,right,0,7);
4110 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4111 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4113 rFalseIfx.condition ^= 1;
4114 genSkipc(&rFalseIfx);
4119 if(ifx) ifx->generated = 1;
4124 /* Size is greater than 1 */
4132 /* this means lit = 0xffffffff, or -1 */
4135 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4136 rFalseIfx.condition ^= 1;
4137 genSkipCond(&rFalseIfx,right,size,7);
4138 if(ifx) ifx->generated = 1;
4145 if(rFalseIfx.condition) {
4146 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4147 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4150 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4152 emitpcode(POC_IORFW, popGet(AOP(right),size));
4156 if(rFalseIfx.condition) {
4157 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4158 emitpLabel(truelbl->key);
4160 rFalseIfx.condition ^= 1;
4161 genSkipCond(&rFalseIfx,right,s,7);
4164 if(ifx) ifx->generated = 1;
4168 if((size == 1) && (0 == (lp1&0xff))) {
4169 /* lower byte of signed word is zero */
4170 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4171 i = ((lp1 >> 8) & 0xff) ^0x80;
4172 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4173 emitpcode(POC_ADDLW, popGetLit( 0x80));
4174 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4175 rFalseIfx.condition ^= 1;
4176 genSkipc(&rFalseIfx);
4179 if(ifx) ifx->generated = 1;
4183 if(lit & (0x80 << (size*8))) {
4184 /* Lit is less than zero */
4185 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4186 //rFalseIfx.condition ^= 1;
4187 //genSkipCond(&rFalseIfx,left,size,7);
4188 //rFalseIfx.condition ^= 1;
4189 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4190 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4192 if(rFalseIfx.condition)
4193 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4195 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4199 /* Lit is greater than or equal to zero */
4200 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4201 //rFalseIfx.condition ^= 1;
4202 //genSkipCond(&rFalseIfx,right,size,7);
4203 //rFalseIfx.condition ^= 1;
4205 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4206 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4208 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4209 if(rFalseIfx.condition)
4210 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4212 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4217 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4218 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4222 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4224 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4226 rFalseIfx.condition ^= 1;
4227 //rFalseIfx.condition = 1;
4228 genSkipc(&rFalseIfx);
4230 emitpLabel(truelbl->key);
4232 if(ifx) ifx->generated = 1;
4237 /* compare word or long to an unsigned literal on the right.*/
4242 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4245 break; /* handled above */
4248 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4250 emitpcode(POC_IORFW, popGet(AOP(right),size));
4251 genSkipz2(&rFalseIfx,0);
4255 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4257 emitpcode(POC_IORFW, popGet(AOP(right),size));
4260 if(rFalseIfx.condition)
4261 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4263 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4266 emitpcode(POC_MOVLW, popGetLit(lit+1));
4267 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4269 rFalseIfx.condition ^= 1;
4270 genSkipc(&rFalseIfx);
4273 emitpLabel(truelbl->key);
4275 if(ifx) ifx->generated = 1;
4281 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4282 i = (lit >> (size*8)) & 0xff;
4284 emitpcode(POC_MOVLW, popGetLit(i));
4285 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4288 i = (lit >> (size*8)) & 0xff;
4291 emitpcode(POC_MOVLW, popGetLit(i));
4293 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4295 /* this byte of the lit is zero,
4296 *if it's not the last then OR in the variable */
4298 emitpcode(POC_IORFW, popGet(AOP(right),size));
4303 emitpLabel(lbl->key);
4305 rFalseIfx.condition ^= 1;
4306 genSkipc(&rFalseIfx);
4310 emitpLabel(truelbl->key);
4311 if(ifx) ifx->generated = 1;
4315 /* Compare two variables */
4317 DEBUGpic14_emitcode(";sign","%d",sign);
4321 /* Sigh. thus sucks... */
4323 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4324 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4325 emitpcode(POC_MOVLW, popGetLit(0x80));
4326 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4327 emitpcode(POC_XORFW, popGet(AOP(right),size));
4328 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4330 /* Signed char comparison */
4331 /* Special thanks to Nikolai Golovchenko for this snippet */
4332 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4333 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4334 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4335 emitpcode(POC_XORFW, popGet(AOP(left),0));
4336 emitpcode(POC_XORFW, popGet(AOP(right),0));
4337 emitpcode(POC_ADDLW, popGetLit(0x80));
4339 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4340 genSkipc(&rFalseIfx);
4342 if(ifx) ifx->generated = 1;
4348 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4349 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4353 /* The rest of the bytes of a multi-byte compare */
4357 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4360 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4361 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4366 emitpLabel(lbl->key);
4368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4369 genSkipc(&rFalseIfx);
4370 if(ifx) ifx->generated = 1;
4375 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4376 pic14_outBitC(result);
4378 /* if the result is used in the next
4379 ifx conditional branch then generate
4380 code a little differently */
4382 genIfxJump (ifx,"c");
4384 pic14_outBitC(result);
4385 /* leave the result in acc */
4390 /*-----------------------------------------------------------------*/
4391 /* genCmpGt :- greater than comparison */
4392 /*-----------------------------------------------------------------*/
4393 static void genCmpGt (iCode *ic, iCode *ifx)
4395 operand *left, *right, *result;
4396 sym_link *letype , *retype;
4399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4401 right= IC_RIGHT(ic);
4402 result = IC_RESULT(ic);
4404 letype = getSpec(operandType(left));
4405 retype =getSpec(operandType(right));
4406 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4407 /* assign the amsops */
4408 aopOp (left,ic,FALSE);
4409 aopOp (right,ic,FALSE);
4410 aopOp (result,ic,TRUE);
4412 genCmp(right, left, result, ifx, sign);
4414 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4415 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4416 freeAsmop(result,NULL,ic,TRUE);
4419 /*-----------------------------------------------------------------*/
4420 /* genCmpLt - less than comparisons */
4421 /*-----------------------------------------------------------------*/
4422 static void genCmpLt (iCode *ic, iCode *ifx)
4424 operand *left, *right, *result;
4425 sym_link *letype , *retype;
4428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4430 right= IC_RIGHT(ic);
4431 result = IC_RESULT(ic);
4433 letype = getSpec(operandType(left));
4434 retype =getSpec(operandType(right));
4435 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4437 /* assign the amsops */
4438 aopOp (left,ic,FALSE);
4439 aopOp (right,ic,FALSE);
4440 aopOp (result,ic,TRUE);
4442 genCmp(left, right, result, ifx, sign);
4444 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4445 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4446 freeAsmop(result,NULL,ic,TRUE);
4449 /*-----------------------------------------------------------------*/
4450 /* genc16bit2lit - compare a 16 bit value to a literal */
4451 /*-----------------------------------------------------------------*/
4452 static void genc16bit2lit(operand *op, int lit, int offset)
4456 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4457 if( (lit&0xff) == 0)
4462 switch( BYTEofLONG(lit,i)) {
4464 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4467 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4470 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4473 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4474 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4479 switch( BYTEofLONG(lit,i)) {
4481 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4485 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4489 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4492 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4494 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4500 /*-----------------------------------------------------------------*/
4501 /* gencjneshort - compare and jump if not equal */
4502 /*-----------------------------------------------------------------*/
4503 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4505 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4510 unsigned long lit = 0L;
4511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4512 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4514 resolveIfx(&rIfx,ifx);
4515 lbl = newiTempLabel(NULL);
4518 /* if the left side is a literal or
4519 if the right is in a pointer register and left
4521 if ((AOP_TYPE(left) == AOP_LIT) ||
4522 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4527 if(AOP_TYPE(right) == AOP_LIT)
4528 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4530 /* if the right side is a literal then anything goes */
4531 if (AOP_TYPE(right) == AOP_LIT &&
4532 AOP_TYPE(left) != AOP_DIR ) {
4535 genc16bit2lit(left, lit, 0);
4537 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4542 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4543 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4545 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4549 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4557 /* if the right side is in a register or in direct space or
4558 if the left is a pointer register & right is not */
4559 else if (AOP_TYPE(right) == AOP_REG ||
4560 AOP_TYPE(right) == AOP_DIR ||
4561 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4562 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4565 genc16bit2lit(left, lit, 0);
4567 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4572 if((AOP_TYPE(left) == AOP_DIR) &&
4573 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4575 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4576 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4578 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4580 switch (lit & 0xff) {
4582 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4585 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4586 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4590 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4591 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4595 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4596 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4601 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4604 if(AOP_TYPE(result) == AOP_CRY) {
4605 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4610 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4612 /* fix me. probably need to check result size too */
4613 emitpcode(POC_CLRF,popGet(AOP(result),0));
4618 emitpcode(POC_INCF,popGet(AOP(result),0));
4628 } else if(AOP_TYPE(right) == AOP_REG &&
4629 AOP_TYPE(left) != AOP_DIR){
4632 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4633 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4634 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4639 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4644 /* right is a pointer reg need both a & b */
4646 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4648 pic14_emitcode("mov","b,%s",l);
4649 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4650 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4654 emitpLabel(lbl->key);
4661 /*-----------------------------------------------------------------*/
4662 /* gencjne - compare and jump if not equal */
4663 /*-----------------------------------------------------------------*/
4664 static void gencjne(operand *left, operand *right, iCode *ifx)
4666 symbol *tlbl = newiTempLabel(NULL);
4668 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4669 gencjneshort(left, right, lbl);
4671 pic14_emitcode("mov","a,%s",one);
4672 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4673 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4674 pic14_emitcode("clr","a");
4675 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4677 emitpLabel(lbl->key);
4678 emitpLabel(tlbl->key);
4683 /*-----------------------------------------------------------------*/
4684 /* genCmpEq - generates code for equal to */
4685 /*-----------------------------------------------------------------*/
4686 static void genCmpEq (iCode *ic, iCode *ifx)
4688 operand *left, *right, *result;
4689 unsigned long lit = 0L;
4692 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4695 DEBUGpic14_emitcode ("; ifx is non-null","");
4697 DEBUGpic14_emitcode ("; ifx is null","");
4699 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4700 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4701 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4703 size = max(AOP_SIZE(left),AOP_SIZE(right));
4705 DEBUGpic14_AopType(__LINE__,left,right,result);
4707 /* if literal, literal on the right or
4708 if the right is in a pointer register and left
4710 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4711 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4712 operand *tmp = right ;
4718 if(ifx && !AOP_SIZE(result)){
4720 /* if they are both bit variables */
4721 if (AOP_TYPE(left) == AOP_CRY &&
4722 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4723 if(AOP_TYPE(right) == AOP_LIT){
4724 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4726 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4727 pic14_emitcode("cpl","c");
4728 } else if(lit == 1L) {
4729 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4731 pic14_emitcode("clr","c");
4733 /* AOP_TYPE(right) == AOP_CRY */
4735 symbol *lbl = newiTempLabel(NULL);
4736 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4737 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4738 pic14_emitcode("cpl","c");
4739 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4741 /* if true label then we jump if condition
4743 tlbl = newiTempLabel(NULL);
4744 if ( IC_TRUE(ifx) ) {
4745 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4746 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4748 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4749 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4751 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4754 /* left and right are both bit variables, result is carry */
4757 resolveIfx(&rIfx,ifx);
4759 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4760 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4761 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4762 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4767 /* They're not both bit variables. Is the right a literal? */
4768 if(AOP_TYPE(right) == AOP_LIT) {
4769 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4774 switch(lit & 0xff) {
4776 if ( IC_TRUE(ifx) ) {
4777 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4779 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4781 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4782 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4786 if ( IC_TRUE(ifx) ) {
4787 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4789 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4791 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4792 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4796 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4798 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4803 /* end of size == 1 */
4807 genc16bit2lit(left,lit,offset);
4810 /* end of size == 2 */
4815 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4816 emitpcode(POC_IORFW,popGet(AOP(left),1));
4817 emitpcode(POC_IORFW,popGet(AOP(left),2));
4818 emitpcode(POC_IORFW,popGet(AOP(left),3));
4822 /* search for patterns that can be optimized */
4824 genc16bit2lit(left,lit,0);
4827 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4829 genc16bit2lit(left,lit,2);
4831 emitpcode(POC_IORFW,popGet(AOP(left),2));
4832 emitpcode(POC_IORFW,popGet(AOP(left),3));
4845 } else if(AOP_TYPE(right) == AOP_CRY ) {
4846 /* we know the left is not a bit, but that the right is */
4847 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4848 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4849 popGet(AOP(right),offset));
4850 emitpcode(POC_XORLW,popGetLit(1));
4852 /* if the two are equal, then W will be 0 and the Z bit is set
4853 * we could test Z now, or go ahead and check the high order bytes if
4854 * the variable we're comparing is larger than a byte. */
4857 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4859 if ( IC_TRUE(ifx) ) {
4861 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4862 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4865 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4866 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4870 /* They're both variables that are larger than bits */
4873 tlbl = newiTempLabel(NULL);
4876 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4877 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4879 if ( IC_TRUE(ifx) ) {
4882 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4883 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4886 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4887 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4891 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4892 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4896 if(s>1 && IC_TRUE(ifx)) {
4897 emitpLabel(tlbl->key);
4898 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4902 /* mark the icode as generated */
4907 /* if they are both bit variables */
4908 if (AOP_TYPE(left) == AOP_CRY &&
4909 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4910 if(AOP_TYPE(right) == AOP_LIT){
4911 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4913 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4914 pic14_emitcode("cpl","c");
4915 } else if(lit == 1L) {
4916 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4918 pic14_emitcode("clr","c");
4920 /* AOP_TYPE(right) == AOP_CRY */
4922 symbol *lbl = newiTempLabel(NULL);
4923 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4924 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4925 pic14_emitcode("cpl","c");
4926 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4929 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4930 pic14_outBitC(result);
4934 genIfxJump (ifx,"c");
4937 /* if the result is used in an arithmetic operation
4938 then put the result in place */
4939 pic14_outBitC(result);
4942 gencjne(left,right,result,ifx);
4945 gencjne(left,right,newiTempLabel(NULL));
4947 if(IC_TRUE(ifx)->key)
4948 gencjne(left,right,IC_TRUE(ifx)->key);
4950 gencjne(left,right,IC_FALSE(ifx)->key);
4954 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4955 aopPut(AOP(result),"a",0);
4960 genIfxJump (ifx,"a");
4964 /* if the result is used in an arithmetic operation
4965 then put the result in place */
4967 if (AOP_TYPE(result) != AOP_CRY)
4968 pic14_outAcc(result);
4970 /* leave the result in acc */
4974 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4975 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4976 freeAsmop(result,NULL,ic,TRUE);
4979 /*-----------------------------------------------------------------*/
4980 /* ifxForOp - returns the icode containing the ifx for operand */
4981 /*-----------------------------------------------------------------*/
4982 static iCode *ifxForOp ( operand *op, iCode *ic )
4984 /* if true symbol then needs to be assigned */
4985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4986 if (IS_TRUE_SYMOP(op))
4989 /* if this has register type condition and
4990 the next instruction is ifx with the same operand
4991 and live to of the operand is upto the ifx only then */
4993 ic->next->op == IFX &&
4994 IC_COND(ic->next)->key == op->key &&
4995 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4999 ic->next->op == IFX &&
5000 IC_COND(ic->next)->key == op->key) {
5001 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5005 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5007 ic->next->op == IFX)
5008 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5011 ic->next->op == IFX &&
5012 IC_COND(ic->next)->key == op->key) {
5013 DEBUGpic14_emitcode ("; "," key is okay");
5014 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5015 OP_SYMBOL(op)->liveTo,
5022 /*-----------------------------------------------------------------*/
5023 /* genAndOp - for && operation */
5024 /*-----------------------------------------------------------------*/
5025 static void genAndOp (iCode *ic)
5027 operand *left,*right, *result;
5030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5031 /* note here that && operations that are in an
5032 if statement are taken away by backPatchLabels
5033 only those used in arthmetic operations remain */
5034 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5035 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5036 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5038 /* if both are bit variables */
5039 if (AOP_TYPE(left) == AOP_CRY &&
5040 AOP_TYPE(right) == AOP_CRY ) {
5041 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5042 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5043 pic14_outBitC(result);
5045 tlbl = newiTempLabel(NULL);
5046 pic14_toBoolean(left);
5047 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5048 pic14_toBoolean(right);
5049 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5050 pic14_outBitAcc(result);
5053 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5054 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5055 freeAsmop(result,NULL,ic,TRUE);
5059 /*-----------------------------------------------------------------*/
5060 /* genOrOp - for || operation */
5061 /*-----------------------------------------------------------------*/
5064 modified this code, but it doesn't appear to ever get called
5067 static void genOrOp (iCode *ic)
5069 operand *left,*right, *result;
5072 /* note here that || operations that are in an
5073 if statement are taken away by backPatchLabels
5074 only those used in arthmetic operations remain */
5075 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5076 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5077 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5078 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5080 DEBUGpic14_AopType(__LINE__,left,right,result);
5082 /* if both are bit variables */
5083 if (AOP_TYPE(left) == AOP_CRY &&
5084 AOP_TYPE(right) == AOP_CRY ) {
5085 pic14_emitcode("clrc","");
5086 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5087 AOP(left)->aopu.aop_dir,
5088 AOP(left)->aopu.aop_dir);
5089 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5090 AOP(right)->aopu.aop_dir,
5091 AOP(right)->aopu.aop_dir);
5092 pic14_emitcode("setc","");
5095 tlbl = newiTempLabel(NULL);
5096 pic14_toBoolean(left);
5098 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5099 pic14_toBoolean(right);
5100 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5102 pic14_outBitAcc(result);
5105 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5106 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5107 freeAsmop(result,NULL,ic,TRUE);
5110 /*-----------------------------------------------------------------*/
5111 /* isLiteralBit - test if lit == 2^n */
5112 /*-----------------------------------------------------------------*/
5113 static int isLiteralBit(unsigned long lit)
5115 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5116 0x100L,0x200L,0x400L,0x800L,
5117 0x1000L,0x2000L,0x4000L,0x8000L,
5118 0x10000L,0x20000L,0x40000L,0x80000L,
5119 0x100000L,0x200000L,0x400000L,0x800000L,
5120 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5121 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5125 for(idx = 0; idx < 32; idx++)
5131 /*-----------------------------------------------------------------*/
5132 /* continueIfTrue - */
5133 /*-----------------------------------------------------------------*/
5134 static void continueIfTrue (iCode *ic)
5136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5138 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5142 /*-----------------------------------------------------------------*/
5144 /*-----------------------------------------------------------------*/
5145 static void jumpIfTrue (iCode *ic)
5147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5149 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5153 /*-----------------------------------------------------------------*/
5154 /* jmpTrueOrFalse - */
5155 /*-----------------------------------------------------------------*/
5156 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5158 // ugly but optimized by peephole
5159 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5161 symbol *nlbl = newiTempLabel(NULL);
5162 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5163 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5164 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5165 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5168 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5169 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5174 /*-----------------------------------------------------------------*/
5175 /* genAnd - code for and */
5176 /*-----------------------------------------------------------------*/
5177 static void genAnd (iCode *ic, iCode *ifx)
5179 operand *left, *right, *result;
5181 unsigned long lit = 0L;
5186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5187 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5188 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5189 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5191 resolveIfx(&rIfx,ifx);
5193 /* if left is a literal & right is not then exchange them */
5194 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5195 AOP_NEEDSACC(left)) {
5196 operand *tmp = right ;
5201 /* if result = right then exchange them */
5202 if(pic14_sameRegs(AOP(result),AOP(right))){
5203 operand *tmp = right ;
5208 /* if right is bit then exchange them */
5209 if (AOP_TYPE(right) == AOP_CRY &&
5210 AOP_TYPE(left) != AOP_CRY){
5211 operand *tmp = right ;
5215 if(AOP_TYPE(right) == AOP_LIT)
5216 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5218 size = AOP_SIZE(result);
5220 DEBUGpic14_AopType(__LINE__,left,right,result);
5223 // result = bit & yy;
5224 if (AOP_TYPE(left) == AOP_CRY){
5225 // c = bit & literal;
5226 if(AOP_TYPE(right) == AOP_LIT){
5228 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5231 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5234 if(size && (AOP_TYPE(result) == AOP_CRY)){
5235 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5238 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5242 pic14_emitcode("clr","c");
5245 if (AOP_TYPE(right) == AOP_CRY){
5247 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5248 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5251 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5253 pic14_emitcode("rrc","a");
5254 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5260 pic14_outBitC(result);
5262 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5263 genIfxJump(ifx, "c");
5267 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5268 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5269 if((AOP_TYPE(right) == AOP_LIT) &&
5270 (AOP_TYPE(result) == AOP_CRY) &&
5271 (AOP_TYPE(left) != AOP_CRY)){
5272 int posbit = isLiteralBit(lit);
5276 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5279 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5285 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5286 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5288 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5289 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5292 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5293 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5294 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5301 symbol *tlbl = newiTempLabel(NULL);
5302 int sizel = AOP_SIZE(left);
5304 pic14_emitcode("setb","c");
5306 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5307 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5309 if((posbit = isLiteralBit(bytelit)) != 0)
5310 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5312 if(bytelit != 0x0FFL)
5313 pic14_emitcode("anl","a,%s",
5314 aopGet(AOP(right),offset,FALSE,TRUE));
5315 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5320 // bit = left & literal
5322 pic14_emitcode("clr","c");
5323 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5325 // if(left & literal)
5328 jmpTrueOrFalse(ifx, tlbl);
5332 pic14_outBitC(result);
5336 /* if left is same as result */
5337 if(pic14_sameRegs(AOP(result),AOP(left))){
5339 for(;size--; offset++,lit>>=8) {
5340 if(AOP_TYPE(right) == AOP_LIT){
5341 switch(lit & 0xff) {
5343 /* and'ing with 0 has clears the result */
5344 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5345 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5348 /* and'ing with 0xff is a nop when the result and left are the same */
5353 int p = my_powof2( (~lit) & 0xff );
5355 /* only one bit is set in the literal, so use a bcf instruction */
5356 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5357 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5360 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5361 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5362 if(know_W != (lit&0xff))
5363 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5365 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5370 if (AOP_TYPE(left) == AOP_ACC) {
5371 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5373 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5374 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5381 // left & result in different registers
5382 if(AOP_TYPE(result) == AOP_CRY){
5384 // if(size), result in bit
5385 // if(!size && ifx), conditional oper: if(left & right)
5386 symbol *tlbl = newiTempLabel(NULL);
5387 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5389 pic14_emitcode("setb","c");
5391 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5392 pic14_emitcode("anl","a,%s",
5393 aopGet(AOP(left),offset,FALSE,FALSE));
5394 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5399 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5400 pic14_outBitC(result);
5402 jmpTrueOrFalse(ifx, tlbl);
5404 for(;(size--);offset++) {
5406 // result = left & right
5407 if(AOP_TYPE(right) == AOP_LIT){
5408 int t = (lit >> (offset*8)) & 0x0FFL;
5411 pic14_emitcode("clrf","%s",
5412 aopGet(AOP(result),offset,FALSE,FALSE));
5413 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5416 pic14_emitcode("movf","%s,w",
5417 aopGet(AOP(left),offset,FALSE,FALSE));
5418 pic14_emitcode("movwf","%s",
5419 aopGet(AOP(result),offset,FALSE,FALSE));
5420 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5421 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5424 pic14_emitcode("movlw","0x%x",t);
5425 pic14_emitcode("andwf","%s,w",
5426 aopGet(AOP(left),offset,FALSE,FALSE));
5427 pic14_emitcode("movwf","%s",
5428 aopGet(AOP(result),offset,FALSE,FALSE));
5430 emitpcode(POC_MOVLW, popGetLit(t));
5431 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5432 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5437 if (AOP_TYPE(left) == AOP_ACC) {
5438 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5439 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5441 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5442 pic14_emitcode("andwf","%s,w",
5443 aopGet(AOP(left),offset,FALSE,FALSE));
5444 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5445 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5447 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5448 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5454 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5455 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5456 freeAsmop(result,NULL,ic,TRUE);
5459 /*-----------------------------------------------------------------*/
5460 /* genOr - code for or */
5461 /*-----------------------------------------------------------------*/
5462 static void genOr (iCode *ic, iCode *ifx)
5464 operand *left, *right, *result;
5466 unsigned long lit = 0L;
5468 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5470 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5471 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5472 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5474 DEBUGpic14_AopType(__LINE__,left,right,result);
5476 /* if left is a literal & right is not then exchange them */
5477 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5478 AOP_NEEDSACC(left)) {
5479 operand *tmp = right ;
5484 /* if result = right then exchange them */
5485 if(pic14_sameRegs(AOP(result),AOP(right))){
5486 operand *tmp = right ;
5491 /* if right is bit then exchange them */
5492 if (AOP_TYPE(right) == AOP_CRY &&
5493 AOP_TYPE(left) != AOP_CRY){
5494 operand *tmp = right ;
5499 DEBUGpic14_AopType(__LINE__,left,right,result);
5501 if(AOP_TYPE(right) == AOP_LIT)
5502 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5504 size = AOP_SIZE(result);
5508 if (AOP_TYPE(left) == AOP_CRY){
5509 if(AOP_TYPE(right) == AOP_LIT){
5510 // c = bit & literal;
5512 // lit != 0 => result = 1
5513 if(AOP_TYPE(result) == AOP_CRY){
5515 emitpcode(POC_BSF, popGet(AOP(result),0));
5516 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5517 // AOP(result)->aopu.aop_dir,
5518 // AOP(result)->aopu.aop_dir);
5520 continueIfTrue(ifx);
5524 // lit == 0 => result = left
5525 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5527 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5530 if (AOP_TYPE(right) == AOP_CRY){
5531 if(pic14_sameRegs(AOP(result),AOP(left))){
5533 emitpcode(POC_BCF, popGet(AOP(result),0));
5534 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5535 emitpcode(POC_BSF, popGet(AOP(result),0));
5537 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5538 AOP(result)->aopu.aop_dir,
5539 AOP(result)->aopu.aop_dir);
5540 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5541 AOP(right)->aopu.aop_dir,
5542 AOP(right)->aopu.aop_dir);
5543 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5544 AOP(result)->aopu.aop_dir,
5545 AOP(result)->aopu.aop_dir);
5547 if( AOP_TYPE(result) == AOP_ACC) {
5548 emitpcode(POC_MOVLW, popGetLit(0));
5549 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5550 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5551 emitpcode(POC_MOVLW, popGetLit(1));
5555 emitpcode(POC_BCF, popGet(AOP(result),0));
5556 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5557 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5558 emitpcode(POC_BSF, popGet(AOP(result),0));
5560 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5561 AOP(result)->aopu.aop_dir,
5562 AOP(result)->aopu.aop_dir);
5563 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5564 AOP(right)->aopu.aop_dir,
5565 AOP(right)->aopu.aop_dir);
5566 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5567 AOP(left)->aopu.aop_dir,
5568 AOP(left)->aopu.aop_dir);
5569 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5570 AOP(result)->aopu.aop_dir,
5571 AOP(result)->aopu.aop_dir);
5576 symbol *tlbl = newiTempLabel(NULL);
5577 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5580 emitpcode(POC_BCF, popGet(AOP(result),0));
5581 if( AOP_TYPE(right) == AOP_ACC) {
5582 emitpcode(POC_IORLW, popGetLit(0));
5584 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5585 emitpcode(POC_BSF, popGet(AOP(result),0));
5590 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5591 pic14_emitcode(";XXX setb","c");
5592 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5593 AOP(left)->aopu.aop_dir,tlbl->key+100);
5594 pic14_toBoolean(right);
5595 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5596 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5597 jmpTrueOrFalse(ifx, tlbl);
5601 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5608 pic14_outBitC(result);
5610 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5611 genIfxJump(ifx, "c");
5615 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5616 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5617 if((AOP_TYPE(right) == AOP_LIT) &&
5618 (AOP_TYPE(result) == AOP_CRY) &&
5619 (AOP_TYPE(left) != AOP_CRY)){
5621 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5624 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5626 continueIfTrue(ifx);
5629 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5630 // lit = 0, result = boolean(left)
5632 pic14_emitcode(";XXX setb","c");
5633 pic14_toBoolean(right);
5635 symbol *tlbl = newiTempLabel(NULL);
5636 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5638 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5640 genIfxJump (ifx,"a");
5644 pic14_outBitC(result);
5648 /* if left is same as result */
5649 if(pic14_sameRegs(AOP(result),AOP(left))){
5651 for(;size--; offset++,lit>>=8) {
5652 if(AOP_TYPE(right) == AOP_LIT){
5653 if((lit & 0xff) == 0)
5654 /* or'ing with 0 has no effect */
5657 int p = my_powof2(lit & 0xff);
5659 /* only one bit is set in the literal, so use a bsf instruction */
5661 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5663 if(know_W != (lit & 0xff))
5664 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5665 know_W = lit & 0xff;
5666 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5671 if (AOP_TYPE(left) == AOP_ACC) {
5672 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5673 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5675 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5676 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5678 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5679 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5685 // left & result in different registers
5686 if(AOP_TYPE(result) == AOP_CRY){
5688 // if(size), result in bit
5689 // if(!size && ifx), conditional oper: if(left | right)
5690 symbol *tlbl = newiTempLabel(NULL);
5691 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5692 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5696 pic14_emitcode(";XXX setb","c");
5698 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5699 pic14_emitcode(";XXX orl","a,%s",
5700 aopGet(AOP(left),offset,FALSE,FALSE));
5701 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5706 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5707 pic14_outBitC(result);
5709 jmpTrueOrFalse(ifx, tlbl);
5710 } else for(;(size--);offset++){
5712 // result = left & right
5713 if(AOP_TYPE(right) == AOP_LIT){
5714 int t = (lit >> (offset*8)) & 0x0FFL;
5717 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5718 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5720 pic14_emitcode("movf","%s,w",
5721 aopGet(AOP(left),offset,FALSE,FALSE));
5722 pic14_emitcode("movwf","%s",
5723 aopGet(AOP(result),offset,FALSE,FALSE));
5726 emitpcode(POC_MOVLW, popGetLit(t));
5727 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5728 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5730 pic14_emitcode("movlw","0x%x",t);
5731 pic14_emitcode("iorwf","%s,w",
5732 aopGet(AOP(left),offset,FALSE,FALSE));
5733 pic14_emitcode("movwf","%s",
5734 aopGet(AOP(result),offset,FALSE,FALSE));
5740 // faster than result <- left, anl result,right
5741 // and better if result is SFR
5742 if (AOP_TYPE(left) == AOP_ACC) {
5743 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5744 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5746 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5747 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5749 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5750 pic14_emitcode("iorwf","%s,w",
5751 aopGet(AOP(left),offset,FALSE,FALSE));
5753 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5754 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5759 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5760 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5761 freeAsmop(result,NULL,ic,TRUE);
5764 /*-----------------------------------------------------------------*/
5765 /* genXor - code for xclusive or */
5766 /*-----------------------------------------------------------------*/
5767 static void genXor (iCode *ic, iCode *ifx)
5769 operand *left, *right, *result;
5771 unsigned long lit = 0L;
5773 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5775 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5776 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5777 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5779 /* if left is a literal & right is not ||
5780 if left needs acc & right does not */
5781 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5782 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5783 operand *tmp = right ;
5788 /* if result = right then exchange them */
5789 if(pic14_sameRegs(AOP(result),AOP(right))){
5790 operand *tmp = right ;
5795 /* if right is bit then exchange them */
5796 if (AOP_TYPE(right) == AOP_CRY &&
5797 AOP_TYPE(left) != AOP_CRY){
5798 operand *tmp = right ;
5802 if(AOP_TYPE(right) == AOP_LIT)
5803 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5805 size = AOP_SIZE(result);
5809 if (AOP_TYPE(left) == AOP_CRY){
5810 if(AOP_TYPE(right) == AOP_LIT){
5811 // c = bit & literal;
5813 // lit>>1 != 0 => result = 1
5814 if(AOP_TYPE(result) == AOP_CRY){
5816 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5817 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5819 continueIfTrue(ifx);
5822 pic14_emitcode("setb","c");
5826 // lit == 0, result = left
5827 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5829 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5831 // lit == 1, result = not(left)
5832 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5833 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5834 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5835 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5838 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5839 pic14_emitcode("cpl","c");
5846 symbol *tlbl = newiTempLabel(NULL);
5847 if (AOP_TYPE(right) == AOP_CRY){
5849 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5852 int sizer = AOP_SIZE(right);
5854 // if val>>1 != 0, result = 1
5855 pic14_emitcode("setb","c");
5857 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5859 // test the msb of the lsb
5860 pic14_emitcode("anl","a,#0xfe");
5861 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5865 pic14_emitcode("rrc","a");
5867 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5868 pic14_emitcode("cpl","c");
5869 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5874 pic14_outBitC(result);
5876 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5877 genIfxJump(ifx, "c");
5881 if(pic14_sameRegs(AOP(result),AOP(left))){
5882 /* if left is same as result */
5883 for(;size--; offset++) {
5884 if(AOP_TYPE(right) == AOP_LIT){
5885 int t = (lit >> (offset*8)) & 0x0FFL;
5889 if (IS_AOP_PREG(left)) {
5890 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5891 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5892 aopPut(AOP(result),"a",offset);
5894 emitpcode(POC_MOVLW, popGetLit(t));
5895 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5896 pic14_emitcode("xrl","%s,%s",
5897 aopGet(AOP(left),offset,FALSE,TRUE),
5898 aopGet(AOP(right),offset,FALSE,FALSE));
5901 if (AOP_TYPE(left) == AOP_ACC)
5902 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5904 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5905 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5907 if (IS_AOP_PREG(left)) {
5908 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5909 aopPut(AOP(result),"a",offset);
5911 pic14_emitcode("xrl","%s,a",
5912 aopGet(AOP(left),offset,FALSE,TRUE));
5918 // left & result in different registers
5919 if(AOP_TYPE(result) == AOP_CRY){
5921 // if(size), result in bit
5922 // if(!size && ifx), conditional oper: if(left ^ right)
5923 symbol *tlbl = newiTempLabel(NULL);
5924 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5926 pic14_emitcode("setb","c");
5928 if((AOP_TYPE(right) == AOP_LIT) &&
5929 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5930 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5932 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5933 pic14_emitcode("xrl","a,%s",
5934 aopGet(AOP(left),offset,FALSE,FALSE));
5936 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5941 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5942 pic14_outBitC(result);
5944 jmpTrueOrFalse(ifx, tlbl);
5945 } else for(;(size--);offset++){
5947 // result = left & right
5948 if(AOP_TYPE(right) == AOP_LIT){
5949 int t = (lit >> (offset*8)) & 0x0FFL;
5952 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5953 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5954 pic14_emitcode("movf","%s,w",
5955 aopGet(AOP(left),offset,FALSE,FALSE));
5956 pic14_emitcode("movwf","%s",
5957 aopGet(AOP(result),offset,FALSE,FALSE));
5960 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5961 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5962 pic14_emitcode("comf","%s,w",
5963 aopGet(AOP(left),offset,FALSE,FALSE));
5964 pic14_emitcode("movwf","%s",
5965 aopGet(AOP(result),offset,FALSE,FALSE));
5968 emitpcode(POC_MOVLW, popGetLit(t));
5969 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5970 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5971 pic14_emitcode("movlw","0x%x",t);
5972 pic14_emitcode("xorwf","%s,w",
5973 aopGet(AOP(left),offset,FALSE,FALSE));
5974 pic14_emitcode("movwf","%s",
5975 aopGet(AOP(result),offset,FALSE,FALSE));
5981 // faster than result <- left, anl result,right
5982 // and better if result is SFR
5983 if (AOP_TYPE(left) == AOP_ACC) {
5984 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5985 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5987 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5988 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5989 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5990 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5992 if ( AOP_TYPE(result) != AOP_ACC){
5993 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5994 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6000 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6001 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6002 freeAsmop(result,NULL,ic,TRUE);
6005 /*-----------------------------------------------------------------*/
6006 /* genInline - write the inline code out */
6007 /*-----------------------------------------------------------------*/
6008 static void genInline (iCode *ic)
6010 char *buffer, *bp, *bp1;
6012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6014 _G.inLine += (!options.asmpeep);
6016 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6017 strcpy(buffer,IC_INLINE(ic));
6019 /* emit each line as a code */
6023 pic14_emitcode(bp1,"");
6024 addpCode2pBlock(pb,newpCodeInlineP(bp1));
6031 pic14_emitcode(bp1,"");
6038 pic14_emitcode(bp1,"");
6039 addpCode2pBlock(pb,newpCodeInlineP(bp1));
6041 /* pic14_emitcode("",buffer); */
6042 _G.inLine -= (!options.asmpeep);
6045 /*-----------------------------------------------------------------*/
6046 /* genRRC - rotate right with carry */
6047 /*-----------------------------------------------------------------*/
6048 static void genRRC (iCode *ic)
6050 operand *left , *result ;
6051 int size, offset = 0, same;
6053 /* rotate right with carry */
6055 result=IC_RESULT(ic);
6056 aopOp (left,ic,FALSE);
6057 aopOp (result,ic,FALSE);
6059 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6061 same = pic14_sameRegs(AOP(result),AOP(left));
6063 size = AOP_SIZE(result);
6065 /* get the lsb and put it into the carry */
6066 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6073 emitpcode(POC_RRF, popGet(AOP(left),offset));
6075 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6076 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6082 freeAsmop(left,NULL,ic,TRUE);
6083 freeAsmop(result,NULL,ic,TRUE);
6086 /*-----------------------------------------------------------------*/
6087 /* genRLC - generate code for rotate left with carry */
6088 /*-----------------------------------------------------------------*/
6089 static void genRLC (iCode *ic)
6091 operand *left , *result ;
6092 int size, offset = 0;
6095 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6096 /* rotate right with carry */
6098 result=IC_RESULT(ic);
6099 aopOp (left,ic,FALSE);
6100 aopOp (result,ic,FALSE);
6102 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6104 same = pic14_sameRegs(AOP(result),AOP(left));
6106 /* move it to the result */
6107 size = AOP_SIZE(result);
6109 /* get the msb and put it into the carry */
6110 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6117 emitpcode(POC_RLF, popGet(AOP(left),offset));
6119 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6120 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6127 freeAsmop(left,NULL,ic,TRUE);
6128 freeAsmop(result,NULL,ic,TRUE);
6131 /*-----------------------------------------------------------------*/
6132 /* genGetHbit - generates code get highest order bit */
6133 /*-----------------------------------------------------------------*/
6134 static void genGetHbit (iCode *ic)
6136 operand *left, *result;
6138 result=IC_RESULT(ic);
6139 aopOp (left,ic,FALSE);
6140 aopOp (result,ic,FALSE);
6142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6143 /* get the highest order byte into a */
6144 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6145 if(AOP_TYPE(result) == AOP_CRY){
6146 pic14_emitcode("rlc","a");
6147 pic14_outBitC(result);
6150 pic14_emitcode("rl","a");
6151 pic14_emitcode("anl","a,#0x01");
6152 pic14_outAcc(result);
6156 freeAsmop(left,NULL,ic,TRUE);
6157 freeAsmop(result,NULL,ic,TRUE);
6160 /*-----------------------------------------------------------------*/
6161 /* AccRol - rotate left accumulator by known count */
6162 /*-----------------------------------------------------------------*/
6163 static void AccRol (int shCount)
6165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6166 shCount &= 0x0007; // shCount : 0..7
6171 pic14_emitcode("rl","a");
6174 pic14_emitcode("rl","a");
6175 pic14_emitcode("rl","a");
6178 pic14_emitcode("swap","a");
6179 pic14_emitcode("rr","a");
6182 pic14_emitcode("swap","a");
6185 pic14_emitcode("swap","a");
6186 pic14_emitcode("rl","a");
6189 pic14_emitcode("rr","a");
6190 pic14_emitcode("rr","a");
6193 pic14_emitcode("rr","a");
6198 /*-----------------------------------------------------------------*/
6199 /* AccLsh - left shift accumulator by known count */
6200 /*-----------------------------------------------------------------*/
6201 static void AccLsh (int shCount)
6203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6206 pic14_emitcode("add","a,acc");
6209 pic14_emitcode("add","a,acc");
6210 pic14_emitcode("add","a,acc");
6212 /* rotate left accumulator */
6214 /* and kill the lower order bits */
6215 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6220 /*-----------------------------------------------------------------*/
6221 /* AccRsh - right shift accumulator by known count */
6222 /*-----------------------------------------------------------------*/
6223 static void AccRsh (int shCount)
6225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6229 pic14_emitcode("rrc","a");
6231 /* rotate right accumulator */
6232 AccRol(8 - shCount);
6233 /* and kill the higher order bits */
6234 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6240 /*-----------------------------------------------------------------*/
6241 /* AccSRsh - signed right shift accumulator by known count */
6242 /*-----------------------------------------------------------------*/
6243 static void AccSRsh (int shCount)
6246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6249 pic14_emitcode("mov","c,acc.7");
6250 pic14_emitcode("rrc","a");
6251 } else if(shCount == 2){
6252 pic14_emitcode("mov","c,acc.7");
6253 pic14_emitcode("rrc","a");
6254 pic14_emitcode("mov","c,acc.7");
6255 pic14_emitcode("rrc","a");
6257 tlbl = newiTempLabel(NULL);
6258 /* rotate right accumulator */
6259 AccRol(8 - shCount);
6260 /* and kill the higher order bits */
6261 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6262 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6263 pic14_emitcode("orl","a,#0x%02x",
6264 (unsigned char)~SRMask[shCount]);
6265 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6270 /*-----------------------------------------------------------------*/
6271 /* shiftR1Left2Result - shift right one byte from left to result */
6272 /*-----------------------------------------------------------------*/
6273 static void shiftR1Left2ResultSigned (operand *left, int offl,
6274 operand *result, int offr,
6279 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6281 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6285 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6287 emitpcode(POC_RRF, popGet(AOP(result),offr));
6289 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6290 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6296 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6298 emitpcode(POC_RRF, popGet(AOP(result),offr));
6300 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6301 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6303 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6304 emitpcode(POC_RRF, popGet(AOP(result),offr));
6310 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6312 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6313 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6316 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6317 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6318 emitpcode(POC_ANDLW, popGetLit(0x1f));
6320 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6321 emitpcode(POC_IORLW, popGetLit(0xe0));
6323 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6327 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6328 emitpcode(POC_ANDLW, popGetLit(0x0f));
6329 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6330 emitpcode(POC_IORLW, popGetLit(0xf0));
6331 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6335 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6337 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6338 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6340 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6341 emitpcode(POC_ANDLW, popGetLit(0x07));
6342 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6343 emitpcode(POC_IORLW, popGetLit(0xf8));
6344 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6349 emitpcode(POC_MOVLW, popGetLit(0x00));
6350 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6351 emitpcode(POC_MOVLW, popGetLit(0xfe));
6352 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6353 emitpcode(POC_IORLW, popGetLit(0x01));
6354 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6356 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6357 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6358 emitpcode(POC_DECF, popGet(AOP(result),offr));
6359 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6360 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6366 emitpcode(POC_MOVLW, popGetLit(0x00));
6367 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6368 emitpcode(POC_MOVLW, popGetLit(0xff));
6369 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6371 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6372 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6373 emitpcode(POC_DECF, popGet(AOP(result),offr));
6381 /*-----------------------------------------------------------------*/
6382 /* shiftR1Left2Result - shift right one byte from left to result */
6383 /*-----------------------------------------------------------------*/
6384 static void shiftR1Left2Result (operand *left, int offl,
6385 operand *result, int offr,
6386 int shCount, int sign)
6390 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6392 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6394 /* Copy the msb into the carry if signed. */
6396 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6406 emitpcode(POC_RRF, popGet(AOP(result),offr));
6408 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6409 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415 emitpcode(POC_RRF, popGet(AOP(result),offr));
6417 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6418 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6421 emitpcode(POC_RRF, popGet(AOP(result),offr));
6426 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6428 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6429 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6432 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6433 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6434 emitpcode(POC_ANDLW, popGetLit(0x1f));
6435 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6439 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6440 emitpcode(POC_ANDLW, popGetLit(0x0f));
6441 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6446 emitpcode(POC_ANDLW, popGetLit(0x0f));
6447 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6449 emitpcode(POC_RRF, popGet(AOP(result),offr));
6454 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6455 emitpcode(POC_ANDLW, popGetLit(0x80));
6456 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6457 emitpcode(POC_RLF, popGet(AOP(result),offr));
6458 emitpcode(POC_RLF, popGet(AOP(result),offr));
6463 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6464 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6465 emitpcode(POC_RLF, popGet(AOP(result),offr));
6474 /*-----------------------------------------------------------------*/
6475 /* shiftL1Left2Result - shift left one byte from left to result */
6476 /*-----------------------------------------------------------------*/
6477 static void shiftL1Left2Result (operand *left, int offl,
6478 operand *result, int offr, int shCount)
6483 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6485 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6486 DEBUGpic14_emitcode ("; ***","same = %d",same);
6487 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6489 /* shift left accumulator */
6490 //AccLsh(shCount); // don't comment out just yet...
6491 // aopPut(AOP(result),"a",offr);
6495 /* Shift left 1 bit position */
6496 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6498 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6500 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6501 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6506 emitpcode(POC_ANDLW,popGetLit(0x7e));
6507 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6508 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6511 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW,popGetLit(0x3e));
6513 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6514 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6515 emitpcode(POC_RLF, popGet(AOP(result),offr));
6518 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6519 emitpcode(POC_ANDLW, popGetLit(0xf0));
6520 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6523 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6524 emitpcode(POC_ANDLW, popGetLit(0xf0));
6525 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6526 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6529 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6530 emitpcode(POC_ANDLW, popGetLit(0x30));
6531 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6532 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6533 emitpcode(POC_RLF, popGet(AOP(result),offr));
6536 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6537 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6538 emitpcode(POC_RRF, popGet(AOP(result),offr));
6542 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6547 /*-----------------------------------------------------------------*/
6548 /* movLeft2Result - move byte from left to result */
6549 /*-----------------------------------------------------------------*/
6550 static void movLeft2Result (operand *left, int offl,
6551 operand *result, int offr)
6554 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6555 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6556 l = aopGet(AOP(left),offl,FALSE,FALSE);
6558 if (*l == '@' && (IS_AOP_PREG(result))) {
6559 pic14_emitcode("mov","a,%s",l);
6560 aopPut(AOP(result),"a",offr);
6562 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6563 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6568 /*-----------------------------------------------------------------*/
6569 /* shiftL2Left2Result - shift left two bytes from left to result */
6570 /*-----------------------------------------------------------------*/
6571 static void shiftL2Left2Result (operand *left, int offl,
6572 operand *result, int offr, int shCount)
6576 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6578 if(pic14_sameRegs(AOP(result), AOP(left))) {
6586 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6587 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6588 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6592 emitpcode(POC_RLF, popGet(AOP(result),offr));
6593 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6599 emitpcode(POC_MOVLW, popGetLit(0x0f));
6600 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6602 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6603 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6604 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6605 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6607 emitpcode(POC_RLF, popGet(AOP(result),offr));
6608 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6612 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_RRF, popGet(AOP(result),offr));
6614 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6615 emitpcode(POC_RRF, popGet(AOP(result),offr));
6616 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6617 emitpcode(POC_ANDLW,popGetLit(0xc0));
6618 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6619 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6620 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6621 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6624 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6625 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6626 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6627 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6628 emitpcode(POC_RRF, popGet(AOP(result),offr));
6638 /* note, use a mov/add for the shift since the mov has a
6639 chance of getting optimized out */
6640 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6641 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6642 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6643 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6644 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6648 emitpcode(POC_RLF, popGet(AOP(result),offr));
6649 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6655 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6656 emitpcode(POC_ANDLW, popGetLit(0xF0));
6657 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6659 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6660 emitpcode(POC_ANDLW, popGetLit(0xF0));
6661 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6662 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6666 emitpcode(POC_RLF, popGet(AOP(result),offr));
6667 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6671 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6672 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6673 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6674 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6676 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6677 emitpcode(POC_RRF, popGet(AOP(result),offr));
6678 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6679 emitpcode(POC_ANDLW,popGetLit(0xc0));
6680 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6681 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6682 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6683 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6686 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6687 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6688 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6689 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6690 emitpcode(POC_RRF, popGet(AOP(result),offr));
6695 /*-----------------------------------------------------------------*/
6696 /* shiftR2Left2Result - shift right two bytes from left to result */
6697 /*-----------------------------------------------------------------*/
6698 static void shiftR2Left2Result (operand *left, int offl,
6699 operand *result, int offr,
6700 int shCount, int sign)
6704 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6705 same = pic14_sameRegs(AOP(result), AOP(left));
6707 if(same && ((offl + MSB16) == offr)){
6709 /* don't crash result[offr] */
6710 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6711 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6713 movLeft2Result(left,offl, result, offr);
6714 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6716 /* a:x >> shCount (x = lsb(result))*/
6719 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6721 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6730 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRF,popGet(AOP(result),offr));
6738 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6739 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6740 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6741 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6746 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6749 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_RRF,popGet(AOP(result),offr));
6757 emitpcode(POC_MOVLW, popGetLit(0xf0));
6758 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6759 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6761 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6762 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6763 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6764 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6766 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6767 emitpcode(POC_ANDLW, popGetLit(0x0f));
6768 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6770 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6771 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6772 emitpcode(POC_ANDLW, popGetLit(0xf0));
6773 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6774 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6778 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6779 emitpcode(POC_RRF, popGet(AOP(result),offr));
6783 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6784 emitpcode(POC_BTFSC,
6785 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6786 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_RLF, popGet(AOP(result),offr));
6795 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6797 emitpcode(POC_RLF, popGet(AOP(result),offr));
6798 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6799 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6800 emitpcode(POC_ANDLW,popGetLit(0x03));
6802 emitpcode(POC_BTFSC,
6803 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6804 emitpcode(POC_IORLW,popGetLit(0xfc));
6806 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6807 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6811 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6812 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6813 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6814 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6815 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_ANDLW,popGetLit(0x03));
6818 emitpcode(POC_BTFSC,
6819 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6820 emitpcode(POC_IORLW,popGetLit(0xfc));
6822 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6823 emitpcode(POC_RLF, popGet(AOP(result),offr));
6830 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6831 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6832 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6833 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6836 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6838 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6843 /*-----------------------------------------------------------------*/
6844 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6845 /*-----------------------------------------------------------------*/
6846 static void shiftLLeftOrResult (operand *left, int offl,
6847 operand *result, int offr, int shCount)
6849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6850 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6851 /* shift left accumulator */
6853 /* or with result */
6854 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6855 /* back to result */
6856 aopPut(AOP(result),"a",offr);
6859 /*-----------------------------------------------------------------*/
6860 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6861 /*-----------------------------------------------------------------*/
6862 static void shiftRLeftOrResult (operand *left, int offl,
6863 operand *result, int offr, int shCount)
6865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6866 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6867 /* shift right accumulator */
6869 /* or with result */
6870 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6871 /* back to result */
6872 aopPut(AOP(result),"a",offr);
6875 /*-----------------------------------------------------------------*/
6876 /* genlshOne - left shift a one byte quantity by known count */
6877 /*-----------------------------------------------------------------*/
6878 static void genlshOne (operand *result, operand *left, int shCount)
6880 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6881 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6884 /*-----------------------------------------------------------------*/
6885 /* genlshTwo - left shift two bytes by known amount != 0 */
6886 /*-----------------------------------------------------------------*/
6887 static void genlshTwo (operand *result,operand *left, int shCount)
6891 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6892 size = pic14_getDataSize(result);
6894 /* if shCount >= 8 */
6900 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6902 movLeft2Result(left, LSB, result, MSB16);
6904 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6907 /* 1 <= shCount <= 7 */
6910 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6912 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6916 /*-----------------------------------------------------------------*/
6917 /* shiftLLong - shift left one long from left to result */
6918 /* offl = LSB or MSB16 */
6919 /*-----------------------------------------------------------------*/
6920 static void shiftLLong (operand *left, operand *result, int offr )
6923 int size = AOP_SIZE(result);
6925 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6926 if(size >= LSB+offr){
6927 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6929 pic14_emitcode("add","a,acc");
6930 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6931 size >= MSB16+offr && offr != LSB )
6932 pic14_emitcode("xch","a,%s",
6933 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6935 aopPut(AOP(result),"a",LSB+offr);
6938 if(size >= MSB16+offr){
6939 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6940 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6943 pic14_emitcode("rlc","a");
6944 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6945 size >= MSB24+offr && offr != LSB)
6946 pic14_emitcode("xch","a,%s",
6947 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6949 aopPut(AOP(result),"a",MSB16+offr);
6952 if(size >= MSB24+offr){
6953 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6954 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6957 pic14_emitcode("rlc","a");
6958 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6959 size >= MSB32+offr && offr != LSB )
6960 pic14_emitcode("xch","a,%s",
6961 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6963 aopPut(AOP(result),"a",MSB24+offr);
6966 if(size > MSB32+offr){
6967 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6968 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6971 pic14_emitcode("rlc","a");
6972 aopPut(AOP(result),"a",MSB32+offr);
6975 aopPut(AOP(result),zero,LSB);
6978 /*-----------------------------------------------------------------*/
6979 /* genlshFour - shift four byte by a known amount != 0 */
6980 /*-----------------------------------------------------------------*/
6981 static void genlshFour (operand *result, operand *left, int shCount)
6985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6986 size = AOP_SIZE(result);
6988 /* if shifting more that 3 bytes */
6989 if (shCount >= 24 ) {
6992 /* lowest order of left goes to the highest
6993 order of the destination */
6994 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6996 movLeft2Result(left, LSB, result, MSB32);
6997 aopPut(AOP(result),zero,LSB);
6998 aopPut(AOP(result),zero,MSB16);
6999 aopPut(AOP(result),zero,MSB32);
7003 /* more than two bytes */
7004 else if ( shCount >= 16 ) {
7005 /* lower order two bytes goes to higher order two bytes */
7007 /* if some more remaining */
7009 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7011 movLeft2Result(left, MSB16, result, MSB32);
7012 movLeft2Result(left, LSB, result, MSB24);
7014 aopPut(AOP(result),zero,MSB16);
7015 aopPut(AOP(result),zero,LSB);
7019 /* if more than 1 byte */
7020 else if ( shCount >= 8 ) {
7021 /* lower order three bytes goes to higher order three bytes */
7025 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7027 movLeft2Result(left, LSB, result, MSB16);
7029 else{ /* size = 4 */
7031 movLeft2Result(left, MSB24, result, MSB32);
7032 movLeft2Result(left, MSB16, result, MSB24);
7033 movLeft2Result(left, LSB, result, MSB16);
7034 aopPut(AOP(result),zero,LSB);
7036 else if(shCount == 1)
7037 shiftLLong(left, result, MSB16);
7039 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7040 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7041 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7042 aopPut(AOP(result),zero,LSB);
7047 /* 1 <= shCount <= 7 */
7048 else if(shCount <= 2){
7049 shiftLLong(left, result, LSB);
7051 shiftLLong(result, result, LSB);
7053 /* 3 <= shCount <= 7, optimize */
7055 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7056 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7057 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7061 /*-----------------------------------------------------------------*/
7062 /* genLeftShiftLiteral - left shifting by known count */
7063 /*-----------------------------------------------------------------*/
7064 static void genLeftShiftLiteral (operand *left,
7069 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7073 freeAsmop(right,NULL,ic,TRUE);
7075 aopOp(left,ic,FALSE);
7076 aopOp(result,ic,FALSE);
7078 size = getSize(operandType(result));
7081 pic14_emitcode("; shift left ","result %d, left %d",size,
7085 /* I suppose that the left size >= result size */
7088 movLeft2Result(left, size, result, size);
7092 else if(shCount >= (size * 8))
7094 aopPut(AOP(result),zero,size);
7098 genlshOne (result,left,shCount);
7103 genlshTwo (result,left,shCount);
7107 genlshFour (result,left,shCount);
7111 freeAsmop(left,NULL,ic,TRUE);
7112 freeAsmop(result,NULL,ic,TRUE);
7115 /*-----------------------------------------------------------------*
7116 * genMultiAsm - repeat assembly instruction for size of register.
7117 * if endian == 1, then the high byte (i.e base address + size of
7118 * register) is used first else the low byte is used first;
7119 *-----------------------------------------------------------------*/
7120 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7138 emitpcode(poc, popGet(AOP(reg),offset));
7143 /*-----------------------------------------------------------------*/
7144 /* genLeftShift - generates code for left shifting */
7145 /*-----------------------------------------------------------------*/
7146 static void genLeftShift (iCode *ic)
7148 operand *left,*right, *result;
7151 symbol *tlbl , *tlbl1;
7154 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7156 right = IC_RIGHT(ic);
7158 result = IC_RESULT(ic);
7160 aopOp(right,ic,FALSE);
7162 /* if the shift count is known then do it
7163 as efficiently as possible */
7164 if (AOP_TYPE(right) == AOP_LIT) {
7165 genLeftShiftLiteral (left,right,result,ic);
7169 /* shift count is unknown then we have to form
7170 a loop get the loop count in B : Note: we take
7171 only the lower order byte since shifting
7172 more that 32 bits make no sense anyway, ( the
7173 largest size of an object can be only 32 bits ) */
7176 aopOp(left,ic,FALSE);
7177 aopOp(result,ic,FALSE);
7179 /* now move the left to the result if they are not the
7181 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7182 AOP_SIZE(result) > 1) {
7184 size = AOP_SIZE(result);
7187 l = aopGet(AOP(left),offset,FALSE,TRUE);
7188 if (*l == '@' && (IS_AOP_PREG(result))) {
7190 pic14_emitcode("mov","a,%s",l);
7191 aopPut(AOP(result),"a",offset);
7193 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7194 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7195 //aopPut(AOP(result),l,offset);
7201 size = AOP_SIZE(result);
7203 /* if it is only one byte then */
7205 if(optimized_for_speed) {
7206 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7207 emitpcode(POC_ANDLW, popGetLit(0xf0));
7208 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7209 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7210 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7211 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7212 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7213 emitpcode(POC_RLFW, popGet(AOP(result),0));
7214 emitpcode(POC_ANDLW, popGetLit(0xfe));
7215 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7216 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7217 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7220 tlbl = newiTempLabel(NULL);
7221 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7222 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7223 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7226 emitpcode(POC_COMFW, popGet(AOP(right),0));
7227 emitpcode(POC_RRF, popGet(AOP(result),0));
7228 emitpLabel(tlbl->key);
7229 emitpcode(POC_RLF, popGet(AOP(result),0));
7230 emitpcode(POC_ADDLW, popGetLit(1));
7232 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7237 if (pic14_sameRegs(AOP(left),AOP(result))) {
7239 tlbl = newiTempLabel(NULL);
7240 emitpcode(POC_COMFW, popGet(AOP(right),0));
7241 genMultiAsm(POC_RRF, result, size,1);
7242 emitpLabel(tlbl->key);
7243 genMultiAsm(POC_RLF, result, size,0);
7244 emitpcode(POC_ADDLW, popGetLit(1));
7246 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7250 //tlbl = newiTempLabel(NULL);
7252 //tlbl1 = newiTempLabel(NULL);
7254 //reAdjustPreg(AOP(result));
7256 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7257 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7258 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7260 //pic14_emitcode("add","a,acc");
7261 //aopPut(AOP(result),"a",offset++);
7263 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7265 // pic14_emitcode("rlc","a");
7266 // aopPut(AOP(result),"a",offset++);
7268 //reAdjustPreg(AOP(result));
7270 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7271 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7274 tlbl = newiTempLabel(NULL);
7275 tlbl1= newiTempLabel(NULL);
7277 size = AOP_SIZE(result);
7280 pctemp = popGetTempReg(); /* grab a temporary working register. */
7282 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7284 /* offset should be 0, 1 or 3 */
7285 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7287 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7289 emitpcode(POC_MOVWF, pctemp);
7292 emitpLabel(tlbl->key);
7295 emitpcode(POC_RLF, popGet(AOP(result),0));
7297 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7299 emitpcode(POC_DECFSZ, pctemp);
7300 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7301 emitpLabel(tlbl1->key);
7303 popReleaseTempReg(pctemp);
7307 freeAsmop (right,NULL,ic,TRUE);
7308 freeAsmop(left,NULL,ic,TRUE);
7309 freeAsmop(result,NULL,ic,TRUE);
7312 /*-----------------------------------------------------------------*/
7313 /* genrshOne - right shift a one byte quantity by known count */
7314 /*-----------------------------------------------------------------*/
7315 static void genrshOne (operand *result, operand *left,
7316 int shCount, int sign)
7318 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7319 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7322 /*-----------------------------------------------------------------*/
7323 /* genrshTwo - right shift two bytes by known amount != 0 */
7324 /*-----------------------------------------------------------------*/
7325 static void genrshTwo (operand *result,operand *left,
7326 int shCount, int sign)
7328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7329 /* if shCount >= 8 */
7333 shiftR1Left2Result(left, MSB16, result, LSB,
7336 movLeft2Result(left, MSB16, result, LSB);
7338 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7341 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7342 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7346 /* 1 <= shCount <= 7 */
7348 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7351 /*-----------------------------------------------------------------*/
7352 /* shiftRLong - shift right one long from left to result */
7353 /* offl = LSB or MSB16 */
7354 /*-----------------------------------------------------------------*/
7355 static void shiftRLong (operand *left, int offl,
7356 operand *result, int sign)
7358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7360 pic14_emitcode("clr","c");
7361 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7363 pic14_emitcode("mov","c,acc.7");
7364 pic14_emitcode("rrc","a");
7365 aopPut(AOP(result),"a",MSB32-offl);
7367 /* add sign of "a" */
7368 addSign(result, MSB32, sign);
7370 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7371 pic14_emitcode("rrc","a");
7372 aopPut(AOP(result),"a",MSB24-offl);
7374 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7375 pic14_emitcode("rrc","a");
7376 aopPut(AOP(result),"a",MSB16-offl);
7379 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7380 pic14_emitcode("rrc","a");
7381 aopPut(AOP(result),"a",LSB);
7385 /*-----------------------------------------------------------------*/
7386 /* genrshFour - shift four byte by a known amount != 0 */
7387 /*-----------------------------------------------------------------*/
7388 static void genrshFour (operand *result, operand *left,
7389 int shCount, int sign)
7391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7392 /* if shifting more that 3 bytes */
7393 if(shCount >= 24 ) {
7396 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7398 movLeft2Result(left, MSB32, result, LSB);
7400 addSign(result, MSB16, sign);
7402 else if(shCount >= 16){
7405 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7407 movLeft2Result(left, MSB24, result, LSB);
7408 movLeft2Result(left, MSB32, result, MSB16);
7410 addSign(result, MSB24, sign);
7412 else if(shCount >= 8){
7415 shiftRLong(left, MSB16, result, sign);
7416 else if(shCount == 0){
7417 movLeft2Result(left, MSB16, result, LSB);
7418 movLeft2Result(left, MSB24, result, MSB16);
7419 movLeft2Result(left, MSB32, result, MSB24);
7420 addSign(result, MSB32, sign);
7423 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7424 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7425 /* the last shift is signed */
7426 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7427 addSign(result, MSB32, sign);
7430 else{ /* 1 <= shCount <= 7 */
7432 shiftRLong(left, LSB, result, sign);
7434 shiftRLong(result, LSB, result, sign);
7437 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7438 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7439 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7444 /*-----------------------------------------------------------------*/
7445 /* genRightShiftLiteral - right shifting by known count */
7446 /*-----------------------------------------------------------------*/
7447 static void genRightShiftLiteral (operand *left,
7453 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7457 freeAsmop(right,NULL,ic,TRUE);
7459 aopOp(left,ic,FALSE);
7460 aopOp(result,ic,FALSE);
7463 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7467 lsize = pic14_getDataSize(left);
7468 res_size = pic14_getDataSize(result);
7469 /* test the LEFT size !!! */
7471 /* I suppose that the left size >= result size */
7474 movLeft2Result(left, lsize, result, res_size);
7477 else if(shCount >= (lsize * 8)){
7480 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7482 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7483 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7488 emitpcode(POC_MOVLW, popGetLit(0));
7489 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7490 emitpcode(POC_MOVLW, popGetLit(0xff));
7492 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7497 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7504 genrshOne (result,left,shCount,sign);
7508 genrshTwo (result,left,shCount,sign);
7512 genrshFour (result,left,shCount,sign);
7520 freeAsmop(left,NULL,ic,TRUE);
7521 freeAsmop(result,NULL,ic,TRUE);
7524 /*-----------------------------------------------------------------*/
7525 /* genSignedRightShift - right shift of signed number */
7526 /*-----------------------------------------------------------------*/
7527 static void genSignedRightShift (iCode *ic)
7529 operand *right, *left, *result;
7532 symbol *tlbl, *tlbl1 ;
7535 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7537 /* we do it the hard way put the shift count in b
7538 and loop thru preserving the sign */
7539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7541 right = IC_RIGHT(ic);
7543 result = IC_RESULT(ic);
7545 aopOp(right,ic,FALSE);
7546 aopOp(left,ic,FALSE);
7547 aopOp(result,ic,FALSE);
7550 if ( AOP_TYPE(right) == AOP_LIT) {
7551 genRightShiftLiteral (left,right,result,ic,1);
7554 /* shift count is unknown then we have to form
7555 a loop get the loop count in B : Note: we take
7556 only the lower order byte since shifting
7557 more that 32 bits make no sense anyway, ( the
7558 largest size of an object can be only 32 bits ) */
7560 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7561 //pic14_emitcode("inc","b");
7562 //freeAsmop (right,NULL,ic,TRUE);
7563 //aopOp(left,ic,FALSE);
7564 //aopOp(result,ic,FALSE);
7566 /* now move the left to the result if they are not the
7568 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7569 AOP_SIZE(result) > 1) {
7571 size = AOP_SIZE(result);
7575 l = aopGet(AOP(left),offset,FALSE,TRUE);
7576 if (*l == '@' && IS_AOP_PREG(result)) {
7578 pic14_emitcode("mov","a,%s",l);
7579 aopPut(AOP(result),"a",offset);
7581 aopPut(AOP(result),l,offset);
7583 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7584 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7590 /* mov the highest order bit to OVR */
7591 tlbl = newiTempLabel(NULL);
7592 tlbl1= newiTempLabel(NULL);
7594 size = AOP_SIZE(result);
7597 pctemp = popGetTempReg(); /* grab a temporary working register. */
7599 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7601 /* offset should be 0, 1 or 3 */
7602 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7604 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7606 emitpcode(POC_MOVWF, pctemp);
7609 emitpLabel(tlbl->key);
7611 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7612 emitpcode(POC_RRF, popGet(AOP(result),offset));
7615 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7618 emitpcode(POC_DECFSZ, pctemp);
7619 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7620 emitpLabel(tlbl1->key);
7622 popReleaseTempReg(pctemp);
7624 size = AOP_SIZE(result);
7626 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7627 pic14_emitcode("rlc","a");
7628 pic14_emitcode("mov","ov,c");
7629 /* if it is only one byte then */
7631 l = aopGet(AOP(left),0,FALSE,FALSE);
7633 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7634 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7635 pic14_emitcode("mov","c,ov");
7636 pic14_emitcode("rrc","a");
7637 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7638 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7639 aopPut(AOP(result),"a",0);
7643 reAdjustPreg(AOP(result));
7644 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7645 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7646 pic14_emitcode("mov","c,ov");
7648 l = aopGet(AOP(result),offset,FALSE,FALSE);
7650 pic14_emitcode("rrc","a");
7651 aopPut(AOP(result),"a",offset--);
7653 reAdjustPreg(AOP(result));
7654 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7655 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7660 freeAsmop(left,NULL,ic,TRUE);
7661 freeAsmop(result,NULL,ic,TRUE);
7662 freeAsmop(right,NULL,ic,TRUE);
7665 /*-----------------------------------------------------------------*/
7666 /* genRightShift - generate code for right shifting */
7667 /*-----------------------------------------------------------------*/
7668 static void genRightShift (iCode *ic)
7670 operand *right, *left, *result;
7674 symbol *tlbl, *tlbl1 ;
7676 /* if signed then we do it the hard way preserve the
7677 sign bit moving it inwards */
7678 retype = getSpec(operandType(IC_RESULT(ic)));
7679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7681 if (!SPEC_USIGN(retype)) {
7682 genSignedRightShift (ic);
7686 /* signed & unsigned types are treated the same : i.e. the
7687 signed is NOT propagated inwards : quoting from the
7688 ANSI - standard : "for E1 >> E2, is equivalent to division
7689 by 2**E2 if unsigned or if it has a non-negative value,
7690 otherwise the result is implementation defined ", MY definition
7691 is that the sign does not get propagated */
7693 right = IC_RIGHT(ic);
7695 result = IC_RESULT(ic);
7697 aopOp(right,ic,FALSE);
7699 /* if the shift count is known then do it
7700 as efficiently as possible */
7701 if (AOP_TYPE(right) == AOP_LIT) {
7702 genRightShiftLiteral (left,right,result,ic, 0);
7706 /* shift count is unknown then we have to form
7707 a loop get the loop count in B : Note: we take
7708 only the lower order byte since shifting
7709 more that 32 bits make no sense anyway, ( the
7710 largest size of an object can be only 32 bits ) */
7712 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7713 pic14_emitcode("inc","b");
7714 aopOp(left,ic,FALSE);
7715 aopOp(result,ic,FALSE);
7717 /* now move the left to the result if they are not the
7719 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7720 AOP_SIZE(result) > 1) {
7722 size = AOP_SIZE(result);
7725 l = aopGet(AOP(left),offset,FALSE,TRUE);
7726 if (*l == '@' && IS_AOP_PREG(result)) {
7728 pic14_emitcode("mov","a,%s",l);
7729 aopPut(AOP(result),"a",offset);
7731 aopPut(AOP(result),l,offset);
7736 tlbl = newiTempLabel(NULL);
7737 tlbl1= newiTempLabel(NULL);
7738 size = AOP_SIZE(result);
7741 /* if it is only one byte then */
7744 tlbl = newiTempLabel(NULL);
7745 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7746 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7747 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7750 emitpcode(POC_COMFW, popGet(AOP(right),0));
7751 emitpcode(POC_RLF, popGet(AOP(result),0));
7752 emitpLabel(tlbl->key);
7753 emitpcode(POC_RRF, popGet(AOP(result),0));
7754 emitpcode(POC_ADDLW, popGetLit(1));
7756 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7761 reAdjustPreg(AOP(result));
7762 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7763 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7766 l = aopGet(AOP(result),offset,FALSE,FALSE);
7768 pic14_emitcode("rrc","a");
7769 aopPut(AOP(result),"a",offset--);
7771 reAdjustPreg(AOP(result));
7773 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7774 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7777 freeAsmop(left,NULL,ic,TRUE);
7778 freeAsmop (right,NULL,ic,TRUE);
7779 freeAsmop(result,NULL,ic,TRUE);
7782 /*-----------------------------------------------------------------*/
7783 /* genUnpackBits - generates code for unpacking bits */
7784 /*-----------------------------------------------------------------*/
7785 static void genUnpackBits (operand *result, char *rname, int ptype)
7792 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7793 etype = getSpec(operandType(result));
7795 /* read the first byte */
7800 pic14_emitcode("mov","a,@%s",rname);
7804 pic14_emitcode("movx","a,@%s",rname);
7808 pic14_emitcode("movx","a,@dptr");
7812 pic14_emitcode("clr","a");
7813 pic14_emitcode("movc","a","@a+dptr");
7817 pic14_emitcode("lcall","__gptrget");
7821 /* if we have bitdisplacement then it fits */
7822 /* into this byte completely or if length is */
7823 /* less than a byte */
7824 if ((shCnt = SPEC_BSTR(etype)) ||
7825 (SPEC_BLEN(etype) <= 8)) {
7827 /* shift right acc */
7830 pic14_emitcode("anl","a,#0x%02x",
7831 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7832 aopPut(AOP(result),"a",offset);
7836 /* bit field did not fit in a byte */
7837 rlen = SPEC_BLEN(etype) - 8;
7838 aopPut(AOP(result),"a",offset++);
7845 pic14_emitcode("inc","%s",rname);
7846 pic14_emitcode("mov","a,@%s",rname);
7850 pic14_emitcode("inc","%s",rname);
7851 pic14_emitcode("movx","a,@%s",rname);
7855 pic14_emitcode("inc","dptr");
7856 pic14_emitcode("movx","a,@dptr");
7860 pic14_emitcode("clr","a");
7861 pic14_emitcode("inc","dptr");
7862 pic14_emitcode("movc","a","@a+dptr");
7866 pic14_emitcode("inc","dptr");
7867 pic14_emitcode("lcall","__gptrget");
7872 /* if we are done */
7876 aopPut(AOP(result),"a",offset++);
7881 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7882 aopPut(AOP(result),"a",offset);
7889 /*-----------------------------------------------------------------*/
7890 /* genDataPointerGet - generates code when ptr offset is known */
7891 /*-----------------------------------------------------------------*/
7892 static void genDataPointerGet (operand *left,
7896 int size , offset = 0;
7899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7902 /* optimization - most of the time, left and result are the same
7903 * address, but different types. for the pic code, we could omit
7907 aopOp(result,ic,TRUE);
7909 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7911 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7913 size = AOP_SIZE(result);
7916 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7920 freeAsmop(left,NULL,ic,TRUE);
7921 freeAsmop(result,NULL,ic,TRUE);
7924 /*-----------------------------------------------------------------*/
7925 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7926 /*-----------------------------------------------------------------*/
7927 static void genNearPointerGet (operand *left,
7934 sym_link *rtype, *retype;
7935 sym_link *ltype = operandType(left);
7938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7940 rtype = operandType(result);
7941 retype= getSpec(rtype);
7943 aopOp(left,ic,FALSE);
7945 /* if left is rematerialisable and
7946 result is not bit variable type and
7947 the left is pointer to data space i.e
7948 lower 128 bytes of space */
7949 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7950 !IS_BITVAR(retype) &&
7951 DCL_TYPE(ltype) == POINTER) {
7952 //genDataPointerGet (left,result,ic);
7956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7958 /* if the value is already in a pointer register
7959 then don't need anything more */
7960 if (!AOP_INPREG(AOP(left))) {
7961 /* otherwise get a free pointer register */
7962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7965 preg = getFreePtr(ic,&aop,FALSE);
7966 pic14_emitcode("mov","%s,%s",
7968 aopGet(AOP(left),0,FALSE,TRUE));
7969 rname = preg->name ;
7973 rname = aopGet(AOP(left),0,FALSE,FALSE);
7975 aopOp (result,ic,FALSE);
7977 /* if bitfield then unpack the bits */
7978 if (IS_BITVAR(retype))
7979 genUnpackBits (result,rname,POINTER);
7981 /* we have can just get the values */
7982 int size = AOP_SIZE(result);
7985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7987 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7988 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7990 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7991 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7993 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7997 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7999 pic14_emitcode("mov","a,@%s",rname);
8000 aopPut(AOP(result),"a",offset);
8002 sprintf(buffer,"@%s",rname);
8003 aopPut(AOP(result),buffer,offset);
8007 pic14_emitcode("inc","%s",rname);
8012 /* now some housekeeping stuff */
8014 /* we had to allocate for this iCode */
8015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8016 freeAsmop(NULL,aop,ic,TRUE);
8018 /* we did not allocate which means left
8019 already in a pointer register, then
8020 if size > 0 && this could be used again
8021 we have to point it back to where it
8023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8024 if (AOP_SIZE(result) > 1 &&
8025 !OP_SYMBOL(left)->remat &&
8026 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8028 int size = AOP_SIZE(result) - 1;
8030 pic14_emitcode("dec","%s",rname);
8035 freeAsmop(left,NULL,ic,TRUE);
8036 freeAsmop(result,NULL,ic,TRUE);
8040 /*-----------------------------------------------------------------*/
8041 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8042 /*-----------------------------------------------------------------*/
8043 static void genPagedPointerGet (operand *left,
8050 sym_link *rtype, *retype;
8052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8054 rtype = operandType(result);
8055 retype= getSpec(rtype);
8057 aopOp(left,ic,FALSE);
8059 /* if the value is already in a pointer register
8060 then don't need anything more */
8061 if (!AOP_INPREG(AOP(left))) {
8062 /* otherwise get a free pointer register */
8064 preg = getFreePtr(ic,&aop,FALSE);
8065 pic14_emitcode("mov","%s,%s",
8067 aopGet(AOP(left),0,FALSE,TRUE));
8068 rname = preg->name ;
8070 rname = aopGet(AOP(left),0,FALSE,FALSE);
8072 freeAsmop(left,NULL,ic,TRUE);
8073 aopOp (result,ic,FALSE);
8075 /* if bitfield then unpack the bits */
8076 if (IS_BITVAR(retype))
8077 genUnpackBits (result,rname,PPOINTER);
8079 /* we have can just get the values */
8080 int size = AOP_SIZE(result);
8085 pic14_emitcode("movx","a,@%s",rname);
8086 aopPut(AOP(result),"a",offset);
8091 pic14_emitcode("inc","%s",rname);
8095 /* now some housekeeping stuff */
8097 /* we had to allocate for this iCode */
8098 freeAsmop(NULL,aop,ic,TRUE);
8100 /* we did not allocate which means left
8101 already in a pointer register, then
8102 if size > 0 && this could be used again
8103 we have to point it back to where it
8105 if (AOP_SIZE(result) > 1 &&
8106 !OP_SYMBOL(left)->remat &&
8107 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8109 int size = AOP_SIZE(result) - 1;
8111 pic14_emitcode("dec","%s",rname);
8116 freeAsmop(result,NULL,ic,TRUE);
8121 /*-----------------------------------------------------------------*/
8122 /* genFarPointerGet - gget value from far space */
8123 /*-----------------------------------------------------------------*/
8124 static void genFarPointerGet (operand *left,
8125 operand *result, iCode *ic)
8128 sym_link *retype = getSpec(operandType(result));
8130 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8132 aopOp(left,ic,FALSE);
8134 /* if the operand is already in dptr
8135 then we do nothing else we move the value to dptr */
8136 if (AOP_TYPE(left) != AOP_STR) {
8137 /* if this is remateriazable */
8138 if (AOP_TYPE(left) == AOP_IMMD)
8139 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8140 else { /* we need to get it byte by byte */
8141 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8142 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8143 if (options.model == MODEL_FLAT24)
8145 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8149 /* so dptr know contains the address */
8150 freeAsmop(left,NULL,ic,TRUE);
8151 aopOp(result,ic,FALSE);
8153 /* if bit then unpack */
8154 if (IS_BITVAR(retype))
8155 genUnpackBits(result,"dptr",FPOINTER);
8157 size = AOP_SIZE(result);
8161 pic14_emitcode("movx","a,@dptr");
8162 aopPut(AOP(result),"a",offset++);
8164 pic14_emitcode("inc","dptr");
8168 freeAsmop(result,NULL,ic,TRUE);
8171 /*-----------------------------------------------------------------*/
8172 /* genCodePointerGet - get value from code space */
8173 /*-----------------------------------------------------------------*/
8174 static void genCodePointerGet (operand *left,
8175 operand *result, iCode *ic)
8178 sym_link *retype = getSpec(operandType(result));
8180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8182 aopOp(left,ic,FALSE);
8184 /* if the operand is already in dptr
8185 then we do nothing else we move the value to dptr */
8186 if (AOP_TYPE(left) != AOP_STR) {
8187 /* if this is remateriazable */
8188 if (AOP_TYPE(left) == AOP_IMMD)
8189 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8190 else { /* we need to get it byte by byte */
8191 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8192 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8193 if (options.model == MODEL_FLAT24)
8195 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8199 /* so dptr know contains the address */
8200 freeAsmop(left,NULL,ic,TRUE);
8201 aopOp(result,ic,FALSE);
8203 /* if bit then unpack */
8204 if (IS_BITVAR(retype))
8205 genUnpackBits(result,"dptr",CPOINTER);
8207 size = AOP_SIZE(result);
8211 pic14_emitcode("clr","a");
8212 pic14_emitcode("movc","a,@a+dptr");
8213 aopPut(AOP(result),"a",offset++);
8215 pic14_emitcode("inc","dptr");
8219 freeAsmop(result,NULL,ic,TRUE);
8222 /*-----------------------------------------------------------------*/
8223 /* genGenPointerGet - gget value from generic pointer space */
8224 /*-----------------------------------------------------------------*/
8225 static void genGenPointerGet (operand *left,
8226 operand *result, iCode *ic)
8229 sym_link *retype = getSpec(operandType(result));
8231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8232 aopOp(left,ic,FALSE);
8233 aopOp(result,ic,FALSE);
8236 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8238 /* if the operand is already in dptr
8239 then we do nothing else we move the value to dptr */
8240 // if (AOP_TYPE(left) != AOP_STR) {
8241 /* if this is remateriazable */
8242 if (AOP_TYPE(left) == AOP_IMMD) {
8243 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8244 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8246 else { /* we need to get it byte by byte */
8248 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8249 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8251 size = AOP_SIZE(result);
8255 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8256 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8258 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8263 /* so dptr know contains the address */
8265 /* if bit then unpack */
8266 //if (IS_BITVAR(retype))
8267 // genUnpackBits(result,"dptr",GPOINTER);
8270 freeAsmop(left,NULL,ic,TRUE);
8271 freeAsmop(result,NULL,ic,TRUE);
8275 /*-----------------------------------------------------------------*/
8276 /* genConstPointerGet - get value from const generic pointer space */
8277 /*-----------------------------------------------------------------*/
8278 static void genConstPointerGet (operand *left,
8279 operand *result, iCode *ic)
8281 //sym_link *retype = getSpec(operandType(result));
8282 symbol *albl = newiTempLabel(NULL);
8283 symbol *blbl = newiTempLabel(NULL);
8286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8287 aopOp(left,ic,FALSE);
8288 aopOp(result,ic,FALSE);
8291 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8293 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8295 emitpcode(POC_CALL,popGetLabel(albl->key));
8296 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8297 emitpLabel(albl->key);
8299 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8301 emitpcode(poc,popGet(AOP(left),1));
8302 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8303 emitpcode(poc,popGet(AOP(left),0));
8304 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8306 emitpLabel(blbl->key);
8308 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8311 freeAsmop(left,NULL,ic,TRUE);
8312 freeAsmop(result,NULL,ic,TRUE);
8315 /*-----------------------------------------------------------------*/
8316 /* genPointerGet - generate code for pointer get */
8317 /*-----------------------------------------------------------------*/
8318 static void genPointerGet (iCode *ic)
8320 operand *left, *result ;
8321 sym_link *type, *etype;
8324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8327 result = IC_RESULT(ic) ;
8329 /* depending on the type of pointer we need to
8330 move it to the correct pointer register */
8331 type = operandType(left);
8332 etype = getSpec(type);
8334 if (IS_PTR_CONST(type))
8335 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8337 /* if left is of type of pointer then it is simple */
8338 if (IS_PTR(type) && !IS_FUNC(type->next))
8339 p_type = DCL_TYPE(type);
8341 /* we have to go by the storage class */
8342 p_type = PTR_TYPE(SPEC_OCLS(etype));
8344 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8346 if (SPEC_OCLS(etype)->codesp ) {
8347 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8348 //p_type = CPOINTER ;
8351 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8352 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8353 /*p_type = FPOINTER ;*/
8355 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8356 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8357 /* p_type = PPOINTER; */
8359 if (SPEC_OCLS(etype) == idata )
8360 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8361 /* p_type = IPOINTER; */
8363 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8364 /* p_type = POINTER ; */
8367 /* now that we have the pointer type we assign
8368 the pointer values */
8373 genNearPointerGet (left,result,ic);
8377 genPagedPointerGet(left,result,ic);
8381 genFarPointerGet (left,result,ic);
8385 genConstPointerGet (left,result,ic);
8386 //pic14_emitcodePointerGet (left,result,ic);
8390 if (IS_PTR_CONST(type))
8391 genConstPointerGet (left,result,ic);
8393 genGenPointerGet (left,result,ic);
8399 /*-----------------------------------------------------------------*/
8400 /* genPackBits - generates code for packed bit storage */
8401 /*-----------------------------------------------------------------*/
8402 static void genPackBits (sym_link *etype ,
8404 char *rname, int p_type)
8412 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8413 blen = SPEC_BLEN(etype);
8414 bstr = SPEC_BSTR(etype);
8416 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8419 /* if the bit lenth is less than or */
8420 /* it exactly fits a byte then */
8421 if (SPEC_BLEN(etype) <= 8 ) {
8422 shCount = SPEC_BSTR(etype) ;
8424 /* shift left acc */
8427 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8432 pic14_emitcode ("mov","b,a");
8433 pic14_emitcode("mov","a,@%s",rname);
8437 pic14_emitcode ("mov","b,a");
8438 pic14_emitcode("movx","a,@dptr");
8442 pic14_emitcode ("push","b");
8443 pic14_emitcode ("push","acc");
8444 pic14_emitcode ("lcall","__gptrget");
8445 pic14_emitcode ("pop","b");
8449 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8450 ((unsigned char)(0xFF << (blen+bstr)) |
8451 (unsigned char)(0xFF >> (8-bstr)) ) );
8452 pic14_emitcode ("orl","a,b");
8453 if (p_type == GPOINTER)
8454 pic14_emitcode("pop","b");
8460 pic14_emitcode("mov","@%s,a",rname);
8464 pic14_emitcode("movx","@dptr,a");
8468 DEBUGpic14_emitcode(";lcall","__gptrput");
8473 if ( SPEC_BLEN(etype) <= 8 )
8476 pic14_emitcode("inc","%s",rname);
8477 rLen = SPEC_BLEN(etype) ;
8479 /* now generate for lengths greater than one byte */
8482 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8492 pic14_emitcode("mov","@%s,a",rname);
8494 pic14_emitcode("mov","@%s,%s",rname,l);
8499 pic14_emitcode("movx","@dptr,a");
8504 DEBUGpic14_emitcode(";lcall","__gptrput");
8507 pic14_emitcode ("inc","%s",rname);
8512 /* last last was not complete */
8514 /* save the byte & read byte */
8517 pic14_emitcode ("mov","b,a");
8518 pic14_emitcode("mov","a,@%s",rname);
8522 pic14_emitcode ("mov","b,a");
8523 pic14_emitcode("movx","a,@dptr");
8527 pic14_emitcode ("push","b");
8528 pic14_emitcode ("push","acc");
8529 pic14_emitcode ("lcall","__gptrget");
8530 pic14_emitcode ("pop","b");
8534 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8535 pic14_emitcode ("orl","a,b");
8538 if (p_type == GPOINTER)
8539 pic14_emitcode("pop","b");
8544 pic14_emitcode("mov","@%s,a",rname);
8548 pic14_emitcode("movx","@dptr,a");
8552 DEBUGpic14_emitcode(";lcall","__gptrput");
8556 /*-----------------------------------------------------------------*/
8557 /* genDataPointerSet - remat pointer to data space */
8558 /*-----------------------------------------------------------------*/
8559 static void genDataPointerSet(operand *right,
8563 int size, offset = 0 ;
8564 char *l, buffer[256];
8566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8567 aopOp(right,ic,FALSE);
8569 l = aopGet(AOP(result),0,FALSE,TRUE);
8570 size = AOP_SIZE(right);
8572 if ( AOP_TYPE(result) == AOP_PCODE) {
8573 fprintf(stderr,"genDataPointerSet %s, %d\n",
8574 AOP(result)->aopu.pcop->name,
8575 PCOI(AOP(result)->aopu.pcop)->offset);
8579 // tsd, was l+1 - the underline `_' prefix was being stripped
8582 sprintf(buffer,"(%s + %d)",l,offset);
8583 fprintf(stderr,"oops %s\n",buffer);
8585 sprintf(buffer,"%s",l);
8587 if (AOP_TYPE(right) == AOP_LIT) {
8588 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8589 lit = lit >> (8*offset);
8591 pic14_emitcode("movlw","%d",lit);
8592 pic14_emitcode("movwf","%s",buffer);
8594 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8595 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8596 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8599 pic14_emitcode("clrf","%s",buffer);
8600 //emitpcode(POC_CLRF, popRegFromString(buffer));
8601 emitpcode(POC_CLRF, popGet(AOP(result),0));
8604 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8605 pic14_emitcode("movwf","%s",buffer);
8607 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8608 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8609 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8616 freeAsmop(right,NULL,ic,TRUE);
8617 freeAsmop(result,NULL,ic,TRUE);
8620 /*-----------------------------------------------------------------*/
8621 /* genNearPointerSet - pic14_emitcode for near pointer put */
8622 /*-----------------------------------------------------------------*/
8623 static void genNearPointerSet (operand *right,
8630 sym_link *ptype = operandType(result);
8633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8634 retype= getSpec(operandType(right));
8636 aopOp(result,ic,FALSE);
8639 /* if the result is rematerializable &
8640 in data space & not a bit variable */
8641 //if (AOP_TYPE(result) == AOP_IMMD &&
8642 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8643 DCL_TYPE(ptype) == POINTER &&
8644 !IS_BITVAR(retype)) {
8645 genDataPointerSet (right,result,ic);
8646 freeAsmop(result,NULL,ic,TRUE);
8650 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8651 aopOp(right,ic,FALSE);
8652 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8654 /* if the value is already in a pointer register
8655 then don't need anything more */
8656 if (!AOP_INPREG(AOP(result))) {
8657 /* otherwise get a free pointer register */
8658 //aop = newAsmop(0);
8659 //preg = getFreePtr(ic,&aop,FALSE);
8660 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8661 //pic14_emitcode("mov","%s,%s",
8663 // aopGet(AOP(result),0,FALSE,TRUE));
8664 //rname = preg->name ;
8665 //pic14_emitcode("movwf","fsr");
8666 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8667 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8668 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8669 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8673 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8676 /* if bitfield then unpack the bits */
8677 if (IS_BITVAR(retype)) {
8678 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8679 "The programmer is obviously confused");
8680 //genPackBits (retype,right,rname,POINTER);
8684 /* we have can just get the values */
8685 int size = AOP_SIZE(right);
8688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8690 l = aopGet(AOP(right),offset,FALSE,TRUE);
8693 //pic14_emitcode("mov","@%s,a",rname);
8694 pic14_emitcode("movf","indf,w ;1");
8697 if (AOP_TYPE(right) == AOP_LIT) {
8698 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8700 pic14_emitcode("movlw","%s",l);
8701 pic14_emitcode("movwf","indf ;2");
8703 pic14_emitcode("clrf","indf");
8705 pic14_emitcode("movf","%s,w",l);
8706 pic14_emitcode("movwf","indf ;2");
8708 //pic14_emitcode("mov","@%s,%s",rname,l);
8711 pic14_emitcode("incf","fsr,f ;3");
8712 //pic14_emitcode("inc","%s",rname);
8717 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8718 /* now some housekeeping stuff */
8720 /* we had to allocate for this iCode */
8721 freeAsmop(NULL,aop,ic,TRUE);
8723 /* we did not allocate which means left
8724 already in a pointer register, then
8725 if size > 0 && this could be used again
8726 we have to point it back to where it
8728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8729 if (AOP_SIZE(right) > 1 &&
8730 !OP_SYMBOL(result)->remat &&
8731 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8733 int size = AOP_SIZE(right) - 1;
8735 pic14_emitcode("decf","fsr,f");
8736 //pic14_emitcode("dec","%s",rname);
8740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8743 freeAsmop(right,NULL,ic,TRUE);
8744 freeAsmop(result,NULL,ic,TRUE);
8747 /*-----------------------------------------------------------------*/
8748 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8749 /*-----------------------------------------------------------------*/
8750 static void genPagedPointerSet (operand *right,
8759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8761 retype= getSpec(operandType(right));
8763 aopOp(result,ic,FALSE);
8765 /* if the value is already in a pointer register
8766 then don't need anything more */
8767 if (!AOP_INPREG(AOP(result))) {
8768 /* otherwise get a free pointer register */
8770 preg = getFreePtr(ic,&aop,FALSE);
8771 pic14_emitcode("mov","%s,%s",
8773 aopGet(AOP(result),0,FALSE,TRUE));
8774 rname = preg->name ;
8776 rname = aopGet(AOP(result),0,FALSE,FALSE);
8778 freeAsmop(result,NULL,ic,TRUE);
8779 aopOp (right,ic,FALSE);
8781 /* if bitfield then unpack the bits */
8782 if (IS_BITVAR(retype))
8783 genPackBits (retype,right,rname,PPOINTER);
8785 /* we have can just get the values */
8786 int size = AOP_SIZE(right);
8790 l = aopGet(AOP(right),offset,FALSE,TRUE);
8793 pic14_emitcode("movx","@%s,a",rname);
8796 pic14_emitcode("inc","%s",rname);
8802 /* now some housekeeping stuff */
8804 /* we had to allocate for this iCode */
8805 freeAsmop(NULL,aop,ic,TRUE);
8807 /* we did not allocate which means left
8808 already in a pointer register, then
8809 if size > 0 && this could be used again
8810 we have to point it back to where it
8812 if (AOP_SIZE(right) > 1 &&
8813 !OP_SYMBOL(result)->remat &&
8814 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8816 int size = AOP_SIZE(right) - 1;
8818 pic14_emitcode("dec","%s",rname);
8823 freeAsmop(right,NULL,ic,TRUE);
8828 /*-----------------------------------------------------------------*/
8829 /* genFarPointerSet - set value from far space */
8830 /*-----------------------------------------------------------------*/
8831 static void genFarPointerSet (operand *right,
8832 operand *result, iCode *ic)
8835 sym_link *retype = getSpec(operandType(right));
8837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8838 aopOp(result,ic,FALSE);
8840 /* if the operand is already in dptr
8841 then we do nothing else we move the value to dptr */
8842 if (AOP_TYPE(result) != AOP_STR) {
8843 /* if this is remateriazable */
8844 if (AOP_TYPE(result) == AOP_IMMD)
8845 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8846 else { /* we need to get it byte by byte */
8847 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8848 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8849 if (options.model == MODEL_FLAT24)
8851 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8855 /* so dptr know contains the address */
8856 freeAsmop(result,NULL,ic,TRUE);
8857 aopOp(right,ic,FALSE);
8859 /* if bit then unpack */
8860 if (IS_BITVAR(retype))
8861 genPackBits(retype,right,"dptr",FPOINTER);
8863 size = AOP_SIZE(right);
8867 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8869 pic14_emitcode("movx","@dptr,a");
8871 pic14_emitcode("inc","dptr");
8875 freeAsmop(right,NULL,ic,TRUE);
8878 /*-----------------------------------------------------------------*/
8879 /* genGenPointerSet - set value from generic pointer space */
8880 /*-----------------------------------------------------------------*/
8881 static void genGenPointerSet (operand *right,
8882 operand *result, iCode *ic)
8885 sym_link *retype = getSpec(operandType(right));
8887 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8889 aopOp(result,ic,FALSE);
8890 aopOp(right,ic,FALSE);
8891 size = AOP_SIZE(right);
8893 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8895 /* if the operand is already in dptr
8896 then we do nothing else we move the value to dptr */
8897 if (AOP_TYPE(result) != AOP_STR) {
8898 /* if this is remateriazable */
8899 if (AOP_TYPE(result) == AOP_IMMD) {
8900 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8901 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8903 else { /* we need to get it byte by byte */
8904 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8905 size = AOP_SIZE(right);
8908 /* hack hack! see if this the FSR. If so don't load W */
8909 if(AOP_TYPE(right) != AOP_ACC) {
8911 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8912 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8915 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8917 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8918 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8922 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8923 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8926 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8933 if(aopIdx(AOP(result),0) != 4) {
8935 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8939 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8944 /* so dptr know contains the address */
8947 /* if bit then unpack */
8948 if (IS_BITVAR(retype))
8949 genPackBits(retype,right,"dptr",GPOINTER);
8951 size = AOP_SIZE(right);
8954 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8958 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8959 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8961 if (AOP_TYPE(right) == AOP_LIT)
8962 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8964 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8966 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8973 freeAsmop(right,NULL,ic,TRUE);
8974 freeAsmop(result,NULL,ic,TRUE);
8977 /*-----------------------------------------------------------------*/
8978 /* genPointerSet - stores the value into a pointer location */
8979 /*-----------------------------------------------------------------*/
8980 static void genPointerSet (iCode *ic)
8982 operand *right, *result ;
8983 sym_link *type, *etype;
8986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8988 right = IC_RIGHT(ic);
8989 result = IC_RESULT(ic) ;
8991 /* depending on the type of pointer we need to
8992 move it to the correct pointer register */
8993 type = operandType(result);
8994 etype = getSpec(type);
8995 /* if left is of type of pointer then it is simple */
8996 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8997 p_type = DCL_TYPE(type);
9000 /* we have to go by the storage class */
9001 p_type = PTR_TYPE(SPEC_OCLS(etype));
9003 /* if (SPEC_OCLS(etype)->codesp ) { */
9004 /* p_type = CPOINTER ; */
9007 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9008 /* p_type = FPOINTER ; */
9010 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9011 /* p_type = PPOINTER ; */
9013 /* if (SPEC_OCLS(etype) == idata ) */
9014 /* p_type = IPOINTER ; */
9016 /* p_type = POINTER ; */
9019 /* now that we have the pointer type we assign
9020 the pointer values */
9025 genNearPointerSet (right,result,ic);
9029 genPagedPointerSet (right,result,ic);
9033 genFarPointerSet (right,result,ic);
9037 genGenPointerSet (right,result,ic);
9041 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9042 "genPointerSet: illegal pointer type");
9046 /*-----------------------------------------------------------------*/
9047 /* genIfx - generate code for Ifx statement */
9048 /*-----------------------------------------------------------------*/
9049 static void genIfx (iCode *ic, iCode *popIc)
9051 operand *cond = IC_COND(ic);
9054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9056 aopOp(cond,ic,FALSE);
9058 /* get the value into acc */
9059 if (AOP_TYPE(cond) != AOP_CRY)
9060 pic14_toBoolean(cond);
9063 /* the result is now in the accumulator */
9064 freeAsmop(cond,NULL,ic,TRUE);
9066 /* if there was something to be popped then do it */
9070 /* if the condition is a bit variable */
9071 if (isbit && IS_ITEMP(cond) &&
9073 genIfxJump(ic,SPIL_LOC(cond)->rname);
9074 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9077 if (isbit && !IS_ITEMP(cond))
9078 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9086 /*-----------------------------------------------------------------*/
9087 /* genAddrOf - generates code for address of */
9088 /*-----------------------------------------------------------------*/
9089 static void genAddrOf (iCode *ic)
9091 operand *right, *result, *left;
9094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9097 //aopOp(IC_RESULT(ic),ic,FALSE);
9099 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9100 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9101 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9103 DEBUGpic14_AopType(__LINE__,left,right,result);
9105 size = AOP_SIZE(IC_RESULT(ic));
9109 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9110 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9114 freeAsmop(left,NULL,ic,FALSE);
9115 freeAsmop(result,NULL,ic,TRUE);
9120 /*-----------------------------------------------------------------*/
9121 /* genFarFarAssign - assignment when both are in far space */
9122 /*-----------------------------------------------------------------*/
9123 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9125 int size = AOP_SIZE(right);
9128 /* first push the right side on to the stack */
9130 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9132 pic14_emitcode ("push","acc");
9135 freeAsmop(right,NULL,ic,FALSE);
9136 /* now assign DPTR to result */
9137 aopOp(result,ic,FALSE);
9138 size = AOP_SIZE(result);
9140 pic14_emitcode ("pop","acc");
9141 aopPut(AOP(result),"a",--offset);
9143 freeAsmop(result,NULL,ic,FALSE);
9148 /*-----------------------------------------------------------------*/
9149 /* genAssign - generate code for assignment */
9150 /*-----------------------------------------------------------------*/
9151 static void genAssign (iCode *ic)
9153 operand *result, *right;
9154 int size, offset,know_W;
9155 unsigned long lit = 0L;
9157 result = IC_RESULT(ic);
9158 right = IC_RIGHT(ic) ;
9160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9162 /* if they are the same */
9163 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9166 aopOp(right,ic,FALSE);
9167 aopOp(result,ic,TRUE);
9169 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9171 /* if they are the same registers */
9172 if (pic14_sameRegs(AOP(right),AOP(result)))
9175 /* if the result is a bit */
9176 if (AOP_TYPE(result) == AOP_CRY) {
9178 /* if the right size is a literal then
9179 we know what the value is */
9180 if (AOP_TYPE(right) == AOP_LIT) {
9182 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9183 popGet(AOP(result),0));
9185 if (((int) operandLitValue(right)))
9186 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9187 AOP(result)->aopu.aop_dir,
9188 AOP(result)->aopu.aop_dir);
9190 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9191 AOP(result)->aopu.aop_dir,
9192 AOP(result)->aopu.aop_dir);
9196 /* the right is also a bit variable */
9197 if (AOP_TYPE(right) == AOP_CRY) {
9198 emitpcode(POC_BCF, popGet(AOP(result),0));
9199 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9200 emitpcode(POC_BSF, popGet(AOP(result),0));
9202 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9203 AOP(result)->aopu.aop_dir,
9204 AOP(result)->aopu.aop_dir);
9205 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9206 AOP(right)->aopu.aop_dir,
9207 AOP(right)->aopu.aop_dir);
9208 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9209 AOP(result)->aopu.aop_dir,
9210 AOP(result)->aopu.aop_dir);
9215 emitpcode(POC_BCF, popGet(AOP(result),0));
9216 pic14_toBoolean(right);
9218 emitpcode(POC_BSF, popGet(AOP(result),0));
9219 //aopPut(AOP(result),"a",0);
9223 /* bit variables done */
9225 size = AOP_SIZE(result);
9227 if(AOP_TYPE(right) == AOP_LIT)
9228 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9230 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9232 if(aopIdx(AOP(result),0) == 4) {
9233 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9234 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9235 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9238 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9244 if(AOP_TYPE(right) == AOP_LIT) {
9246 if(know_W != (lit&0xff))
9247 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9249 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9251 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9255 } else if (AOP_TYPE(right) == AOP_CRY) {
9256 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9258 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9259 emitpcode(POC_INCF, popGet(AOP(result),0));
9262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9263 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9264 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9272 freeAsmop (right,NULL,ic,FALSE);
9273 freeAsmop (result,NULL,ic,TRUE);
9276 /*-----------------------------------------------------------------*/
9277 /* genJumpTab - genrates code for jump table */
9278 /*-----------------------------------------------------------------*/
9279 static void genJumpTab (iCode *ic)
9284 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9286 aopOp(IC_JTCOND(ic),ic,FALSE);
9287 /* get the condition into accumulator */
9288 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9290 /* multiply by three */
9291 pic14_emitcode("add","a,acc");
9292 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9294 jtab = newiTempLabel(NULL);
9295 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9296 pic14_emitcode("jmp","@a+dptr");
9297 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9299 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9300 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9302 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9303 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9304 emitpLabel(jtab->key);
9306 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9308 /* now generate the jump labels */
9309 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9310 jtab = setNextItem(IC_JTLABELS(ic))) {
9311 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9312 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9318 /*-----------------------------------------------------------------*/
9319 /* genMixedOperation - gen code for operators between mixed types */
9320 /*-----------------------------------------------------------------*/
9322 TSD - Written for the PIC port - but this unfortunately is buggy.
9323 This routine is good in that it is able to efficiently promote
9324 types to different (larger) sizes. Unfortunately, the temporary
9325 variables that are optimized out by this routine are sometimes
9326 used in other places. So until I know how to really parse the
9327 iCode tree, I'm going to not be using this routine :(.
9329 static int genMixedOperation (iCode *ic)
9332 operand *result = IC_RESULT(ic);
9333 sym_link *ctype = operandType(IC_LEFT(ic));
9334 operand *right = IC_RIGHT(ic);
9340 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9342 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9348 nextright = IC_RIGHT(nextic);
9349 nextleft = IC_LEFT(nextic);
9350 nextresult = IC_RESULT(nextic);
9352 aopOp(right,ic,FALSE);
9353 aopOp(result,ic,FALSE);
9354 aopOp(nextright, nextic, FALSE);
9355 aopOp(nextleft, nextic, FALSE);
9356 aopOp(nextresult, nextic, FALSE);
9358 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9364 pic14_emitcode(";remove right +","");
9366 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9372 pic14_emitcode(";remove left +","");
9376 big = AOP_SIZE(nextleft);
9377 small = AOP_SIZE(nextright);
9379 switch(nextic->op) {
9382 pic14_emitcode(";optimize a +","");
9383 /* if unsigned or not an integral type */
9384 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9385 pic14_emitcode(";add a bit to something","");
9388 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9390 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9391 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9392 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9394 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9402 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9403 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9404 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9407 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9409 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9410 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9411 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9412 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9413 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9416 pic14_emitcode("rlf","known_zero,w");
9423 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9424 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9425 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9427 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9437 freeAsmop(right,NULL,ic,TRUE);
9438 freeAsmop(result,NULL,ic,TRUE);
9439 freeAsmop(nextright,NULL,ic,TRUE);
9440 freeAsmop(nextleft,NULL,ic,TRUE);
9442 nextic->generated = 1;
9449 /*-----------------------------------------------------------------*/
9450 /* genCast - gen code for casting */
9451 /*-----------------------------------------------------------------*/
9452 static void genCast (iCode *ic)
9454 operand *result = IC_RESULT(ic);
9455 sym_link *ctype = operandType(IC_LEFT(ic));
9456 sym_link *rtype = operandType(IC_RIGHT(ic));
9457 operand *right = IC_RIGHT(ic);
9460 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9461 /* if they are equivalent then do nothing */
9462 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9465 aopOp(right,ic,FALSE) ;
9466 aopOp(result,ic,FALSE);
9468 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9470 /* if the result is a bit */
9471 if (AOP_TYPE(result) == AOP_CRY) {
9472 /* if the right size is a literal then
9473 we know what the value is */
9474 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9475 if (AOP_TYPE(right) == AOP_LIT) {
9477 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9478 popGet(AOP(result),0));
9480 if (((int) operandLitValue(right)))
9481 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9482 AOP(result)->aopu.aop_dir,
9483 AOP(result)->aopu.aop_dir);
9485 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9486 AOP(result)->aopu.aop_dir,
9487 AOP(result)->aopu.aop_dir);
9492 /* the right is also a bit variable */
9493 if (AOP_TYPE(right) == AOP_CRY) {
9496 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9498 pic14_emitcode("clrc","");
9499 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9500 AOP(right)->aopu.aop_dir,
9501 AOP(right)->aopu.aop_dir);
9502 aopPut(AOP(result),"c",0);
9507 if (AOP_TYPE(right) == AOP_REG) {
9508 emitpcode(POC_BCF, popGet(AOP(result),0));
9509 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9510 emitpcode(POC_BSF, popGet(AOP(result),0));
9512 pic14_toBoolean(right);
9513 aopPut(AOP(result),"a",0);
9517 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9519 size = AOP_SIZE(result);
9521 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9523 emitpcode(POC_CLRF, popGet(AOP(result),0));
9524 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9525 emitpcode(POC_INCF, popGet(AOP(result),0));
9528 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9533 /* if they are the same size : or less */
9534 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9536 /* if they are in the same place */
9537 if (pic14_sameRegs(AOP(right),AOP(result)))
9540 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9541 if (IS_PTR_CONST(rtype))
9542 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9543 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9544 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9546 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9547 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9548 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9549 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9550 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9551 if(AOP_SIZE(result) <2)
9552 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9556 /* if they in different places then copy */
9557 size = AOP_SIZE(result);
9560 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9561 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9563 //aopPut(AOP(result),
9564 // aopGet(AOP(right),offset,FALSE,FALSE),
9574 /* if the result is of type pointer */
9575 if (IS_PTR(ctype)) {
9578 sym_link *type = operandType(right);
9579 sym_link *etype = getSpec(type);
9580 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9582 /* pointer to generic pointer */
9583 if (IS_GENPTR(ctype)) {
9587 p_type = DCL_TYPE(type);
9589 /* we have to go by the storage class */
9590 p_type = PTR_TYPE(SPEC_OCLS(etype));
9592 /* if (SPEC_OCLS(etype)->codesp ) */
9593 /* p_type = CPOINTER ; */
9595 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9596 /* p_type = FPOINTER ; */
9598 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9599 /* p_type = PPOINTER; */
9601 /* if (SPEC_OCLS(etype) == idata ) */
9602 /* p_type = IPOINTER ; */
9604 /* p_type = POINTER ; */
9607 /* the first two bytes are known */
9608 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9609 size = GPTRSIZE - 1;
9612 if(offset < AOP_SIZE(right)) {
9613 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9614 if ((AOP_TYPE(right) == AOP_PCODE) &&
9615 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9616 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9617 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9620 aopGet(AOP(right),offset,FALSE,FALSE),
9624 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9627 /* the last byte depending on type */
9631 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9634 pic14_emitcode(";BUG!? ","%d",__LINE__);
9638 pic14_emitcode(";BUG!? ","%d",__LINE__);
9642 pic14_emitcode(";BUG!? ","%d",__LINE__);
9647 /* this should never happen */
9648 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9649 "got unknown pointer type");
9652 //aopPut(AOP(result),l, GPTRSIZE - 1);
9656 /* just copy the pointers */
9657 size = AOP_SIZE(result);
9661 aopGet(AOP(right),offset,FALSE,FALSE),
9670 /* so we now know that the size of destination is greater
9671 than the size of the source.
9672 Now, if the next iCode is an operator then we might be
9673 able to optimize the operation without performing a cast.
9675 if(genMixedOperation(ic))
9678 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9680 /* we move to result for the size of source */
9681 size = AOP_SIZE(right);
9684 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9685 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9689 /* now depending on the sign of the destination */
9690 size = AOP_SIZE(result) - AOP_SIZE(right);
9691 /* if unsigned or not an integral type */
9692 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9694 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9696 /* we need to extend the sign :{ */
9699 /* Save one instruction of casting char to int */
9700 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9701 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9702 emitpcode(POC_DECF, popGet(AOP(result),offset));
9704 emitpcodeNULLop(POC_CLRW);
9707 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9709 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9711 emitpcode(POC_MOVLW, popGetLit(0xff));
9714 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9719 freeAsmop(right,NULL,ic,TRUE);
9720 freeAsmop(result,NULL,ic,TRUE);
9724 /*-----------------------------------------------------------------*/
9725 /* genDjnz - generate decrement & jump if not zero instrucion */
9726 /*-----------------------------------------------------------------*/
9727 static int genDjnz (iCode *ic, iCode *ifx)
9730 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9735 /* if the if condition has a false label
9736 then we cannot save */
9740 /* if the minus is not of the form
9742 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9743 !IS_OP_LITERAL(IC_RIGHT(ic)))
9746 if (operandLitValue(IC_RIGHT(ic)) != 1)
9749 /* if the size of this greater than one then no
9751 if (getSize(operandType(IC_RESULT(ic))) > 1)
9754 /* otherwise we can save BIG */
9755 lbl = newiTempLabel(NULL);
9756 lbl1= newiTempLabel(NULL);
9758 aopOp(IC_RESULT(ic),ic,FALSE);
9760 if (IS_AOP_PREG(IC_RESULT(ic))) {
9761 pic14_emitcode("dec","%s",
9762 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9763 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9764 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9768 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9769 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9771 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9772 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9775 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9776 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9777 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9778 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9781 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9786 /*-----------------------------------------------------------------*/
9787 /* genReceive - generate code for a receive iCode */
9788 /*-----------------------------------------------------------------*/
9789 static void genReceive (iCode *ic)
9791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9793 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9794 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9795 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9797 int size = getSize(operandType(IC_RESULT(ic)));
9798 int offset = fReturnSizePic - size;
9800 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9801 fReturn[fReturnSizePic - offset - 1] : "acc"));
9804 aopOp(IC_RESULT(ic),ic,FALSE);
9805 size = AOP_SIZE(IC_RESULT(ic));
9808 pic14_emitcode ("pop","acc");
9809 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9814 aopOp(IC_RESULT(ic),ic,FALSE);
9816 assignResultValue(IC_RESULT(ic));
9819 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9822 /*-----------------------------------------------------------------*/
9823 /* genpic14Code - generate code for pic14 based controllers */
9824 /*-----------------------------------------------------------------*/
9826 * At this point, ralloc.c has gone through the iCode and attempted
9827 * to optimize in a way suitable for a PIC. Now we've got to generate
9828 * PIC instructions that correspond to the iCode.
9830 * Once the instructions are generated, we'll pass through both the
9831 * peep hole optimizer and the pCode optimizer.
9832 *-----------------------------------------------------------------*/
9834 void genpic14Code (iCode *lic)
9839 lineHead = lineCurr = NULL;
9841 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9844 /* if debug information required */
9845 if (options.debug && currFunc) {
9847 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9849 if (IS_STATIC(currFunc->etype)) {
9850 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9851 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9853 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9854 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9861 for (ic = lic ; ic ; ic = ic->next ) {
9863 DEBUGpic14_emitcode(";ic","");
9864 if ( cln != ic->lineno ) {
9865 if ( options.debug ) {
9867 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9868 FileBaseName(ic->filename),ic->lineno,
9869 ic->level,ic->block);
9873 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9874 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9875 printCLine(ic->filename, ic->lineno));
9878 newpCodeCSource(ic->lineno,
9880 printCLine(ic->filename, ic->lineno)));
9884 /* if the result is marked as
9885 spilt and rematerializable or code for
9886 this has already been generated then
9888 if (resultRemat(ic) || ic->generated )
9891 /* depending on the operation */
9910 /* IPOP happens only when trying to restore a
9911 spilt live range, if there is an ifx statement
9912 following this pop then the if statement might
9913 be using some of the registers being popped which
9914 would destory the contents of the register so
9915 we need to check for this condition and handle it */
9917 ic->next->op == IFX &&
9918 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9919 genIfx (ic->next,ic);
9937 genEndFunction (ic);
9957 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9974 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9978 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9985 /* note these two are xlated by algebraic equivalence
9986 during parsing SDCC.y */
9987 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9988 "got '>=' or '<=' shouldn't have come here");
9992 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10004 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10008 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10012 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10036 genRightShift (ic);
10039 case GET_VALUE_AT_ADDRESS:
10044 if (POINTER_SET(ic))
10071 addSet(&_G.sendSet,ic);
10080 /* now we are ready to call the
10081 peep hole optimizer */
10082 if (!options.nopeep) {
10083 peepHole (&lineHead);
10085 /* now do the actual printing */
10086 printLine (lineHead,codeOutFile);
10089 DFPRINTF((stderr,"printing pBlock\n\n"));
10090 printpBlock(stdout,pb);