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 extern int debug_verbose;
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 */
410 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
411 __FUNCTION__,__LINE__,resIfx->lbl->key);
415 resIfx->lbl = IC_TRUE(ifx);
417 resIfx->lbl = IC_FALSE(ifx);
418 resIfx->condition = 0;
422 DEBUGpic14_emitcode("; ***","ifx true is non-null");
424 DEBUGpic14_emitcode("; ***","ifx false is non-null");
428 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
431 /*-----------------------------------------------------------------*/
432 /* pointerCode - returns the code for a pointer type */
433 /*-----------------------------------------------------------------*/
434 static int pointerCode (sym_link *etype)
437 return PTR_TYPE(SPEC_OCLS(etype));
441 /*-----------------------------------------------------------------*/
442 /* aopForSym - for a true symbol */
443 /*-----------------------------------------------------------------*/
444 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
447 memmap *space= SPEC_OCLS(sym->etype);
449 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
450 /* if already has one */
454 /* assign depending on the storage class */
455 /* if it is on the stack or indirectly addressable */
456 /* space we need to assign either r0 or r1 to it */
457 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
458 sym->aop = aop = newAsmop(0);
459 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
460 aop->size = getSize(sym->type);
462 /* now assign the address of the variable to
463 the pointer register */
464 if (aop->type != AOP_STK) {
468 pic14_emitcode("push","acc");
470 pic14_emitcode("mov","a,_bp");
471 pic14_emitcode("add","a,#0x%02x",
473 ((char)(sym->stack - _G.nRegsSaved )) :
474 ((char)sym->stack)) & 0xff);
475 pic14_emitcode("mov","%s,a",
476 aop->aopu.aop_ptr->name);
479 pic14_emitcode("pop","acc");
481 pic14_emitcode("mov","%s,#%s",
482 aop->aopu.aop_ptr->name,
484 aop->paged = space->paged;
486 aop->aopu.aop_stk = sym->stack;
490 if (sym->onStack && options.stack10bit)
492 /* It's on the 10 bit stack, which is located in
496 //DEBUGpic14_emitcode(";","%d",__LINE__);
499 pic14_emitcode("push","acc");
501 pic14_emitcode("mov","a,_bp");
502 pic14_emitcode("add","a,#0x%02x",
504 ((char)(sym->stack - _G.nRegsSaved )) :
505 ((char)sym->stack)) & 0xff);
508 pic14_emitcode ("mov","dpx1,#0x40");
509 pic14_emitcode ("mov","dph1,#0x00");
510 pic14_emitcode ("mov","dpl1, a");
514 pic14_emitcode("pop","acc");
516 sym->aop = aop = newAsmop(AOP_DPTR2);
517 aop->size = getSize(sym->type);
521 //DEBUGpic14_emitcode(";","%d",__LINE__);
522 /* if in bit space */
523 if (IN_BITSPACE(space)) {
524 sym->aop = aop = newAsmop (AOP_CRY);
525 aop->aopu.aop_dir = sym->rname ;
526 aop->size = getSize(sym->type);
527 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
530 /* if it is in direct space */
531 if (IN_DIRSPACE(space)) {
532 sym->aop = aop = newAsmop (AOP_DIR);
533 aop->aopu.aop_dir = sym->rname ;
534 aop->size = getSize(sym->type);
535 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
539 /* special case for a function */
540 if (IS_FUNC(sym->type)) {
541 sym->aop = aop = newAsmop(AOP_IMMD);
542 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
543 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
544 strcpy(aop->aopu.aop_immd,sym->rname);
545 aop->size = FPTRSIZE;
546 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
551 /* only remaining is far space */
552 /* in which case DPTR gets the address */
553 sym->aop = aop = newAsmop(AOP_PCODE);
555 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
556 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
557 PCOI(aop->aopu.pcop)->index = 0;
559 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
560 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
562 allocDirReg (IC_LEFT(ic));
564 aop->size = FPTRSIZE;
566 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
567 sym->aop = aop = newAsmop(AOP_DPTR);
568 pic14_emitcode ("mov","dptr,#%s", sym->rname);
569 aop->size = getSize(sym->type);
571 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
574 /* if it is in code space */
575 if (IN_CODESPACE(space))
581 /*-----------------------------------------------------------------*/
582 /* aopForRemat - rematerialzes an object */
583 /*-----------------------------------------------------------------*/
584 static asmop *aopForRemat (operand *op) // x symbol *sym)
586 symbol *sym = OP_SYMBOL(op);
588 asmop *aop = newAsmop(AOP_PCODE);
592 ic = sym->rematiCode;
594 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
595 if(IS_OP_POINTER(op)) {
596 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
600 val += (int) operandLitValue(IC_RIGHT(ic));
601 } else if (ic->op == '-') {
602 val -= (int) operandLitValue(IC_RIGHT(ic));
606 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
609 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
610 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
611 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
612 PCOI(aop->aopu.pcop)->index = val;
614 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
615 OP_SYMBOL(IC_LEFT(ic))->rname,
616 val, IS_PTR_CONST(operandType(op)));
618 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
620 allocDirReg (IC_LEFT(ic));
625 int aopIdx (asmop *aop, int offset)
630 if(aop->type != AOP_REG)
633 return aop->aopu.aop_reg[offset]->rIdx;
636 /*-----------------------------------------------------------------*/
637 /* regsInCommon - two operands have some registers in common */
638 /*-----------------------------------------------------------------*/
639 static bool regsInCommon (operand *op1, operand *op2)
644 /* if they have registers in common */
645 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
648 sym1 = OP_SYMBOL(op1);
649 sym2 = OP_SYMBOL(op2);
651 if (sym1->nRegs == 0 || sym2->nRegs == 0)
654 for (i = 0 ; i < sym1->nRegs ; i++) {
659 for (j = 0 ; j < sym2->nRegs ;j++ ) {
663 if (sym2->regs[j] == sym1->regs[i])
671 /*-----------------------------------------------------------------*/
672 /* operandsEqu - equivalent */
673 /*-----------------------------------------------------------------*/
674 static bool operandsEqu ( operand *op1, operand *op2)
678 /* if they not symbols */
679 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
682 sym1 = OP_SYMBOL(op1);
683 sym2 = OP_SYMBOL(op2);
685 /* if both are itemps & one is spilt
686 and the other is not then false */
687 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
688 sym1->isspilt != sym2->isspilt )
691 /* if they are the same */
695 if (strcmp(sym1->rname,sym2->rname) == 0)
699 /* if left is a tmp & right is not */
703 (sym1->usl.spillLoc == sym2))
710 (sym2->usl.spillLoc == sym1))
716 /*-----------------------------------------------------------------*/
717 /* pic14_sameRegs - two asmops have the same registers */
718 /*-----------------------------------------------------------------*/
719 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
726 if (aop1->type != AOP_REG ||
727 aop2->type != AOP_REG )
730 if (aop1->size != aop2->size )
733 for (i = 0 ; i < aop1->size ; i++ )
734 if (aop1->aopu.aop_reg[i] !=
735 aop2->aopu.aop_reg[i] )
741 /*-----------------------------------------------------------------*/
742 /* aopOp - allocates an asmop for an operand : */
743 /*-----------------------------------------------------------------*/
744 void aopOp (operand *op, iCode *ic, bool result)
753 // DEBUGpic14_emitcode(";","%d",__LINE__);
754 /* if this a literal */
755 if (IS_OP_LITERAL(op)) {
756 op->aop = aop = newAsmop(AOP_LIT);
757 aop->aopu.aop_lit = op->operand.valOperand;
758 aop->size = getSize(operandType(op));
763 sym_link *type = operandType(op);
764 if(IS_PTR_CONST(type))
765 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
768 /* if already has a asmop then continue */
772 /* if the underlying symbol has a aop */
773 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
774 DEBUGpic14_emitcode(";","%d",__LINE__);
775 op->aop = OP_SYMBOL(op)->aop;
779 /* if this is a true symbol */
780 if (IS_TRUE_SYMOP(op)) {
781 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
782 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
786 /* this is a temporary : this has
792 e) can be a return use only */
797 /* if the type is a conditional */
798 if (sym->regType == REG_CND) {
799 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
804 /* if it is spilt then two situations
806 b) has a spill location */
807 if (sym->isspilt || sym->nRegs == 0) {
809 DEBUGpic14_emitcode(";","%d",__LINE__);
810 /* rematerialize it NOW */
813 sym->aop = op->aop = aop =
815 aop->size = getSize(sym->type);
816 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
822 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
823 aop->size = getSize(sym->type);
824 for ( i = 0 ; i < 2 ; i++ )
825 aop->aopu.aop_str[i] = accUse[i];
826 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
832 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
833 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
834 //allocDirReg (IC_LEFT(ic));
835 aop->size = getSize(sym->type);
840 aop = op->aop = sym->aop = newAsmop(AOP_STR);
841 aop->size = getSize(sym->type);
842 for ( i = 0 ; i < fReturnSizePic ; i++ )
843 aop->aopu.aop_str[i] = fReturn[i];
845 DEBUGpic14_emitcode(";","%d",__LINE__);
849 /* else spill location */
850 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
851 /* force a new aop if sizes differ */
852 sym->usl.spillLoc->aop = NULL;
854 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
855 __FUNCTION__,__LINE__,
856 sym->usl.spillLoc->rname,
857 sym->rname, sym->usl.spillLoc->offset);
859 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
860 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
861 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
863 sym->usl.spillLoc->offset);
864 aop->size = getSize(sym->type);
870 sym_link *type = operandType(op);
871 if(IS_PTR_CONST(type))
872 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
875 /* must be in a register */
876 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
877 sym->aop = op->aop = aop = newAsmop(AOP_REG);
878 aop->size = sym->nRegs;
879 for ( i = 0 ; i < sym->nRegs ;i++)
880 aop->aopu.aop_reg[i] = sym->regs[i];
883 /*-----------------------------------------------------------------*/
884 /* freeAsmop - free up the asmop given to an operand */
885 /*----------------------------------------------------------------*/
886 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
903 /* depending on the asmop type only three cases need work AOP_RO
904 , AOP_R1 && AOP_STK */
910 pic14_emitcode ("pop","ar0");
914 bitVectUnSetBit(ic->rUsed,R0_IDX);
920 pic14_emitcode ("pop","ar1");
924 bitVectUnSetBit(ic->rUsed,R1_IDX);
930 int stk = aop->aopu.aop_stk + aop->size;
931 bitVectUnSetBit(ic->rUsed,R0_IDX);
932 bitVectUnSetBit(ic->rUsed,R1_IDX);
934 getFreePtr(ic,&aop,FALSE);
936 if (options.stack10bit)
938 /* I'm not sure what to do here yet... */
941 "*** Warning: probably generating bad code for "
942 "10 bit stack mode.\n");
946 pic14_emitcode ("mov","a,_bp");
947 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
948 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
950 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
954 pic14_emitcode("pop","acc");
955 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
957 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
960 freeAsmop(op,NULL,ic,TRUE);
962 pic14_emitcode("pop","ar0");
967 pic14_emitcode("pop","ar1");
975 /* all other cases just dealloc */
979 OP_SYMBOL(op)->aop = NULL;
980 /* if the symbol has a spill */
982 SPIL_LOC(op)->aop = NULL;
987 /*-----------------------------------------------------------------*/
988 /* aopGet - for fetching value of the aop */
989 /*-----------------------------------------------------------------*/
990 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
995 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
996 /* offset is greater than
998 if (offset > (aop->size - 1) &&
999 aop->type != AOP_LIT)
1002 /* depending on type */
1003 switch (aop->type) {
1007 DEBUGpic14_emitcode(";","%d",__LINE__);
1008 /* if we need to increment it */
1009 while (offset > aop->coff) {
1010 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1014 while (offset < aop->coff) {
1015 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1019 aop->coff = offset ;
1021 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1022 return (dname ? "acc" : "a");
1024 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1025 rs = Safe_calloc(1,strlen(s)+1);
1031 DEBUGpic14_emitcode(";","%d",__LINE__);
1032 if (aop->type == AOP_DPTR2)
1037 while (offset > aop->coff) {
1038 pic14_emitcode ("inc","dptr");
1042 while (offset < aop->coff) {
1043 pic14_emitcode("lcall","__decdptr");
1049 pic14_emitcode("clr","a");
1050 pic14_emitcode("movc","a,@a+dptr");
1053 pic14_emitcode("movx","a,@dptr");
1056 if (aop->type == AOP_DPTR2)
1061 return (dname ? "acc" : "a");
1066 sprintf (s,"%s",aop->aopu.aop_immd);
1069 sprintf(s,"(%s >> %d)",
1074 aop->aopu.aop_immd);
1075 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1076 rs = Safe_calloc(1,strlen(s)+1);
1082 sprintf(s,"(%s + %d)",
1085 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1087 sprintf(s,"%s",aop->aopu.aop_dir);
1088 rs = Safe_calloc(1,strlen(s)+1);
1094 // return aop->aopu.aop_reg[offset]->dname;
1096 return aop->aopu.aop_reg[offset]->name;
1099 //pic14_emitcode(";","%d",__LINE__);
1100 return aop->aopu.aop_dir;
1103 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1104 return "AOP_accumulator_bug";
1107 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1108 rs = Safe_calloc(1,strlen(s)+1);
1113 DEBUGpic14_emitcode(";","%d",__LINE__);
1114 aop->coff = offset ;
1115 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1119 return aop->aopu.aop_str[offset];
1123 pCodeOp *pcop = aop->aopu.pcop;
1124 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1126 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1127 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1128 sprintf(s,"%s", pcop->name);
1130 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1133 rs = Safe_calloc(1,strlen(s)+1);
1139 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1140 "aopget got unsupported aop->type");
1145 /*-----------------------------------------------------------------*/
1146 /* popGetTempReg - create a new temporary pCodeOp */
1147 /*-----------------------------------------------------------------*/
1148 pCodeOp *popGetTempReg(void)
1153 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1154 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1155 PCOR(pcop)->r->wasUsed=1;
1156 PCOR(pcop)->r->isFree=0;
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp */
1164 /*-----------------------------------------------------------------*/
1165 void popReleaseTempReg(pCodeOp *pcop)
1168 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1169 PCOR(pcop)->r->isFree = 1;
1172 /*-----------------------------------------------------------------*/
1173 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1174 /*-----------------------------------------------------------------*/
1175 pCodeOp *popGetLabel(unsigned int key)
1178 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1183 return newpCodeOpLabel(NULL,key+100+labelOffset);
1186 /*-----------------------------------------------------------------*/
1187 /* popCopyReg - copy a pcode operator */
1188 /*-----------------------------------------------------------------*/
1189 pCodeOp *popCopyReg(pCodeOpReg *pc)
1193 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1194 pcor->pcop.type = pc->pcop.type;
1196 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1197 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1199 pcor->pcop.name = NULL;
1202 pcor->rIdx = pc->rIdx;
1205 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1209 /*-----------------------------------------------------------------*/
1210 /* popGet - asm operator to pcode operator conversion */
1211 /*-----------------------------------------------------------------*/
1212 pCodeOp *popGetLit(unsigned int lit)
1215 return newpCodeOpLit(lit);
1219 /*-----------------------------------------------------------------*/
1220 /* popGetImmd - asm operator to pcode immediate conversion */
1221 /*-----------------------------------------------------------------*/
1222 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1225 return newpCodeOpImmd(name, offset,index, 0);
1229 /*-----------------------------------------------------------------*/
1230 /* popGet - asm operator to pcode operator conversion */
1231 /*-----------------------------------------------------------------*/
1232 pCodeOp *popGetWithString(char *str)
1238 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1242 pcop = newpCodeOp(str,PO_STR);
1247 /*-----------------------------------------------------------------*/
1248 /* popRegFromString - */
1249 /*-----------------------------------------------------------------*/
1250 pCodeOp *popRegFromString(char *str, int size, int offset)
1253 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1254 pcop->type = PO_DIR;
1256 DEBUGpic14_emitcode(";","%d",__LINE__);
1261 pcop->name = Safe_calloc(1,strlen(str)+1);
1262 strcpy(pcop->name,str);
1264 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1266 PCOR(pcop)->r = dirregWithName(pcop->name);
1267 if(PCOR(pcop)->r == NULL) {
1268 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1269 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1270 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1272 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1274 PCOR(pcop)->instance = offset;
1279 pCodeOp *popRegFromIdx(int rIdx)
1283 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1284 __FUNCTION__,__LINE__,rIdx);
1286 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1288 PCOR(pcop)->rIdx = rIdx;
1289 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1290 PCOR(pcop)->r->isFree = 0;
1291 PCOR(pcop)->r->wasUsed = 1;
1293 pcop->type = PCOR(pcop)->r->pc_type;
1298 /*-----------------------------------------------------------------*/
1299 /* popGet - asm operator to pcode operator conversion */
1300 /*-----------------------------------------------------------------*/
1301 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1303 //char *s = buffer ;
1308 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1309 /* offset is greater than
1312 if (offset > (aop->size - 1) &&
1313 aop->type != AOP_LIT)
1314 return NULL; //zero;
1316 /* depending on type */
1317 switch (aop->type) {
1324 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1328 DEBUGpic14_emitcode(";","%d",__LINE__);
1329 return popGetImmd(aop->aopu.aop_immd,offset,0);
1332 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1334 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1335 pcop->type = PO_DIR;
1339 sprintf(s,"(%s + %d)",
1343 sprintf(s,"%s",aop->aopu.aop_dir);
1344 pcop->name = Safe_calloc(1,strlen(s)+1);
1345 strcpy(pcop->name,s);
1347 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1348 strcpy(pcop->name,aop->aopu.aop_dir);
1349 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1350 if(PCOR(pcop)->r == NULL) {
1351 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1352 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1353 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1355 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1357 PCOR(pcop)->instance = offset;
1364 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1366 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1367 PCOR(pcop)->rIdx = rIdx;
1368 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1369 PCOR(pcop)->r->wasUsed=1;
1370 PCOR(pcop)->r->isFree=0;
1372 PCOR(pcop)->instance = offset;
1373 pcop->type = PCOR(pcop)->r->pc_type;
1374 //rs = aop->aopu.aop_reg[offset]->name;
1375 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1380 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1381 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1382 //if(PCOR(pcop)->r == NULL)
1383 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1387 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1390 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1391 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1393 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1394 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1395 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1396 pcop->type = PCOR(pcop)->r->pc_type;
1397 pcop->name = PCOR(pcop)->r->name;
1403 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1405 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1406 pcop = pCodeOpCopy(aop->aopu.pcop);
1407 PCOI(pcop)->offset = offset;
1411 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1412 "popGet got unsupported aop->type");
1415 /*-----------------------------------------------------------------*/
1416 /* aopPut - puts a string for a aop */
1417 /*-----------------------------------------------------------------*/
1418 void aopPut (asmop *aop, char *s, int offset)
1423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1425 if (aop->size && offset > ( aop->size - 1)) {
1426 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1427 "aopPut got offset > aop->size");
1431 /* will assign value to value */
1432 /* depending on where it is ofcourse */
1433 switch (aop->type) {
1436 sprintf(d,"(%s + %d)",
1437 aop->aopu.aop_dir,offset);
1438 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1441 sprintf(d,"%s",aop->aopu.aop_dir);
1444 DEBUGpic14_emitcode(";","%d",__LINE__);
1446 pic14_emitcode("movf","%s,w",s);
1447 pic14_emitcode("movwf","%s",d);
1450 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1451 if(offset >= aop->size) {
1452 emitpcode(POC_CLRF,popGet(aop,offset));
1455 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1458 emitpcode(POC_MOVWF,popGet(aop,offset));
1465 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1466 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1469 strcmp(s,"r0") == 0 ||
1470 strcmp(s,"r1") == 0 ||
1471 strcmp(s,"r2") == 0 ||
1472 strcmp(s,"r3") == 0 ||
1473 strcmp(s,"r4") == 0 ||
1474 strcmp(s,"r5") == 0 ||
1475 strcmp(s,"r6") == 0 ||
1476 strcmp(s,"r7") == 0 )
1477 pic14_emitcode("mov","%s,%s ; %d",
1478 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1482 if(strcmp(s,"W")==0 )
1483 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1485 pic14_emitcode("movwf","%s",
1486 aop->aopu.aop_reg[offset]->name);
1488 if(strcmp(s,zero)==0) {
1489 emitpcode(POC_CLRF,popGet(aop,offset));
1491 } else if(strcmp(s,"W")==0) {
1492 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1493 pcop->type = PO_GPR_REGISTER;
1495 PCOR(pcop)->rIdx = -1;
1496 PCOR(pcop)->r = NULL;
1498 DEBUGpic14_emitcode(";","%d",__LINE__);
1499 pcop->name = Safe_strdup(s);
1500 emitpcode(POC_MOVFW,pcop);
1501 emitpcode(POC_MOVWF,popGet(aop,offset));
1502 } else if(strcmp(s,one)==0) {
1503 emitpcode(POC_CLRF,popGet(aop,offset));
1504 emitpcode(POC_INCF,popGet(aop,offset));
1506 emitpcode(POC_MOVWF,popGet(aop,offset));
1514 if (aop->type == AOP_DPTR2)
1520 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1521 "aopPut writting to code space");
1525 while (offset > aop->coff) {
1527 pic14_emitcode ("inc","dptr");
1530 while (offset < aop->coff) {
1532 pic14_emitcode("lcall","__decdptr");
1537 /* if not in accumulater */
1540 pic14_emitcode ("movx","@dptr,a");
1542 if (aop->type == AOP_DPTR2)
1550 while (offset > aop->coff) {
1552 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1554 while (offset < aop->coff) {
1556 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1562 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1567 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1569 if (strcmp(s,"r0") == 0 ||
1570 strcmp(s,"r1") == 0 ||
1571 strcmp(s,"r2") == 0 ||
1572 strcmp(s,"r3") == 0 ||
1573 strcmp(s,"r4") == 0 ||
1574 strcmp(s,"r5") == 0 ||
1575 strcmp(s,"r6") == 0 ||
1576 strcmp(s,"r7") == 0 ) {
1578 sprintf(buffer,"a%s",s);
1579 pic14_emitcode("mov","@%s,%s",
1580 aop->aopu.aop_ptr->name,buffer);
1582 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1587 if (strcmp(s,"a") == 0)
1588 pic14_emitcode("push","acc");
1590 pic14_emitcode("push","%s",s);
1595 /* if bit variable */
1596 if (!aop->aopu.aop_dir) {
1597 pic14_emitcode("clr","a");
1598 pic14_emitcode("rlc","a");
1601 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1604 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1607 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1609 lbl = newiTempLabel(NULL);
1611 if (strcmp(s,"a")) {
1614 pic14_emitcode("clr","c");
1615 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1616 pic14_emitcode("cpl","c");
1617 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1618 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1625 if (strcmp(aop->aopu.aop_str[offset],s))
1626 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1631 if (!offset && (strcmp(s,"acc") == 0))
1634 if (strcmp(aop->aopu.aop_str[offset],s))
1635 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1639 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1640 "aopPut got unsupported aop->type");
1646 /*-----------------------------------------------------------------*/
1647 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1648 /*-----------------------------------------------------------------*/
1649 void mov2w (asmop *aop, int offset)
1655 if ( aop->type == AOP_PCODE ||
1656 aop->type == AOP_LIT )
1657 emitpcode(POC_MOVLW,popGet(aop,offset));
1659 emitpcode(POC_MOVFW,popGet(aop,offset));
1663 /*-----------------------------------------------------------------*/
1664 /* reAdjustPreg - points a register back to where it should */
1665 /*-----------------------------------------------------------------*/
1666 static void reAdjustPreg (asmop *aop)
1670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1672 if ((size = aop->size) <= 1)
1675 switch (aop->type) {
1679 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1683 if (aop->type == AOP_DPTR2)
1689 pic14_emitcode("lcall","__decdptr");
1692 if (aop->type == AOP_DPTR2)
1702 /*-----------------------------------------------------------------*/
1703 /* genNotFloat - generates not for float operations */
1704 /*-----------------------------------------------------------------*/
1705 static void genNotFloat (operand *op, operand *res)
1711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1712 /* we will put 127 in the first byte of
1714 aopPut(AOP(res),"#127",0);
1715 size = AOP_SIZE(op) - 1;
1718 l = aopGet(op->aop,offset++,FALSE,FALSE);
1722 pic14_emitcode("orl","a,%s",
1724 offset++,FALSE,FALSE));
1726 tlbl = newiTempLabel(NULL);
1728 tlbl = newiTempLabel(NULL);
1729 aopPut(res->aop,one,1);
1730 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1731 aopPut(res->aop,zero,1);
1732 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1734 size = res->aop->size - 2;
1736 /* put zeros in the rest */
1738 aopPut(res->aop,zero,offset++);
1742 /*-----------------------------------------------------------------*/
1743 /* opIsGptr: returns non-zero if the passed operand is */
1744 /* a generic pointer type. */
1745 /*-----------------------------------------------------------------*/
1746 static int opIsGptr(operand *op)
1748 sym_link *type = operandType(op);
1750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1751 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1759 /*-----------------------------------------------------------------*/
1760 /* pic14_getDataSize - get the operand data size */
1761 /*-----------------------------------------------------------------*/
1762 int pic14_getDataSize(operand *op)
1764 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1767 return AOP_SIZE(op);
1769 // tsd- in the pic port, the genptr size is 1, so this code here
1770 // fails. ( in the 8051 port, the size was 4).
1773 size = AOP_SIZE(op);
1774 if (size == GPTRSIZE)
1776 sym_link *type = operandType(op);
1777 if (IS_GENPTR(type))
1779 /* generic pointer; arithmetic operations
1780 * should ignore the high byte (pointer type).
1783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1790 /*-----------------------------------------------------------------*/
1791 /* pic14_outAcc - output Acc */
1792 /*-----------------------------------------------------------------*/
1793 void pic14_outAcc(operand *result)
1796 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1797 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1800 size = pic14_getDataSize(result);
1802 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1805 /* unsigned or positive */
1807 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1812 /*-----------------------------------------------------------------*/
1813 /* pic14_outBitC - output a bit C */
1814 /*-----------------------------------------------------------------*/
1815 void pic14_outBitC(operand *result)
1818 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1819 /* if the result is bit */
1820 if (AOP_TYPE(result) == AOP_CRY)
1821 aopPut(AOP(result),"c",0);
1823 pic14_emitcode("clr","a ; %d", __LINE__);
1824 pic14_emitcode("rlc","a");
1825 pic14_outAcc(result);
1829 /*-----------------------------------------------------------------*/
1830 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1831 /*-----------------------------------------------------------------*/
1832 void pic14_toBoolean(operand *oper)
1834 int size = AOP_SIZE(oper) - 1;
1837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1839 if ( AOP_TYPE(oper) != AOP_ACC) {
1840 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1843 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1848 /*-----------------------------------------------------------------*/
1849 /* genNot - generate code for ! operation */
1850 /*-----------------------------------------------------------------*/
1851 static void genNot (iCode *ic)
1854 sym_link *optype = operandType(IC_LEFT(ic));
1857 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1858 /* assign asmOps to operand & result */
1859 aopOp (IC_LEFT(ic),ic,FALSE);
1860 aopOp (IC_RESULT(ic),ic,TRUE);
1862 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1863 /* if in bit space then a special case */
1864 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1865 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1866 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1867 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1869 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1870 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1871 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1876 /* if type float then do float */
1877 if (IS_FLOAT(optype)) {
1878 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1882 size = AOP_SIZE(IC_RESULT(ic));
1884 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1885 emitpcode(POC_ANDLW,popGetLit(1));
1886 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1889 pic14_toBoolean(IC_LEFT(ic));
1891 tlbl = newiTempLabel(NULL);
1892 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1893 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1894 pic14_outBitC(IC_RESULT(ic));
1897 /* release the aops */
1898 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1903 /*-----------------------------------------------------------------*/
1904 /* genCpl - generate code for complement */
1905 /*-----------------------------------------------------------------*/
1906 static void genCpl (iCode *ic)
1912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1913 /* assign asmOps to operand & result */
1914 aopOp (IC_LEFT(ic),ic,FALSE);
1915 aopOp (IC_RESULT(ic),ic,TRUE);
1917 /* if both are in bit space then
1919 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1920 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1922 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1923 pic14_emitcode("cpl","c");
1924 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1928 size = AOP_SIZE(IC_RESULT(ic));
1930 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1932 pic14_emitcode("cpl","a");
1933 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1938 /* release the aops */
1939 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1940 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1943 /*-----------------------------------------------------------------*/
1944 /* genUminusFloat - unary minus for floating points */
1945 /*-----------------------------------------------------------------*/
1946 static void genUminusFloat(operand *op,operand *result)
1948 int size ,offset =0 ;
1951 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1952 /* for this we just need to flip the
1953 first it then copy the rest in place */
1954 size = AOP_SIZE(op) - 1;
1955 l = aopGet(AOP(op),3,FALSE,FALSE);
1959 pic14_emitcode("cpl","acc.7");
1960 aopPut(AOP(result),"a",3);
1964 aopGet(AOP(op),offset,FALSE,FALSE),
1970 /*-----------------------------------------------------------------*/
1971 /* genUminus - unary minus code generation */
1972 /*-----------------------------------------------------------------*/
1973 static void genUminus (iCode *ic)
1976 sym_link *optype, *rtype;
1979 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1981 aopOp(IC_LEFT(ic),ic,FALSE);
1982 aopOp(IC_RESULT(ic),ic,TRUE);
1984 /* if both in bit space then special
1986 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1987 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1989 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1990 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1991 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1996 optype = operandType(IC_LEFT(ic));
1997 rtype = operandType(IC_RESULT(ic));
1999 /* if float then do float stuff */
2000 if (IS_FLOAT(optype)) {
2001 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2005 /* otherwise subtract from zero by taking the 2's complement */
2006 size = AOP_SIZE(IC_LEFT(ic));
2008 for(i=0; i<size; i++) {
2009 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2010 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2012 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2013 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2017 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2018 for(i=1; i<size; i++) {
2020 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2024 /* release the aops */
2025 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2026 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2029 /*-----------------------------------------------------------------*/
2030 /* saveRegisters - will look for a call and save the registers */
2031 /*-----------------------------------------------------------------*/
2032 static void saveRegisters(iCode *lic)
2039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2041 for (ic = lic ; ic ; ic = ic->next)
2042 if (ic->op == CALL || ic->op == PCALL)
2046 fprintf(stderr,"found parameter push with no function call\n");
2050 /* if the registers have been saved already then
2052 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2055 /* find the registers in use at this time
2056 and push them away to safety */
2057 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2061 if (options.useXstack) {
2062 if (bitVectBitValue(rsave,R0_IDX))
2063 pic14_emitcode("mov","b,r0");
2064 pic14_emitcode("mov","r0,%s",spname);
2065 for (i = 0 ; i < pic14_nRegs ; i++) {
2066 if (bitVectBitValue(rsave,i)) {
2068 pic14_emitcode("mov","a,b");
2070 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2071 pic14_emitcode("movx","@r0,a");
2072 pic14_emitcode("inc","r0");
2075 pic14_emitcode("mov","%s,r0",spname);
2076 if (bitVectBitValue(rsave,R0_IDX))
2077 pic14_emitcode("mov","r0,b");
2079 //for (i = 0 ; i < pic14_nRegs ; i++) {
2080 // if (bitVectBitValue(rsave,i))
2081 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2084 dtype = operandType(IC_LEFT(ic));
2085 if (currFunc && dtype &&
2086 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2087 IFFUNC_ISISR(currFunc->type) &&
2090 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2093 /*-----------------------------------------------------------------*/
2094 /* unsaveRegisters - pop the pushed registers */
2095 /*-----------------------------------------------------------------*/
2096 static void unsaveRegisters (iCode *ic)
2101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2102 /* find the registers in use at this time
2103 and push them away to safety */
2104 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2107 if (options.useXstack) {
2108 pic14_emitcode("mov","r0,%s",spname);
2109 for (i = pic14_nRegs ; i >= 0 ; i--) {
2110 if (bitVectBitValue(rsave,i)) {
2111 pic14_emitcode("dec","r0");
2112 pic14_emitcode("movx","a,@r0");
2114 pic14_emitcode("mov","b,a");
2116 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2120 pic14_emitcode("mov","%s,r0",spname);
2121 if (bitVectBitValue(rsave,R0_IDX))
2122 pic14_emitcode("mov","r0,b");
2124 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2125 // if (bitVectBitValue(rsave,i))
2126 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2132 /*-----------------------------------------------------------------*/
2134 /*-----------------------------------------------------------------*/
2135 static void pushSide(operand * oper, int size)
2139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2141 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2142 if (AOP_TYPE(oper) != AOP_REG &&
2143 AOP_TYPE(oper) != AOP_DIR &&
2145 pic14_emitcode("mov","a,%s",l);
2146 pic14_emitcode("push","acc");
2148 pic14_emitcode("push","%s",l);
2153 /*-----------------------------------------------------------------*/
2154 /* assignResultValue - */
2155 /*-----------------------------------------------------------------*/
2156 static void assignResultValue(operand * oper)
2158 int size = AOP_SIZE(oper);
2160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2162 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2164 if(!GpsuedoStkPtr) {
2165 /* The last byte in the assignment is in W */
2167 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2172 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2174 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2179 /*-----------------------------------------------------------------*/
2180 /* genIpush - genrate code for pushing this gets a little complex */
2181 /*-----------------------------------------------------------------*/
2182 static void genIpush (iCode *ic)
2185 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2187 int size, offset = 0 ;
2191 /* if this is not a parm push : ie. it is spill push
2192 and spill push is always done on the local stack */
2193 if (!ic->parmPush) {
2195 /* and the item is spilt then do nothing */
2196 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2199 aopOp(IC_LEFT(ic),ic,FALSE);
2200 size = AOP_SIZE(IC_LEFT(ic));
2201 /* push it on the stack */
2203 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2208 pic14_emitcode("push","%s",l);
2213 /* this is a paramter push: in this case we call
2214 the routine to find the call and save those
2215 registers that need to be saved */
2218 /* then do the push */
2219 aopOp(IC_LEFT(ic),ic,FALSE);
2222 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2223 size = AOP_SIZE(IC_LEFT(ic));
2226 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2227 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2228 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2230 pic14_emitcode("mov","a,%s",l);
2231 pic14_emitcode("push","acc");
2233 pic14_emitcode("push","%s",l);
2236 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2240 /*-----------------------------------------------------------------*/
2241 /* genIpop - recover the registers: can happen only for spilling */
2242 /*-----------------------------------------------------------------*/
2243 static void genIpop (iCode *ic)
2245 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2250 /* if the temp was not pushed then */
2251 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2254 aopOp(IC_LEFT(ic),ic,FALSE);
2255 size = AOP_SIZE(IC_LEFT(ic));
2258 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2261 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2265 /*-----------------------------------------------------------------*/
2266 /* unsaverbank - restores the resgister bank from stack */
2267 /*-----------------------------------------------------------------*/
2268 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2270 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2278 if (options.useXstack) {
2280 r = getFreePtr(ic,&aop,FALSE);
2283 pic14_emitcode("mov","%s,_spx",r->name);
2284 pic14_emitcode("movx","a,@%s",r->name);
2285 pic14_emitcode("mov","psw,a");
2286 pic14_emitcode("dec","%s",r->name);
2289 pic14_emitcode ("pop","psw");
2292 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2293 if (options.useXstack) {
2294 pic14_emitcode("movx","a,@%s",r->name);
2295 //pic14_emitcode("mov","(%s+%d),a",
2296 // regspic14[i].base,8*bank+regspic14[i].offset);
2297 pic14_emitcode("dec","%s",r->name);
2300 pic14_emitcode("pop",""); //"(%s+%d)",
2301 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2304 if (options.useXstack) {
2306 pic14_emitcode("mov","_spx,%s",r->name);
2307 freeAsmop(NULL,aop,ic,TRUE);
2313 /*-----------------------------------------------------------------*/
2314 /* saverbank - saves an entire register bank on the stack */
2315 /*-----------------------------------------------------------------*/
2316 static void saverbank (int bank, iCode *ic, bool pushPsw)
2318 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2325 if (options.useXstack) {
2328 r = getFreePtr(ic,&aop,FALSE);
2329 pic14_emitcode("mov","%s,_spx",r->name);
2333 for (i = 0 ; i < pic14_nRegs ;i++) {
2334 if (options.useXstack) {
2335 pic14_emitcode("inc","%s",r->name);
2336 //pic14_emitcode("mov","a,(%s+%d)",
2337 // regspic14[i].base,8*bank+regspic14[i].offset);
2338 pic14_emitcode("movx","@%s,a",r->name);
2340 pic14_emitcode("push","");// "(%s+%d)",
2341 //regspic14[i].base,8*bank+regspic14[i].offset);
2345 if (options.useXstack) {
2346 pic14_emitcode("mov","a,psw");
2347 pic14_emitcode("movx","@%s,a",r->name);
2348 pic14_emitcode("inc","%s",r->name);
2349 pic14_emitcode("mov","_spx,%s",r->name);
2350 freeAsmop (NULL,aop,ic,TRUE);
2353 pic14_emitcode("push","psw");
2355 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2361 /*-----------------------------------------------------------------*/
2362 /* genCall - generates a call statement */
2363 /*-----------------------------------------------------------------*/
2364 static void genCall (iCode *ic)
2368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2370 /* if caller saves & we have not saved then */
2374 /* if we are calling a function that is not using
2375 the same register bank then we need to save the
2376 destination registers on the stack */
2377 dtype = operandType(IC_LEFT(ic));
2378 if (currFunc && dtype &&
2379 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2380 IFFUNC_ISISR(currFunc->type) &&
2383 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2385 /* if send set is not empty the assign */
2388 /* For the Pic port, there is no data stack.
2389 * So parameters passed to functions are stored
2390 * in registers. (The pCode optimizer will get
2391 * rid of most of these :).
2393 int psuedoStkPtr=-1;
2394 int firstTimeThruLoop = 1;
2396 _G.sendSet = reverseSet(_G.sendSet);
2398 /* First figure how many parameters are getting passed */
2399 for (sic = setFirstItem(_G.sendSet) ; sic ;
2400 sic = setNextItem(_G.sendSet)) {
2402 aopOp(IC_LEFT(sic),sic,FALSE);
2403 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2404 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2407 for (sic = setFirstItem(_G.sendSet) ; sic ;
2408 sic = setNextItem(_G.sendSet)) {
2409 int size, offset = 0;
2411 aopOp(IC_LEFT(sic),sic,FALSE);
2412 size = AOP_SIZE(IC_LEFT(sic));
2415 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2416 AopType(AOP_TYPE(IC_LEFT(sic))));
2418 if(!firstTimeThruLoop) {
2419 /* If this is not the first time we've been through the loop
2420 * then we need to save the parameter in a temporary
2421 * register. The last byte of the last parameter is
2423 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2426 firstTimeThruLoop=0;
2428 //if (strcmp(l,fReturn[offset])) {
2429 mov2w (AOP(IC_LEFT(sic)), offset);
2431 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2432 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2433 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2435 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2440 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2445 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2446 OP_SYMBOL(IC_LEFT(ic))->rname :
2447 OP_SYMBOL(IC_LEFT(ic))->name));
2450 /* if we need assign a result value */
2451 if ((IS_ITEMP(IC_RESULT(ic)) &&
2452 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2453 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2454 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2457 aopOp(IC_RESULT(ic),ic,FALSE);
2460 assignResultValue(IC_RESULT(ic));
2462 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2463 AopType(AOP_TYPE(IC_RESULT(ic))));
2465 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2468 /* adjust the stack for parameters if
2470 if (ic->parmBytes) {
2472 if (ic->parmBytes > 3) {
2473 pic14_emitcode("mov","a,%s",spname);
2474 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2475 pic14_emitcode("mov","%s,a",spname);
2477 for ( i = 0 ; i < ic->parmBytes ;i++)
2478 pic14_emitcode("dec","%s",spname);
2482 /* if register bank was saved then pop them */
2484 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2486 /* if we hade saved some registers then unsave them */
2487 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2488 unsaveRegisters (ic);
2493 /*-----------------------------------------------------------------*/
2494 /* genPcall - generates a call by pointer statement */
2495 /*-----------------------------------------------------------------*/
2496 static void genPcall (iCode *ic)
2499 symbol *rlbl = newiTempLabel(NULL);
2502 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2503 /* if caller saves & we have not saved then */
2507 /* if we are calling a function that is not using
2508 the same register bank then we need to save the
2509 destination registers on the stack */
2510 dtype = operandType(IC_LEFT(ic));
2511 if (currFunc && dtype &&
2512 IFFUNC_ISISR(currFunc->type) &&
2513 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2514 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2517 /* push the return address on to the stack */
2518 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2519 pic14_emitcode("push","acc");
2520 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2521 pic14_emitcode("push","acc");
2523 if (options.model == MODEL_FLAT24)
2525 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2526 pic14_emitcode("push","acc");
2529 /* now push the calling address */
2530 aopOp(IC_LEFT(ic),ic,FALSE);
2532 pushSide(IC_LEFT(ic), FPTRSIZE);
2534 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2536 /* if send set is not empty the assign */
2540 for (sic = setFirstItem(_G.sendSet) ; sic ;
2541 sic = setNextItem(_G.sendSet)) {
2542 int size, offset = 0;
2543 aopOp(IC_LEFT(sic),sic,FALSE);
2544 size = AOP_SIZE(IC_LEFT(sic));
2546 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2548 if (strcmp(l,fReturn[offset]))
2549 pic14_emitcode("mov","%s,%s",
2554 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2559 pic14_emitcode("ret","");
2560 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2563 /* if we need assign a result value */
2564 if ((IS_ITEMP(IC_RESULT(ic)) &&
2565 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2566 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2567 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2570 aopOp(IC_RESULT(ic),ic,FALSE);
2573 assignResultValue(IC_RESULT(ic));
2575 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2578 /* adjust the stack for parameters if
2580 if (ic->parmBytes) {
2582 if (ic->parmBytes > 3) {
2583 pic14_emitcode("mov","a,%s",spname);
2584 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2585 pic14_emitcode("mov","%s,a",spname);
2587 for ( i = 0 ; i < ic->parmBytes ;i++)
2588 pic14_emitcode("dec","%s",spname);
2592 /* if register bank was saved then unsave them */
2593 if (currFunc && dtype &&
2594 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2595 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2597 /* if we hade saved some registers then
2600 unsaveRegisters (ic);
2604 /*-----------------------------------------------------------------*/
2605 /* resultRemat - result is rematerializable */
2606 /*-----------------------------------------------------------------*/
2607 static int resultRemat (iCode *ic)
2609 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2610 if (SKIP_IC(ic) || ic->op == IFX)
2613 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2614 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2615 if (sym->remat && !POINTER_SET(ic))
2622 #if defined(__BORLANDC__) || defined(_MSC_VER)
2623 #define STRCASECMP stricmp
2625 #define STRCASECMP strcasecmp
2629 /*-----------------------------------------------------------------*/
2630 /* inExcludeList - return 1 if the string is in exclude Reg list */
2631 /*-----------------------------------------------------------------*/
2632 static bool inExcludeList(char *s)
2634 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2637 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2638 if (options.excludeRegs[i] &&
2639 STRCASECMP(options.excludeRegs[i],"none") == 0)
2642 for ( i = 0 ; options.excludeRegs[i]; i++) {
2643 if (options.excludeRegs[i] &&
2644 STRCASECMP(s,options.excludeRegs[i]) == 0)
2651 /*-----------------------------------------------------------------*/
2652 /* genFunction - generated code for function entry */
2653 /*-----------------------------------------------------------------*/
2654 static void genFunction (iCode *ic)
2659 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2661 labelOffset += (max_key+4);
2665 /* create the function header */
2666 pic14_emitcode(";","-----------------------------------------");
2667 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2668 pic14_emitcode(";","-----------------------------------------");
2670 pic14_emitcode("","%s:",sym->rname);
2671 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2673 ftype = operandType(IC_LEFT(ic));
2675 /* if critical function then turn interrupts off */
2676 if (IFFUNC_ISCRITICAL(ftype))
2677 pic14_emitcode("clr","ea");
2679 /* here we need to generate the equates for the
2680 register bank if required */
2682 if (FUNC_REGBANK(ftype) != rbank) {
2685 rbank = FUNC_REGBANK(ftype);
2686 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2687 if (strcmp(regspic14[i].base,"0") == 0)
2688 pic14_emitcode("","%s = 0x%02x",
2690 8*rbank+regspic14[i].offset);
2692 pic14_emitcode ("","%s = %s + 0x%02x",
2695 8*rbank+regspic14[i].offset);
2700 /* if this is an interrupt service routine then
2701 save acc, b, dpl, dph */
2702 if (IFFUNC_ISISR(sym->type)) {
2703 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2704 emitpcodeNULLop(POC_NOP);
2705 emitpcodeNULLop(POC_NOP);
2706 emitpcodeNULLop(POC_NOP);
2707 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2708 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2709 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2710 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2712 pBlockConvert2ISR(pb);
2714 if (!inExcludeList("acc"))
2715 pic14_emitcode ("push","acc");
2716 if (!inExcludeList("b"))
2717 pic14_emitcode ("push","b");
2718 if (!inExcludeList("dpl"))
2719 pic14_emitcode ("push","dpl");
2720 if (!inExcludeList("dph"))
2721 pic14_emitcode ("push","dph");
2722 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2724 pic14_emitcode ("push", "dpx");
2725 /* Make sure we're using standard DPTR */
2726 pic14_emitcode ("push", "dps");
2727 pic14_emitcode ("mov", "dps, #0x00");
2728 if (options.stack10bit)
2730 /* This ISR could conceivably use DPTR2. Better save it. */
2731 pic14_emitcode ("push", "dpl1");
2732 pic14_emitcode ("push", "dph1");
2733 pic14_emitcode ("push", "dpx1");
2736 /* if this isr has no bank i.e. is going to
2737 run with bank 0 , then we need to save more
2739 if (!FUNC_REGBANK(sym->type)) {
2741 /* if this function does not call any other
2742 function then we can be economical and
2743 save only those registers that are used */
2744 if (! IFFUNC_HASFCALL(sym->type)) {
2747 /* if any registers used */
2748 if (sym->regsUsed) {
2749 /* save the registers used */
2750 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2751 if (bitVectBitValue(sym->regsUsed,i) ||
2752 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2753 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2758 /* this function has a function call cannot
2759 determines register usage so we will have the
2761 saverbank(0,ic,FALSE);
2766 /* if callee-save to be used for this function
2767 then save the registers being used in this function */
2768 if (IFFUNC_CALLEESAVES(sym->type)) {
2771 /* if any registers used */
2772 if (sym->regsUsed) {
2773 /* save the registers used */
2774 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2775 if (bitVectBitValue(sym->regsUsed,i) ||
2776 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2777 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2785 /* set the register bank to the desired value */
2786 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2787 pic14_emitcode("push","psw");
2788 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2791 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2793 if (options.useXstack) {
2794 pic14_emitcode("mov","r0,%s",spname);
2795 pic14_emitcode("mov","a,_bp");
2796 pic14_emitcode("movx","@r0,a");
2797 pic14_emitcode("inc","%s",spname);
2801 /* set up the stack */
2802 pic14_emitcode ("push","_bp"); /* save the callers stack */
2804 pic14_emitcode ("mov","_bp,%s",spname);
2807 /* adjust the stack for the function */
2812 werror(W_STACK_OVERFLOW,sym->name);
2814 if (i > 3 && sym->recvSize < 4) {
2816 pic14_emitcode ("mov","a,sp");
2817 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2818 pic14_emitcode ("mov","sp,a");
2823 pic14_emitcode("inc","sp");
2828 pic14_emitcode ("mov","a,_spx");
2829 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2830 pic14_emitcode ("mov","_spx,a");
2835 /*-----------------------------------------------------------------*/
2836 /* genEndFunction - generates epilogue for functions */
2837 /*-----------------------------------------------------------------*/
2838 static void genEndFunction (iCode *ic)
2840 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2842 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2844 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2846 pic14_emitcode ("mov","%s,_bp",spname);
2849 /* if use external stack but some variables were
2850 added to the local stack then decrement the
2852 if (options.useXstack && sym->stack) {
2853 pic14_emitcode("mov","a,sp");
2854 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2855 pic14_emitcode("mov","sp,a");
2859 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2860 if (options.useXstack) {
2861 pic14_emitcode("mov","r0,%s",spname);
2862 pic14_emitcode("movx","a,@r0");
2863 pic14_emitcode("mov","_bp,a");
2864 pic14_emitcode("dec","%s",spname);
2868 pic14_emitcode ("pop","_bp");
2872 /* restore the register bank */
2873 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2874 pic14_emitcode ("pop","psw");
2876 if (IFFUNC_ISISR(sym->type)) {
2878 /* now we need to restore the registers */
2879 /* if this isr has no bank i.e. is going to
2880 run with bank 0 , then we need to save more
2882 if (!FUNC_REGBANK(sym->type)) {
2884 /* if this function does not call any other
2885 function then we can be economical and
2886 save only those registers that are used */
2887 if (! IFFUNC_HASFCALL(sym->type)) {
2890 /* if any registers used */
2891 if (sym->regsUsed) {
2892 /* save the registers used */
2893 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2894 if (bitVectBitValue(sym->regsUsed,i) ||
2895 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2896 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2901 /* this function has a function call cannot
2902 determines register usage so we will have the
2904 unsaverbank(0,ic,FALSE);
2908 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2910 if (options.stack10bit)
2912 pic14_emitcode ("pop", "dpx1");
2913 pic14_emitcode ("pop", "dph1");
2914 pic14_emitcode ("pop", "dpl1");
2916 pic14_emitcode ("pop", "dps");
2917 pic14_emitcode ("pop", "dpx");
2919 if (!inExcludeList("dph"))
2920 pic14_emitcode ("pop","dph");
2921 if (!inExcludeList("dpl"))
2922 pic14_emitcode ("pop","dpl");
2923 if (!inExcludeList("b"))
2924 pic14_emitcode ("pop","b");
2925 if (!inExcludeList("acc"))
2926 pic14_emitcode ("pop","acc");
2928 if (IFFUNC_ISCRITICAL(sym->type))
2929 pic14_emitcode("setb","ea");
2932 /* if debug then send end of function */
2933 /* if (options.debug && currFunc) { */
2936 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2937 FileBaseName(ic->filename),currFunc->lastLine,
2938 ic->level,ic->block);
2939 if (IS_STATIC(currFunc->etype))
2940 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2942 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2946 pic14_emitcode ("reti","");
2948 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2949 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2950 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2951 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2952 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2953 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2955 emitpcodeNULLop(POC_RETFIE);
2959 if (IFFUNC_ISCRITICAL(sym->type))
2960 pic14_emitcode("setb","ea");
2962 if (IFFUNC_CALLEESAVES(sym->type)) {
2965 /* if any registers used */
2966 if (sym->regsUsed) {
2967 /* save the registers used */
2968 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2969 if (bitVectBitValue(sym->regsUsed,i) ||
2970 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2971 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2977 /* if debug then send end of function */
2980 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2981 FileBaseName(ic->filename),currFunc->lastLine,
2982 ic->level,ic->block);
2983 if (IS_STATIC(currFunc->etype))
2984 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2986 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2990 pic14_emitcode ("return","");
2991 emitpcodeNULLop(POC_RETURN);
2993 /* Mark the end of a function */
2994 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2999 /*-----------------------------------------------------------------*/
3000 /* genRet - generate code for return statement */
3001 /*-----------------------------------------------------------------*/
3002 static void genRet (iCode *ic)
3004 int size,offset = 0 , pushed = 0;
3006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3007 /* if we have no return value then
3008 just generate the "ret" */
3012 /* we have something to return then
3013 move the return value into place */
3014 aopOp(IC_LEFT(ic),ic,FALSE);
3015 size = AOP_SIZE(IC_LEFT(ic));
3019 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3021 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3023 pic14_emitcode("push","%s",l);
3026 l = aopGet(AOP(IC_LEFT(ic)),offset,
3028 if (strcmp(fReturn[offset],l)) {
3029 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3030 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3031 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3033 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3036 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3046 if (strcmp(fReturn[pushed],"a"))
3047 pic14_emitcode("pop",fReturn[pushed]);
3049 pic14_emitcode("pop","acc");
3052 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3055 /* generate a jump to the return label
3056 if the next is not the return statement */
3057 if (!(ic->next && ic->next->op == LABEL &&
3058 IC_LABEL(ic->next) == returnLabel)) {
3060 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3061 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3066 /*-----------------------------------------------------------------*/
3067 /* genLabel - generates a label */
3068 /*-----------------------------------------------------------------*/
3069 static void genLabel (iCode *ic)
3071 /* special case never generate */
3072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3073 if (IC_LABEL(ic) == entryLabel)
3076 emitpLabel(IC_LABEL(ic)->key);
3077 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3080 /*-----------------------------------------------------------------*/
3081 /* genGoto - generates a goto */
3082 /*-----------------------------------------------------------------*/
3084 static void genGoto (iCode *ic)
3086 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3087 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3091 /*-----------------------------------------------------------------*/
3092 /* genMultbits :- multiplication of bits */
3093 /*-----------------------------------------------------------------*/
3094 static void genMultbits (operand *left,
3098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3100 if(!pic14_sameRegs(AOP(result),AOP(right)))
3101 emitpcode(POC_BSF, popGet(AOP(result),0));
3103 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3104 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3105 emitpcode(POC_BCF, popGet(AOP(result),0));
3110 /*-----------------------------------------------------------------*/
3111 /* genMultOneByte : 8 bit multiplication & division */
3112 /*-----------------------------------------------------------------*/
3113 static void genMultOneByte (operand *left,
3117 sym_link *opetype = operandType(result);
3122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3123 DEBUGpic14_AopType(__LINE__,left,right,result);
3124 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3126 /* (if two literals, the value is computed before) */
3127 /* if one literal, literal on the right */
3128 if (AOP_TYPE(left) == AOP_LIT){
3134 size = AOP_SIZE(result);
3137 if (AOP_TYPE(right) == AOP_LIT){
3138 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3139 aopGet(AOP(right),0,FALSE,FALSE),
3140 aopGet(AOP(left),0,FALSE,FALSE),
3141 aopGet(AOP(result),0,FALSE,FALSE));
3142 pic14_emitcode("call","genMultLit");
3144 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3145 aopGet(AOP(right),0,FALSE,FALSE),
3146 aopGet(AOP(left),0,FALSE,FALSE),
3147 aopGet(AOP(result),0,FALSE,FALSE));
3148 pic14_emitcode("call","genMult8X8_8");
3151 genMult8X8_8 (left, right,result);
3154 /* signed or unsigned */
3155 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3156 //l = aopGet(AOP(left),0,FALSE,FALSE);
3158 //pic14_emitcode("mul","ab");
3159 /* if result size = 1, mul signed = mul unsigned */
3160 //aopPut(AOP(result),"a",0);
3162 } else { // (size > 1)
3164 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3165 aopGet(AOP(right),0,FALSE,FALSE),
3166 aopGet(AOP(left),0,FALSE,FALSE),
3167 aopGet(AOP(result),0,FALSE,FALSE));
3169 if (SPEC_USIGN(opetype)){
3170 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3171 genUMult8X8_16 (left, right, result, NULL);
3174 /* for filling the MSBs */
3175 emitpcode(POC_CLRF, popGet(AOP(result),2));
3176 emitpcode(POC_CLRF, popGet(AOP(result),3));
3180 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3182 pic14_emitcode("mov","a,b");
3184 /* adjust the MSB if left or right neg */
3186 /* if one literal */
3187 if (AOP_TYPE(right) == AOP_LIT){
3188 pic14_emitcode("multiply ","right is a lit");
3189 /* AND literal negative */
3190 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3191 /* adjust MSB (c==0 after mul) */
3192 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3196 genSMult8X8_16 (left, right, result, NULL);
3200 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3202 pic14_emitcode("rlc","a");
3203 pic14_emitcode("subb","a,acc");
3211 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3212 //aopPut(AOP(result),"a",offset++);
3216 /*-----------------------------------------------------------------*/
3217 /* genMult - generates code for multiplication */
3218 /*-----------------------------------------------------------------*/
3219 static void genMult (iCode *ic)
3221 operand *left = IC_LEFT(ic);
3222 operand *right = IC_RIGHT(ic);
3223 operand *result= IC_RESULT(ic);
3225 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3226 /* assign the amsops */
3227 aopOp (left,ic,FALSE);
3228 aopOp (right,ic,FALSE);
3229 aopOp (result,ic,TRUE);
3231 DEBUGpic14_AopType(__LINE__,left,right,result);
3233 /* special cases first */
3235 if (AOP_TYPE(left) == AOP_CRY &&
3236 AOP_TYPE(right)== AOP_CRY) {
3237 genMultbits(left,right,result);
3241 /* if both are of size == 1 */
3242 if (AOP_SIZE(left) == 1 &&
3243 AOP_SIZE(right) == 1 ) {
3244 genMultOneByte(left,right,result);
3248 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3250 /* should have been converted to function call */
3254 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3255 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3256 freeAsmop(result,NULL,ic,TRUE);
3259 /*-----------------------------------------------------------------*/
3260 /* genDivbits :- division of bits */
3261 /*-----------------------------------------------------------------*/
3262 static void genDivbits (operand *left,
3269 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3270 /* the result must be bit */
3271 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3272 l = aopGet(AOP(left),0,FALSE,FALSE);
3276 pic14_emitcode("div","ab");
3277 pic14_emitcode("rrc","a");
3278 aopPut(AOP(result),"c",0);
3281 /*-----------------------------------------------------------------*/
3282 /* genDivOneByte : 8 bit division */
3283 /*-----------------------------------------------------------------*/
3284 static void genDivOneByte (operand *left,
3288 sym_link *opetype = operandType(result);
3293 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3294 size = AOP_SIZE(result) - 1;
3296 /* signed or unsigned */
3297 if (SPEC_USIGN(opetype)) {
3298 /* unsigned is easy */
3299 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3300 l = aopGet(AOP(left),0,FALSE,FALSE);
3302 pic14_emitcode("div","ab");
3303 aopPut(AOP(result),"a",0);
3305 aopPut(AOP(result),zero,offset++);
3309 /* signed is a little bit more difficult */
3311 /* save the signs of the operands */
3312 l = aopGet(AOP(left),0,FALSE,FALSE);
3314 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3315 pic14_emitcode("push","acc"); /* save it on the stack */
3317 /* now sign adjust for both left & right */
3318 l = aopGet(AOP(right),0,FALSE,FALSE);
3320 lbl = newiTempLabel(NULL);
3321 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3322 pic14_emitcode("cpl","a");
3323 pic14_emitcode("inc","a");
3324 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3325 pic14_emitcode("mov","b,a");
3327 /* sign adjust left side */
3328 l = aopGet(AOP(left),0,FALSE,FALSE);
3331 lbl = newiTempLabel(NULL);
3332 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3333 pic14_emitcode("cpl","a");
3334 pic14_emitcode("inc","a");
3335 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3337 /* now the division */
3338 pic14_emitcode("div","ab");
3339 /* we are interested in the lower order
3341 pic14_emitcode("mov","b,a");
3342 lbl = newiTempLabel(NULL);
3343 pic14_emitcode("pop","acc");
3344 /* if there was an over flow we don't
3345 adjust the sign of the result */
3346 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3347 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3349 pic14_emitcode("clr","a");
3350 pic14_emitcode("subb","a,b");
3351 pic14_emitcode("mov","b,a");
3352 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3354 /* now we are done */
3355 aopPut(AOP(result),"b",0);
3357 pic14_emitcode("mov","c,b.7");
3358 pic14_emitcode("subb","a,acc");
3361 aopPut(AOP(result),"a",offset++);
3365 /*-----------------------------------------------------------------*/
3366 /* genDiv - generates code for division */
3367 /*-----------------------------------------------------------------*/
3368 static void genDiv (iCode *ic)
3370 operand *left = IC_LEFT(ic);
3371 operand *right = IC_RIGHT(ic);
3372 operand *result= IC_RESULT(ic);
3374 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3375 /* assign the amsops */
3376 aopOp (left,ic,FALSE);
3377 aopOp (right,ic,FALSE);
3378 aopOp (result,ic,TRUE);
3380 /* special cases first */
3382 if (AOP_TYPE(left) == AOP_CRY &&
3383 AOP_TYPE(right)== AOP_CRY) {
3384 genDivbits(left,right,result);
3388 /* if both are of size == 1 */
3389 if (AOP_SIZE(left) == 1 &&
3390 AOP_SIZE(right) == 1 ) {
3391 genDivOneByte(left,right,result);
3395 /* should have been converted to function call */
3398 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3399 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3400 freeAsmop(result,NULL,ic,TRUE);
3403 /*-----------------------------------------------------------------*/
3404 /* genModbits :- modulus of bits */
3405 /*-----------------------------------------------------------------*/
3406 static void genModbits (operand *left,
3413 /* the result must be bit */
3414 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3415 l = aopGet(AOP(left),0,FALSE,FALSE);
3419 pic14_emitcode("div","ab");
3420 pic14_emitcode("mov","a,b");
3421 pic14_emitcode("rrc","a");
3422 aopPut(AOP(result),"c",0);
3425 /*-----------------------------------------------------------------*/
3426 /* genModOneByte : 8 bit modulus */
3427 /*-----------------------------------------------------------------*/
3428 static void genModOneByte (operand *left,
3432 sym_link *opetype = operandType(result);
3436 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3437 /* signed or unsigned */
3438 if (SPEC_USIGN(opetype)) {
3439 /* unsigned is easy */
3440 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3441 l = aopGet(AOP(left),0,FALSE,FALSE);
3443 pic14_emitcode("div","ab");
3444 aopPut(AOP(result),"b",0);
3448 /* signed is a little bit more difficult */
3450 /* save the signs of the operands */
3451 l = aopGet(AOP(left),0,FALSE,FALSE);
3454 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3455 pic14_emitcode("push","acc"); /* save it on the stack */
3457 /* now sign adjust for both left & right */
3458 l = aopGet(AOP(right),0,FALSE,FALSE);
3461 lbl = newiTempLabel(NULL);
3462 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3463 pic14_emitcode("cpl","a");
3464 pic14_emitcode("inc","a");
3465 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3466 pic14_emitcode("mov","b,a");
3468 /* sign adjust left side */
3469 l = aopGet(AOP(left),0,FALSE,FALSE);
3472 lbl = newiTempLabel(NULL);
3473 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3474 pic14_emitcode("cpl","a");
3475 pic14_emitcode("inc","a");
3476 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3478 /* now the multiplication */
3479 pic14_emitcode("div","ab");
3480 /* we are interested in the lower order
3482 lbl = newiTempLabel(NULL);
3483 pic14_emitcode("pop","acc");
3484 /* if there was an over flow we don't
3485 adjust the sign of the result */
3486 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3487 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3489 pic14_emitcode("clr","a");
3490 pic14_emitcode("subb","a,b");
3491 pic14_emitcode("mov","b,a");
3492 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3494 /* now we are done */
3495 aopPut(AOP(result),"b",0);
3499 /*-----------------------------------------------------------------*/
3500 /* genMod - generates code for division */
3501 /*-----------------------------------------------------------------*/
3502 static void genMod (iCode *ic)
3504 operand *left = IC_LEFT(ic);
3505 operand *right = IC_RIGHT(ic);
3506 operand *result= IC_RESULT(ic);
3508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3509 /* assign the amsops */
3510 aopOp (left,ic,FALSE);
3511 aopOp (right,ic,FALSE);
3512 aopOp (result,ic,TRUE);
3514 /* special cases first */
3516 if (AOP_TYPE(left) == AOP_CRY &&
3517 AOP_TYPE(right)== AOP_CRY) {
3518 genModbits(left,right,result);
3522 /* if both are of size == 1 */
3523 if (AOP_SIZE(left) == 1 &&
3524 AOP_SIZE(right) == 1 ) {
3525 genModOneByte(left,right,result);
3529 /* should have been converted to function call */
3533 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3534 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3535 freeAsmop(result,NULL,ic,TRUE);
3538 /*-----------------------------------------------------------------*/
3539 /* genIfxJump :- will create a jump depending on the ifx */
3540 /*-----------------------------------------------------------------*/
3542 note: May need to add parameter to indicate when a variable is in bit space.
3544 static void genIfxJump (iCode *ic, char *jval)
3547 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3548 /* if true label then we jump if condition
3550 if ( IC_TRUE(ic) ) {
3552 if(strcmp(jval,"a") == 0)
3554 else if (strcmp(jval,"c") == 0)
3557 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3558 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3561 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3562 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3566 /* false label is present */
3567 if(strcmp(jval,"a") == 0)
3569 else if (strcmp(jval,"c") == 0)
3572 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3573 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3576 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3577 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3582 /* mark the icode as generated */
3586 /*-----------------------------------------------------------------*/
3588 /*-----------------------------------------------------------------*/
3589 static void genSkip(iCode *ifx,int status_bit)
3594 if ( IC_TRUE(ifx) ) {
3595 switch(status_bit) {
3610 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3611 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3615 switch(status_bit) {
3629 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3630 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3636 /*-----------------------------------------------------------------*/
3638 /*-----------------------------------------------------------------*/
3639 static void genSkipc(resolvedIfx *rifx)
3649 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3650 rifx->generated = 1;
3653 /*-----------------------------------------------------------------*/
3655 /*-----------------------------------------------------------------*/
3656 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3661 if( (rifx->condition ^ invert_condition) & 1)
3666 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3667 rifx->generated = 1;
3670 /*-----------------------------------------------------------------*/
3672 /*-----------------------------------------------------------------*/
3673 static void genSkipz(iCode *ifx, int condition)
3684 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3686 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3689 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3691 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3694 /*-----------------------------------------------------------------*/
3696 /*-----------------------------------------------------------------*/
3697 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3703 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3705 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3708 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3709 rifx->generated = 1;
3713 /*-----------------------------------------------------------------*/
3714 /* genChkZeroes :- greater or less than comparison */
3715 /* For each byte in a literal that is zero, inclusive or the */
3716 /* the corresponding byte in the operand with W */
3717 /* returns true if any of the bytes are zero */
3718 /*-----------------------------------------------------------------*/
3719 static int genChkZeroes(operand *op, int lit, int size)
3726 i = (lit >> (size*8)) & 0xff;
3730 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3732 emitpcode(POC_IORFW, popGet(AOP(op),size));
3741 /*-----------------------------------------------------------------*/
3742 /* genCmp :- greater or less than comparison */
3743 /*-----------------------------------------------------------------*/
3744 static void genCmp (operand *left,operand *right,
3745 operand *result, iCode *ifx, int sign)
3747 int size; //, offset = 0 ;
3748 unsigned long lit = 0L,i = 0;
3749 resolvedIfx rFalseIfx;
3750 // resolvedIfx rTrueIfx;
3752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3755 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3756 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3760 resolveIfx(&rFalseIfx,ifx);
3761 truelbl = newiTempLabel(NULL);
3762 size = max(AOP_SIZE(left),AOP_SIZE(right));
3766 /* if literal is on the right then swap with left */
3767 if ((AOP_TYPE(right) == AOP_LIT)) {
3768 operand *tmp = right ;
3769 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3770 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3773 lit = (lit - 1) & mask;
3776 rFalseIfx.condition ^= 1;
3779 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3780 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3784 //if(IC_TRUE(ifx) == NULL)
3785 /* if left & right are bit variables */
3786 if (AOP_TYPE(left) == AOP_CRY &&
3787 AOP_TYPE(right) == AOP_CRY ) {
3788 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3789 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3791 /* subtract right from left if at the
3792 end the carry flag is set then we know that
3793 left is greater than right */
3797 symbol *lbl = newiTempLabel(NULL);
3800 if(AOP_TYPE(right) == AOP_LIT) {
3802 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3804 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3811 genSkipCond(&rFalseIfx,left,size-1,7);
3813 /* no need to compare to 0...*/
3814 /* NOTE: this is a de-generate compare that most certainly
3815 * creates some dead code. */
3816 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3818 if(ifx) ifx->generated = 1;
3825 //i = (lit >> (size*8)) & 0xff;
3826 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3828 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3830 i = ((0-lit) & 0xff);
3833 /* lit is 0x7f, all signed chars are less than
3834 * this except for 0x7f itself */
3835 emitpcode(POC_XORLW, popGetLit(0x7f));
3836 genSkipz2(&rFalseIfx,0);
3838 emitpcode(POC_ADDLW, popGetLit(0x80));
3839 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3840 genSkipc(&rFalseIfx);
3845 genSkipz2(&rFalseIfx,1);
3847 emitpcode(POC_ADDLW, popGetLit(i));
3848 genSkipc(&rFalseIfx);
3852 if(ifx) ifx->generated = 1;
3856 /* chars are out of the way. now do ints and longs */
3859 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3866 genSkipCond(&rFalseIfx,left,size,7);
3867 if(ifx) ifx->generated = 1;
3872 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3874 //rFalseIfx.condition ^= 1;
3875 //genSkipCond(&rFalseIfx,left,size,7);
3876 //rFalseIfx.condition ^= 1;
3878 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3879 if(rFalseIfx.condition)
3880 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3882 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3884 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3885 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3886 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3889 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3891 if(rFalseIfx.condition) {
3893 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3899 genSkipc(&rFalseIfx);
3900 emitpLabel(truelbl->key);
3901 if(ifx) ifx->generated = 1;
3908 if( (lit & 0xff) == 0) {
3909 /* lower byte is zero */
3910 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3911 i = ((lit >> 8) & 0xff) ^0x80;
3912 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3913 emitpcode(POC_ADDLW, popGetLit( 0x80));
3914 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3915 genSkipc(&rFalseIfx);
3918 if(ifx) ifx->generated = 1;
3923 /* Special cases for signed longs */
3924 if( (lit & 0xffffff) == 0) {
3925 /* lower byte is zero */
3926 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3927 i = ((lit >> 8*3) & 0xff) ^0x80;
3928 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3929 emitpcode(POC_ADDLW, popGetLit( 0x80));
3930 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3931 genSkipc(&rFalseIfx);
3934 if(ifx) ifx->generated = 1;
3942 if(lit & (0x80 << (size*8))) {
3943 /* lit is negative */
3944 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3946 //genSkipCond(&rFalseIfx,left,size,7);
3948 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3950 if(rFalseIfx.condition)
3951 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3953 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3957 /* lit is positive */
3958 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3959 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3960 if(rFalseIfx.condition)
3961 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3963 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3968 This works, but is only good for ints.
3969 It also requires a "known zero" register.
3970 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3971 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3972 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3973 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3974 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3975 genSkipc(&rFalseIfx);
3977 emitpLabel(truelbl->key);
3978 if(ifx) ifx->generated = 1;
3982 /* There are no more special cases, so perform a general compare */
3984 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3985 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3989 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3991 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3993 //rFalseIfx.condition ^= 1;
3994 genSkipc(&rFalseIfx);
3996 emitpLabel(truelbl->key);
3998 if(ifx) ifx->generated = 1;
4005 /* sign is out of the way. So now do an unsigned compare */
4006 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4009 /* General case - compare to an unsigned literal on the right.*/
4011 i = (lit >> (size*8)) & 0xff;
4012 emitpcode(POC_MOVLW, popGetLit(i));
4013 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4015 i = (lit >> (size*8)) & 0xff;
4018 emitpcode(POC_MOVLW, popGetLit(i));
4020 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4022 /* this byte of the lit is zero,
4023 *if it's not the last then OR in the variable */
4025 emitpcode(POC_IORFW, popGet(AOP(left),size));
4030 emitpLabel(lbl->key);
4031 //if(emitFinalCheck)
4032 genSkipc(&rFalseIfx);
4034 emitpLabel(truelbl->key);
4036 if(ifx) ifx->generated = 1;
4042 if(AOP_TYPE(left) == AOP_LIT) {
4043 //symbol *lbl = newiTempLabel(NULL);
4045 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4048 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4051 if((lit == 0) && (sign == 0)){
4054 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4056 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4058 genSkipz2(&rFalseIfx,0);
4059 if(ifx) ifx->generated = 1;
4066 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4067 /* degenerate compare can never be true */
4068 if(rFalseIfx.condition == 0)
4069 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4071 if(ifx) ifx->generated = 1;
4076 /* signed comparisons to a literal byte */
4078 int lp1 = (lit+1) & 0xff;
4080 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4083 rFalseIfx.condition ^= 1;
4084 genSkipCond(&rFalseIfx,right,0,7);
4087 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4088 emitpcode(POC_XORLW, popGetLit(0x7f));
4089 genSkipz2(&rFalseIfx,1);
4092 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4093 emitpcode(POC_ADDLW, popGetLit(0x80));
4094 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4095 rFalseIfx.condition ^= 1;
4096 genSkipc(&rFalseIfx);
4100 /* unsigned comparisons to a literal byte */
4102 switch(lit & 0xff ) {
4104 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4105 genSkipz2(&rFalseIfx,0);
4108 rFalseIfx.condition ^= 1;
4109 genSkipCond(&rFalseIfx,right,0,7);
4113 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4114 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4115 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4116 rFalseIfx.condition ^= 1;
4117 genSkipc(&rFalseIfx);
4122 if(ifx) ifx->generated = 1;
4127 /* Size is greater than 1 */
4135 /* this means lit = 0xffffffff, or -1 */
4138 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4139 rFalseIfx.condition ^= 1;
4140 genSkipCond(&rFalseIfx,right,size,7);
4141 if(ifx) ifx->generated = 1;
4148 if(rFalseIfx.condition) {
4149 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4150 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4153 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4155 emitpcode(POC_IORFW, popGet(AOP(right),size));
4159 if(rFalseIfx.condition) {
4160 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4161 emitpLabel(truelbl->key);
4163 rFalseIfx.condition ^= 1;
4164 genSkipCond(&rFalseIfx,right,s,7);
4167 if(ifx) ifx->generated = 1;
4171 if((size == 1) && (0 == (lp1&0xff))) {
4172 /* lower byte of signed word is zero */
4173 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4174 i = ((lp1 >> 8) & 0xff) ^0x80;
4175 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4176 emitpcode(POC_ADDLW, popGetLit( 0x80));
4177 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4178 rFalseIfx.condition ^= 1;
4179 genSkipc(&rFalseIfx);
4182 if(ifx) ifx->generated = 1;
4186 if(lit & (0x80 << (size*8))) {
4187 /* Lit is less than zero */
4188 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4189 //rFalseIfx.condition ^= 1;
4190 //genSkipCond(&rFalseIfx,left,size,7);
4191 //rFalseIfx.condition ^= 1;
4192 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4193 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4195 if(rFalseIfx.condition)
4196 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4198 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4202 /* Lit is greater than or equal to zero */
4203 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4204 //rFalseIfx.condition ^= 1;
4205 //genSkipCond(&rFalseIfx,right,size,7);
4206 //rFalseIfx.condition ^= 1;
4208 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4209 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4211 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4212 if(rFalseIfx.condition)
4213 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4215 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4220 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4221 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4225 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4227 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4229 rFalseIfx.condition ^= 1;
4230 //rFalseIfx.condition = 1;
4231 genSkipc(&rFalseIfx);
4233 emitpLabel(truelbl->key);
4235 if(ifx) ifx->generated = 1;
4240 /* compare word or long to an unsigned literal on the right.*/
4245 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4248 break; /* handled above */
4251 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4253 emitpcode(POC_IORFW, popGet(AOP(right),size));
4254 genSkipz2(&rFalseIfx,0);
4258 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4260 emitpcode(POC_IORFW, popGet(AOP(right),size));
4263 if(rFalseIfx.condition)
4264 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4266 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4269 emitpcode(POC_MOVLW, popGetLit(lit+1));
4270 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4272 rFalseIfx.condition ^= 1;
4273 genSkipc(&rFalseIfx);
4276 emitpLabel(truelbl->key);
4278 if(ifx) ifx->generated = 1;
4284 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4285 i = (lit >> (size*8)) & 0xff;
4287 emitpcode(POC_MOVLW, popGetLit(i));
4288 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4291 i = (lit >> (size*8)) & 0xff;
4294 emitpcode(POC_MOVLW, popGetLit(i));
4296 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4298 /* this byte of the lit is zero,
4299 *if it's not the last then OR in the variable */
4301 emitpcode(POC_IORFW, popGet(AOP(right),size));
4306 emitpLabel(lbl->key);
4308 rFalseIfx.condition ^= 1;
4309 genSkipc(&rFalseIfx);
4313 emitpLabel(truelbl->key);
4314 if(ifx) ifx->generated = 1;
4318 /* Compare two variables */
4320 DEBUGpic14_emitcode(";sign","%d",sign);
4324 /* Sigh. thus sucks... */
4326 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4327 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4328 emitpcode(POC_MOVLW, popGetLit(0x80));
4329 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4330 emitpcode(POC_XORFW, popGet(AOP(right),size));
4331 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4333 /* Signed char comparison */
4334 /* Special thanks to Nikolai Golovchenko for this snippet */
4335 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4336 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4337 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4338 emitpcode(POC_XORFW, popGet(AOP(left),0));
4339 emitpcode(POC_XORFW, popGet(AOP(right),0));
4340 emitpcode(POC_ADDLW, popGetLit(0x80));
4342 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4343 genSkipc(&rFalseIfx);
4345 if(ifx) ifx->generated = 1;
4351 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4352 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4356 /* The rest of the bytes of a multi-byte compare */
4360 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4363 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4364 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4369 emitpLabel(lbl->key);
4371 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4372 genSkipc(&rFalseIfx);
4373 if(ifx) ifx->generated = 1;
4378 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4379 pic14_outBitC(result);
4381 /* if the result is used in the next
4382 ifx conditional branch then generate
4383 code a little differently */
4385 genIfxJump (ifx,"c");
4387 pic14_outBitC(result);
4388 /* leave the result in acc */
4393 /*-----------------------------------------------------------------*/
4394 /* genCmpGt :- greater than comparison */
4395 /*-----------------------------------------------------------------*/
4396 static void genCmpGt (iCode *ic, iCode *ifx)
4398 operand *left, *right, *result;
4399 sym_link *letype , *retype;
4402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4404 right= IC_RIGHT(ic);
4405 result = IC_RESULT(ic);
4407 letype = getSpec(operandType(left));
4408 retype =getSpec(operandType(right));
4409 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4410 /* assign the amsops */
4411 aopOp (left,ic,FALSE);
4412 aopOp (right,ic,FALSE);
4413 aopOp (result,ic,TRUE);
4415 genCmp(right, left, result, ifx, sign);
4417 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4418 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4419 freeAsmop(result,NULL,ic,TRUE);
4422 /*-----------------------------------------------------------------*/
4423 /* genCmpLt - less than comparisons */
4424 /*-----------------------------------------------------------------*/
4425 static void genCmpLt (iCode *ic, iCode *ifx)
4427 operand *left, *right, *result;
4428 sym_link *letype , *retype;
4431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4433 right= IC_RIGHT(ic);
4434 result = IC_RESULT(ic);
4436 letype = getSpec(operandType(left));
4437 retype =getSpec(operandType(right));
4438 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4440 /* assign the amsops */
4441 aopOp (left,ic,FALSE);
4442 aopOp (right,ic,FALSE);
4443 aopOp (result,ic,TRUE);
4445 genCmp(left, right, result, ifx, sign);
4447 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4448 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4449 freeAsmop(result,NULL,ic,TRUE);
4452 /*-----------------------------------------------------------------*/
4453 /* genc16bit2lit - compare a 16 bit value to a literal */
4454 /*-----------------------------------------------------------------*/
4455 static void genc16bit2lit(operand *op, int lit, int offset)
4459 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4460 if( (lit&0xff) == 0)
4465 switch( BYTEofLONG(lit,i)) {
4467 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4470 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4473 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4476 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4477 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4482 switch( BYTEofLONG(lit,i)) {
4484 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4488 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4492 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4495 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4497 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4503 /*-----------------------------------------------------------------*/
4504 /* gencjneshort - compare and jump if not equal */
4505 /*-----------------------------------------------------------------*/
4506 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4508 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4513 unsigned long lit = 0L;
4514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4515 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4517 resolveIfx(&rIfx,ifx);
4518 lbl = newiTempLabel(NULL);
4521 /* if the left side is a literal or
4522 if the right is in a pointer register and left
4524 if ((AOP_TYPE(left) == AOP_LIT) ||
4525 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4530 if(AOP_TYPE(right) == AOP_LIT)
4531 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4533 /* if the right side is a literal then anything goes */
4534 if (AOP_TYPE(right) == AOP_LIT &&
4535 AOP_TYPE(left) != AOP_DIR ) {
4538 genc16bit2lit(left, lit, 0);
4540 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4545 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4546 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4548 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4552 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4560 /* if the right side is in a register or in direct space or
4561 if the left is a pointer register & right is not */
4562 else if (AOP_TYPE(right) == AOP_REG ||
4563 AOP_TYPE(right) == AOP_DIR ||
4564 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4565 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4568 genc16bit2lit(left, lit, 0);
4570 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4575 if((AOP_TYPE(left) == AOP_DIR) &&
4576 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4578 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4579 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4581 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4583 switch (lit & 0xff) {
4585 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4588 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4589 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4593 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4594 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4598 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4599 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4604 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4607 if(AOP_TYPE(result) == AOP_CRY) {
4608 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4613 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4615 /* fix me. probably need to check result size too */
4616 emitpcode(POC_CLRF,popGet(AOP(result),0));
4621 emitpcode(POC_INCF,popGet(AOP(result),0));
4631 } else if(AOP_TYPE(right) == AOP_REG &&
4632 AOP_TYPE(left) != AOP_DIR){
4635 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4636 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4637 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4642 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4647 /* right is a pointer reg need both a & b */
4649 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4651 pic14_emitcode("mov","b,%s",l);
4652 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4653 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4657 emitpLabel(lbl->key);
4664 /*-----------------------------------------------------------------*/
4665 /* gencjne - compare and jump if not equal */
4666 /*-----------------------------------------------------------------*/
4667 static void gencjne(operand *left, operand *right, iCode *ifx)
4669 symbol *tlbl = newiTempLabel(NULL);
4671 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4672 gencjneshort(left, right, lbl);
4674 pic14_emitcode("mov","a,%s",one);
4675 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4676 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4677 pic14_emitcode("clr","a");
4678 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4680 emitpLabel(lbl->key);
4681 emitpLabel(tlbl->key);
4686 /*-----------------------------------------------------------------*/
4687 /* genCmpEq - generates code for equal to */
4688 /*-----------------------------------------------------------------*/
4689 static void genCmpEq (iCode *ic, iCode *ifx)
4691 operand *left, *right, *result;
4692 unsigned long lit = 0L;
4695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4698 DEBUGpic14_emitcode ("; ifx is non-null","");
4700 DEBUGpic14_emitcode ("; ifx is null","");
4702 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4703 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4704 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4706 size = max(AOP_SIZE(left),AOP_SIZE(right));
4708 DEBUGpic14_AopType(__LINE__,left,right,result);
4710 /* if literal, literal on the right or
4711 if the right is in a pointer register and left
4713 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4714 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4715 operand *tmp = right ;
4721 if(ifx && !AOP_SIZE(result)){
4723 /* if they are both bit variables */
4724 if (AOP_TYPE(left) == AOP_CRY &&
4725 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4726 if(AOP_TYPE(right) == AOP_LIT){
4727 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4729 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4730 pic14_emitcode("cpl","c");
4731 } else if(lit == 1L) {
4732 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4734 pic14_emitcode("clr","c");
4736 /* AOP_TYPE(right) == AOP_CRY */
4738 symbol *lbl = newiTempLabel(NULL);
4739 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4740 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4741 pic14_emitcode("cpl","c");
4742 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4744 /* if true label then we jump if condition
4746 tlbl = newiTempLabel(NULL);
4747 if ( IC_TRUE(ifx) ) {
4748 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4749 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4751 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4752 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4754 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4757 /* left and right are both bit variables, result is carry */
4760 resolveIfx(&rIfx,ifx);
4762 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4763 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4764 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4765 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4770 /* They're not both bit variables. Is the right a literal? */
4771 if(AOP_TYPE(right) == AOP_LIT) {
4772 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4777 switch(lit & 0xff) {
4779 if ( IC_TRUE(ifx) ) {
4780 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4782 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4784 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4785 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4789 if ( IC_TRUE(ifx) ) {
4790 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4792 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4794 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4795 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4799 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4801 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4806 /* end of size == 1 */
4810 genc16bit2lit(left,lit,offset);
4813 /* end of size == 2 */
4818 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4819 emitpcode(POC_IORFW,popGet(AOP(left),1));
4820 emitpcode(POC_IORFW,popGet(AOP(left),2));
4821 emitpcode(POC_IORFW,popGet(AOP(left),3));
4825 /* search for patterns that can be optimized */
4827 genc16bit2lit(left,lit,0);
4830 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4832 genc16bit2lit(left,lit,2);
4834 emitpcode(POC_IORFW,popGet(AOP(left),2));
4835 emitpcode(POC_IORFW,popGet(AOP(left),3));
4848 } else if(AOP_TYPE(right) == AOP_CRY ) {
4849 /* we know the left is not a bit, but that the right is */
4850 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4851 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4852 popGet(AOP(right),offset));
4853 emitpcode(POC_XORLW,popGetLit(1));
4855 /* if the two are equal, then W will be 0 and the Z bit is set
4856 * we could test Z now, or go ahead and check the high order bytes if
4857 * the variable we're comparing is larger than a byte. */
4860 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4862 if ( IC_TRUE(ifx) ) {
4864 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4865 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4868 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4869 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4873 /* They're both variables that are larger than bits */
4876 tlbl = newiTempLabel(NULL);
4879 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4880 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4882 if ( IC_TRUE(ifx) ) {
4885 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4886 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4889 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4890 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4894 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4895 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4899 if(s>1 && IC_TRUE(ifx)) {
4900 emitpLabel(tlbl->key);
4901 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4905 /* mark the icode as generated */
4910 /* if they are both bit variables */
4911 if (AOP_TYPE(left) == AOP_CRY &&
4912 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4913 if(AOP_TYPE(right) == AOP_LIT){
4914 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4916 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4917 pic14_emitcode("cpl","c");
4918 } else if(lit == 1L) {
4919 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4921 pic14_emitcode("clr","c");
4923 /* AOP_TYPE(right) == AOP_CRY */
4925 symbol *lbl = newiTempLabel(NULL);
4926 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4927 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4928 pic14_emitcode("cpl","c");
4929 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4932 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4933 pic14_outBitC(result);
4937 genIfxJump (ifx,"c");
4940 /* if the result is used in an arithmetic operation
4941 then put the result in place */
4942 pic14_outBitC(result);
4945 gencjne(left,right,result,ifx);
4948 gencjne(left,right,newiTempLabel(NULL));
4950 if(IC_TRUE(ifx)->key)
4951 gencjne(left,right,IC_TRUE(ifx)->key);
4953 gencjne(left,right,IC_FALSE(ifx)->key);
4957 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4958 aopPut(AOP(result),"a",0);
4963 genIfxJump (ifx,"a");
4967 /* if the result is used in an arithmetic operation
4968 then put the result in place */
4970 if (AOP_TYPE(result) != AOP_CRY)
4971 pic14_outAcc(result);
4973 /* leave the result in acc */
4977 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4978 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4979 freeAsmop(result,NULL,ic,TRUE);
4982 /*-----------------------------------------------------------------*/
4983 /* ifxForOp - returns the icode containing the ifx for operand */
4984 /*-----------------------------------------------------------------*/
4985 static iCode *ifxForOp ( operand *op, iCode *ic )
4987 /* if true symbol then needs to be assigned */
4988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4989 if (IS_TRUE_SYMOP(op))
4992 /* if this has register type condition and
4993 the next instruction is ifx with the same operand
4994 and live to of the operand is upto the ifx only then */
4996 ic->next->op == IFX &&
4997 IC_COND(ic->next)->key == op->key &&
4998 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5002 ic->next->op == IFX &&
5003 IC_COND(ic->next)->key == op->key) {
5004 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5008 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5010 ic->next->op == IFX)
5011 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5014 ic->next->op == IFX &&
5015 IC_COND(ic->next)->key == op->key) {
5016 DEBUGpic14_emitcode ("; "," key is okay");
5017 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5018 OP_SYMBOL(op)->liveTo,
5025 /*-----------------------------------------------------------------*/
5026 /* genAndOp - for && operation */
5027 /*-----------------------------------------------------------------*/
5028 static void genAndOp (iCode *ic)
5030 operand *left,*right, *result;
5033 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5034 /* note here that && operations that are in an
5035 if statement are taken away by backPatchLabels
5036 only those used in arthmetic operations remain */
5037 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5038 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5039 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5041 /* if both are bit variables */
5042 if (AOP_TYPE(left) == AOP_CRY &&
5043 AOP_TYPE(right) == AOP_CRY ) {
5044 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5045 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
5046 pic14_outBitC(result);
5048 tlbl = newiTempLabel(NULL);
5049 pic14_toBoolean(left);
5050 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
5051 pic14_toBoolean(right);
5052 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5053 pic14_outBitAcc(result);
5056 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5057 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5058 freeAsmop(result,NULL,ic,TRUE);
5062 /*-----------------------------------------------------------------*/
5063 /* genOrOp - for || operation */
5064 /*-----------------------------------------------------------------*/
5067 modified this code, but it doesn't appear to ever get called
5070 static void genOrOp (iCode *ic)
5072 operand *left,*right, *result;
5075 /* note here that || operations that are in an
5076 if statement are taken away by backPatchLabels
5077 only those used in arthmetic operations remain */
5078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5079 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5080 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5081 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5083 DEBUGpic14_AopType(__LINE__,left,right,result);
5085 /* if both are bit variables */
5086 if (AOP_TYPE(left) == AOP_CRY &&
5087 AOP_TYPE(right) == AOP_CRY ) {
5088 pic14_emitcode("clrc","");
5089 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5090 AOP(left)->aopu.aop_dir,
5091 AOP(left)->aopu.aop_dir);
5092 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5093 AOP(right)->aopu.aop_dir,
5094 AOP(right)->aopu.aop_dir);
5095 pic14_emitcode("setc","");
5098 tlbl = newiTempLabel(NULL);
5099 pic14_toBoolean(left);
5101 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5102 pic14_toBoolean(right);
5103 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5105 pic14_outBitAcc(result);
5108 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5109 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110 freeAsmop(result,NULL,ic,TRUE);
5113 /*-----------------------------------------------------------------*/
5114 /* isLiteralBit - test if lit == 2^n */
5115 /*-----------------------------------------------------------------*/
5116 static int isLiteralBit(unsigned long lit)
5118 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5119 0x100L,0x200L,0x400L,0x800L,
5120 0x1000L,0x2000L,0x4000L,0x8000L,
5121 0x10000L,0x20000L,0x40000L,0x80000L,
5122 0x100000L,0x200000L,0x400000L,0x800000L,
5123 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5124 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5127 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5128 for(idx = 0; idx < 32; idx++)
5134 /*-----------------------------------------------------------------*/
5135 /* continueIfTrue - */
5136 /*-----------------------------------------------------------------*/
5137 static void continueIfTrue (iCode *ic)
5139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5141 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5145 /*-----------------------------------------------------------------*/
5147 /*-----------------------------------------------------------------*/
5148 static void jumpIfTrue (iCode *ic)
5150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5152 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5156 /*-----------------------------------------------------------------*/
5157 /* jmpTrueOrFalse - */
5158 /*-----------------------------------------------------------------*/
5159 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5161 // ugly but optimized by peephole
5162 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5164 symbol *nlbl = newiTempLabel(NULL);
5165 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5166 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5167 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5168 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5171 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5172 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5177 /*-----------------------------------------------------------------*/
5178 /* genAnd - code for and */
5179 /*-----------------------------------------------------------------*/
5180 static void genAnd (iCode *ic, iCode *ifx)
5182 operand *left, *right, *result;
5184 unsigned long lit = 0L;
5189 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5190 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5191 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5192 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5194 resolveIfx(&rIfx,ifx);
5196 /* if left is a literal & right is not then exchange them */
5197 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5198 AOP_NEEDSACC(left)) {
5199 operand *tmp = right ;
5204 /* if result = right then exchange them */
5205 if(pic14_sameRegs(AOP(result),AOP(right))){
5206 operand *tmp = right ;
5211 /* if right is bit then exchange them */
5212 if (AOP_TYPE(right) == AOP_CRY &&
5213 AOP_TYPE(left) != AOP_CRY){
5214 operand *tmp = right ;
5218 if(AOP_TYPE(right) == AOP_LIT)
5219 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5221 size = AOP_SIZE(result);
5223 DEBUGpic14_AopType(__LINE__,left,right,result);
5226 // result = bit & yy;
5227 if (AOP_TYPE(left) == AOP_CRY){
5228 // c = bit & literal;
5229 if(AOP_TYPE(right) == AOP_LIT){
5231 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5234 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5237 if(size && (AOP_TYPE(result) == AOP_CRY)){
5238 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5241 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5245 pic14_emitcode("clr","c");
5248 if (AOP_TYPE(right) == AOP_CRY){
5250 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5251 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5254 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5256 pic14_emitcode("rrc","a");
5257 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5263 pic14_outBitC(result);
5265 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5266 genIfxJump(ifx, "c");
5270 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5271 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5272 if((AOP_TYPE(right) == AOP_LIT) &&
5273 (AOP_TYPE(result) == AOP_CRY) &&
5274 (AOP_TYPE(left) != AOP_CRY)){
5275 int posbit = isLiteralBit(lit);
5279 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5282 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5288 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5289 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5291 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5292 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5295 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5296 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5297 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5304 symbol *tlbl = newiTempLabel(NULL);
5305 int sizel = AOP_SIZE(left);
5307 pic14_emitcode("setb","c");
5309 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5310 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5312 if((posbit = isLiteralBit(bytelit)) != 0)
5313 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5315 if(bytelit != 0x0FFL)
5316 pic14_emitcode("anl","a,%s",
5317 aopGet(AOP(right),offset,FALSE,TRUE));
5318 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5323 // bit = left & literal
5325 pic14_emitcode("clr","c");
5326 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5328 // if(left & literal)
5331 jmpTrueOrFalse(ifx, tlbl);
5335 pic14_outBitC(result);
5339 /* if left is same as result */
5340 if(pic14_sameRegs(AOP(result),AOP(left))){
5342 for(;size--; offset++,lit>>=8) {
5343 if(AOP_TYPE(right) == AOP_LIT){
5344 switch(lit & 0xff) {
5346 /* and'ing with 0 has clears the result */
5347 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5348 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5351 /* and'ing with 0xff is a nop when the result and left are the same */
5356 int p = my_powof2( (~lit) & 0xff );
5358 /* only one bit is set in the literal, so use a bcf instruction */
5359 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5360 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5363 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5364 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5365 if(know_W != (lit&0xff))
5366 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5368 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5373 if (AOP_TYPE(left) == AOP_ACC) {
5374 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5376 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5377 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5384 // left & result in different registers
5385 if(AOP_TYPE(result) == AOP_CRY){
5387 // if(size), result in bit
5388 // if(!size && ifx), conditional oper: if(left & right)
5389 symbol *tlbl = newiTempLabel(NULL);
5390 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5392 pic14_emitcode("setb","c");
5394 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5395 pic14_emitcode("anl","a,%s",
5396 aopGet(AOP(left),offset,FALSE,FALSE));
5397 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5402 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5403 pic14_outBitC(result);
5405 jmpTrueOrFalse(ifx, tlbl);
5407 for(;(size--);offset++) {
5409 // result = left & right
5410 if(AOP_TYPE(right) == AOP_LIT){
5411 int t = (lit >> (offset*8)) & 0x0FFL;
5414 pic14_emitcode("clrf","%s",
5415 aopGet(AOP(result),offset,FALSE,FALSE));
5416 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5419 pic14_emitcode("movf","%s,w",
5420 aopGet(AOP(left),offset,FALSE,FALSE));
5421 pic14_emitcode("movwf","%s",
5422 aopGet(AOP(result),offset,FALSE,FALSE));
5423 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5424 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5427 pic14_emitcode("movlw","0x%x",t);
5428 pic14_emitcode("andwf","%s,w",
5429 aopGet(AOP(left),offset,FALSE,FALSE));
5430 pic14_emitcode("movwf","%s",
5431 aopGet(AOP(result),offset,FALSE,FALSE));
5433 emitpcode(POC_MOVLW, popGetLit(t));
5434 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5435 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5440 if (AOP_TYPE(left) == AOP_ACC) {
5441 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5442 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5444 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5445 pic14_emitcode("andwf","%s,w",
5446 aopGet(AOP(left),offset,FALSE,FALSE));
5447 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5448 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5450 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5451 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5457 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5458 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5459 freeAsmop(result,NULL,ic,TRUE);
5462 /*-----------------------------------------------------------------*/
5463 /* genOr - code for or */
5464 /*-----------------------------------------------------------------*/
5465 static void genOr (iCode *ic, iCode *ifx)
5467 operand *left, *right, *result;
5469 unsigned long lit = 0L;
5471 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5473 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5474 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5475 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5477 DEBUGpic14_AopType(__LINE__,left,right,result);
5479 /* if left is a literal & right is not then exchange them */
5480 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5481 AOP_NEEDSACC(left)) {
5482 operand *tmp = right ;
5487 /* if result = right then exchange them */
5488 if(pic14_sameRegs(AOP(result),AOP(right))){
5489 operand *tmp = right ;
5494 /* if right is bit then exchange them */
5495 if (AOP_TYPE(right) == AOP_CRY &&
5496 AOP_TYPE(left) != AOP_CRY){
5497 operand *tmp = right ;
5502 DEBUGpic14_AopType(__LINE__,left,right,result);
5504 if(AOP_TYPE(right) == AOP_LIT)
5505 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5507 size = AOP_SIZE(result);
5511 if (AOP_TYPE(left) == AOP_CRY){
5512 if(AOP_TYPE(right) == AOP_LIT){
5513 // c = bit & literal;
5515 // lit != 0 => result = 1
5516 if(AOP_TYPE(result) == AOP_CRY){
5518 emitpcode(POC_BSF, popGet(AOP(result),0));
5519 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5520 // AOP(result)->aopu.aop_dir,
5521 // AOP(result)->aopu.aop_dir);
5523 continueIfTrue(ifx);
5527 // lit == 0 => result = left
5528 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5530 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5533 if (AOP_TYPE(right) == AOP_CRY){
5534 if(pic14_sameRegs(AOP(result),AOP(left))){
5536 emitpcode(POC_BCF, popGet(AOP(result),0));
5537 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5538 emitpcode(POC_BSF, popGet(AOP(result),0));
5540 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5541 AOP(result)->aopu.aop_dir,
5542 AOP(result)->aopu.aop_dir);
5543 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5544 AOP(right)->aopu.aop_dir,
5545 AOP(right)->aopu.aop_dir);
5546 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5547 AOP(result)->aopu.aop_dir,
5548 AOP(result)->aopu.aop_dir);
5550 if( AOP_TYPE(result) == AOP_ACC) {
5551 emitpcode(POC_MOVLW, popGetLit(0));
5552 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5553 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5554 emitpcode(POC_MOVLW, popGetLit(1));
5558 emitpcode(POC_BCF, popGet(AOP(result),0));
5559 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5560 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5561 emitpcode(POC_BSF, popGet(AOP(result),0));
5563 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5564 AOP(result)->aopu.aop_dir,
5565 AOP(result)->aopu.aop_dir);
5566 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5567 AOP(right)->aopu.aop_dir,
5568 AOP(right)->aopu.aop_dir);
5569 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5570 AOP(left)->aopu.aop_dir,
5571 AOP(left)->aopu.aop_dir);
5572 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5573 AOP(result)->aopu.aop_dir,
5574 AOP(result)->aopu.aop_dir);
5579 symbol *tlbl = newiTempLabel(NULL);
5580 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5583 emitpcode(POC_BCF, popGet(AOP(result),0));
5584 if( AOP_TYPE(right) == AOP_ACC) {
5585 emitpcode(POC_IORLW, popGetLit(0));
5587 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5588 emitpcode(POC_BSF, popGet(AOP(result),0));
5593 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5594 pic14_emitcode(";XXX setb","c");
5595 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5596 AOP(left)->aopu.aop_dir,tlbl->key+100);
5597 pic14_toBoolean(right);
5598 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5599 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5600 jmpTrueOrFalse(ifx, tlbl);
5604 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5611 pic14_outBitC(result);
5613 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5614 genIfxJump(ifx, "c");
5618 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5619 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5620 if((AOP_TYPE(right) == AOP_LIT) &&
5621 (AOP_TYPE(result) == AOP_CRY) &&
5622 (AOP_TYPE(left) != AOP_CRY)){
5624 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5627 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5629 continueIfTrue(ifx);
5632 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5633 // lit = 0, result = boolean(left)
5635 pic14_emitcode(";XXX setb","c");
5636 pic14_toBoolean(right);
5638 symbol *tlbl = newiTempLabel(NULL);
5639 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5641 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5643 genIfxJump (ifx,"a");
5647 pic14_outBitC(result);
5651 /* if left is same as result */
5652 if(pic14_sameRegs(AOP(result),AOP(left))){
5654 for(;size--; offset++,lit>>=8) {
5655 if(AOP_TYPE(right) == AOP_LIT){
5656 if((lit & 0xff) == 0)
5657 /* or'ing with 0 has no effect */
5660 int p = my_powof2(lit & 0xff);
5662 /* only one bit is set in the literal, so use a bsf instruction */
5664 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5666 if(know_W != (lit & 0xff))
5667 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5668 know_W = lit & 0xff;
5669 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5674 if (AOP_TYPE(left) == AOP_ACC) {
5675 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5676 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5678 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5679 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5681 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5682 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5688 // left & result in different registers
5689 if(AOP_TYPE(result) == AOP_CRY){
5691 // if(size), result in bit
5692 // if(!size && ifx), conditional oper: if(left | right)
5693 symbol *tlbl = newiTempLabel(NULL);
5694 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5695 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5699 pic14_emitcode(";XXX setb","c");
5701 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5702 pic14_emitcode(";XXX orl","a,%s",
5703 aopGet(AOP(left),offset,FALSE,FALSE));
5704 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5710 pic14_outBitC(result);
5712 jmpTrueOrFalse(ifx, tlbl);
5713 } else for(;(size--);offset++){
5715 // result = left & right
5716 if(AOP_TYPE(right) == AOP_LIT){
5717 int t = (lit >> (offset*8)) & 0x0FFL;
5720 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5721 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5723 pic14_emitcode("movf","%s,w",
5724 aopGet(AOP(left),offset,FALSE,FALSE));
5725 pic14_emitcode("movwf","%s",
5726 aopGet(AOP(result),offset,FALSE,FALSE));
5729 emitpcode(POC_MOVLW, popGetLit(t));
5730 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5731 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5733 pic14_emitcode("movlw","0x%x",t);
5734 pic14_emitcode("iorwf","%s,w",
5735 aopGet(AOP(left),offset,FALSE,FALSE));
5736 pic14_emitcode("movwf","%s",
5737 aopGet(AOP(result),offset,FALSE,FALSE));
5743 // faster than result <- left, anl result,right
5744 // and better if result is SFR
5745 if (AOP_TYPE(left) == AOP_ACC) {
5746 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5747 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5749 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5750 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5752 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5753 pic14_emitcode("iorwf","%s,w",
5754 aopGet(AOP(left),offset,FALSE,FALSE));
5756 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5757 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5762 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5763 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5764 freeAsmop(result,NULL,ic,TRUE);
5767 /*-----------------------------------------------------------------*/
5768 /* genXor - code for xclusive or */
5769 /*-----------------------------------------------------------------*/
5770 static void genXor (iCode *ic, iCode *ifx)
5772 operand *left, *right, *result;
5774 unsigned long lit = 0L;
5776 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5778 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5779 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5780 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5782 /* if left is a literal & right is not ||
5783 if left needs acc & right does not */
5784 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5785 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5786 operand *tmp = right ;
5791 /* if result = right then exchange them */
5792 if(pic14_sameRegs(AOP(result),AOP(right))){
5793 operand *tmp = right ;
5798 /* if right is bit then exchange them */
5799 if (AOP_TYPE(right) == AOP_CRY &&
5800 AOP_TYPE(left) != AOP_CRY){
5801 operand *tmp = right ;
5805 if(AOP_TYPE(right) == AOP_LIT)
5806 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5808 size = AOP_SIZE(result);
5812 if (AOP_TYPE(left) == AOP_CRY){
5813 if(AOP_TYPE(right) == AOP_LIT){
5814 // c = bit & literal;
5816 // lit>>1 != 0 => result = 1
5817 if(AOP_TYPE(result) == AOP_CRY){
5819 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5820 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5822 continueIfTrue(ifx);
5825 pic14_emitcode("setb","c");
5829 // lit == 0, result = left
5830 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5832 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5834 // lit == 1, result = not(left)
5835 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5836 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5837 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5838 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5841 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5842 pic14_emitcode("cpl","c");
5849 symbol *tlbl = newiTempLabel(NULL);
5850 if (AOP_TYPE(right) == AOP_CRY){
5852 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5855 int sizer = AOP_SIZE(right);
5857 // if val>>1 != 0, result = 1
5858 pic14_emitcode("setb","c");
5860 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5862 // test the msb of the lsb
5863 pic14_emitcode("anl","a,#0xfe");
5864 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5868 pic14_emitcode("rrc","a");
5870 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5871 pic14_emitcode("cpl","c");
5872 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5877 pic14_outBitC(result);
5879 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5880 genIfxJump(ifx, "c");
5884 if(pic14_sameRegs(AOP(result),AOP(left))){
5885 /* if left is same as result */
5886 for(;size--; offset++) {
5887 if(AOP_TYPE(right) == AOP_LIT){
5888 int t = (lit >> (offset*8)) & 0x0FFL;
5892 if (IS_AOP_PREG(left)) {
5893 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5894 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5895 aopPut(AOP(result),"a",offset);
5897 emitpcode(POC_MOVLW, popGetLit(t));
5898 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5899 pic14_emitcode("xrl","%s,%s",
5900 aopGet(AOP(left),offset,FALSE,TRUE),
5901 aopGet(AOP(right),offset,FALSE,FALSE));
5904 if (AOP_TYPE(left) == AOP_ACC)
5905 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5907 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5908 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5910 if (IS_AOP_PREG(left)) {
5911 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5912 aopPut(AOP(result),"a",offset);
5914 pic14_emitcode("xrl","%s,a",
5915 aopGet(AOP(left),offset,FALSE,TRUE));
5921 // left & result in different registers
5922 if(AOP_TYPE(result) == AOP_CRY){
5924 // if(size), result in bit
5925 // if(!size && ifx), conditional oper: if(left ^ right)
5926 symbol *tlbl = newiTempLabel(NULL);
5927 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5929 pic14_emitcode("setb","c");
5931 if((AOP_TYPE(right) == AOP_LIT) &&
5932 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5933 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5935 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5936 pic14_emitcode("xrl","a,%s",
5937 aopGet(AOP(left),offset,FALSE,FALSE));
5939 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5944 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5945 pic14_outBitC(result);
5947 jmpTrueOrFalse(ifx, tlbl);
5948 } else for(;(size--);offset++){
5950 // result = left & right
5951 if(AOP_TYPE(right) == AOP_LIT){
5952 int t = (lit >> (offset*8)) & 0x0FFL;
5955 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5956 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5957 pic14_emitcode("movf","%s,w",
5958 aopGet(AOP(left),offset,FALSE,FALSE));
5959 pic14_emitcode("movwf","%s",
5960 aopGet(AOP(result),offset,FALSE,FALSE));
5963 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5964 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5965 pic14_emitcode("comf","%s,w",
5966 aopGet(AOP(left),offset,FALSE,FALSE));
5967 pic14_emitcode("movwf","%s",
5968 aopGet(AOP(result),offset,FALSE,FALSE));
5971 emitpcode(POC_MOVLW, popGetLit(t));
5972 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5973 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5974 pic14_emitcode("movlw","0x%x",t);
5975 pic14_emitcode("xorwf","%s,w",
5976 aopGet(AOP(left),offset,FALSE,FALSE));
5977 pic14_emitcode("movwf","%s",
5978 aopGet(AOP(result),offset,FALSE,FALSE));
5984 // faster than result <- left, anl result,right
5985 // and better if result is SFR
5986 if (AOP_TYPE(left) == AOP_ACC) {
5987 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5988 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5990 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5991 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5992 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5993 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5995 if ( AOP_TYPE(result) != AOP_ACC){
5996 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5997 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6003 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6004 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6005 freeAsmop(result,NULL,ic,TRUE);
6008 /*-----------------------------------------------------------------*/
6009 /* genInline - write the inline code out */
6010 /*-----------------------------------------------------------------*/
6011 static void genInline (iCode *ic)
6013 char *buffer, *bp, *bp1;
6015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6017 _G.inLine += (!options.asmpeep);
6019 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6020 strcpy(buffer,IC_INLINE(ic));
6022 /* emit each line as a code */
6026 pic14_emitcode(bp1,"");
6027 addpCode2pBlock(pb,newpCodeInlineP(bp1));
6034 pic14_emitcode(bp1,"");
6041 pic14_emitcode(bp1,"");
6042 addpCode2pBlock(pb,newpCodeInlineP(bp1));
6044 /* pic14_emitcode("",buffer); */
6045 _G.inLine -= (!options.asmpeep);
6048 /*-----------------------------------------------------------------*/
6049 /* genRRC - rotate right with carry */
6050 /*-----------------------------------------------------------------*/
6051 static void genRRC (iCode *ic)
6053 operand *left , *result ;
6054 int size, offset = 0, same;
6056 /* rotate right with carry */
6058 result=IC_RESULT(ic);
6059 aopOp (left,ic,FALSE);
6060 aopOp (result,ic,FALSE);
6062 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6064 same = pic14_sameRegs(AOP(result),AOP(left));
6066 size = AOP_SIZE(result);
6068 /* get the lsb and put it into the carry */
6069 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6076 emitpcode(POC_RRF, popGet(AOP(left),offset));
6078 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6079 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6085 freeAsmop(left,NULL,ic,TRUE);
6086 freeAsmop(result,NULL,ic,TRUE);
6089 /*-----------------------------------------------------------------*/
6090 /* genRLC - generate code for rotate left with carry */
6091 /*-----------------------------------------------------------------*/
6092 static void genRLC (iCode *ic)
6094 operand *left , *result ;
6095 int size, offset = 0;
6098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6099 /* rotate right with carry */
6101 result=IC_RESULT(ic);
6102 aopOp (left,ic,FALSE);
6103 aopOp (result,ic,FALSE);
6105 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6107 same = pic14_sameRegs(AOP(result),AOP(left));
6109 /* move it to the result */
6110 size = AOP_SIZE(result);
6112 /* get the msb and put it into the carry */
6113 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6120 emitpcode(POC_RLF, popGet(AOP(left),offset));
6122 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6123 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6130 freeAsmop(left,NULL,ic,TRUE);
6131 freeAsmop(result,NULL,ic,TRUE);
6134 /*-----------------------------------------------------------------*/
6135 /* genGetHbit - generates code get highest order bit */
6136 /*-----------------------------------------------------------------*/
6137 static void genGetHbit (iCode *ic)
6139 operand *left, *result;
6141 result=IC_RESULT(ic);
6142 aopOp (left,ic,FALSE);
6143 aopOp (result,ic,FALSE);
6145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6146 /* get the highest order byte into a */
6147 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6148 if(AOP_TYPE(result) == AOP_CRY){
6149 pic14_emitcode("rlc","a");
6150 pic14_outBitC(result);
6153 pic14_emitcode("rl","a");
6154 pic14_emitcode("anl","a,#0x01");
6155 pic14_outAcc(result);
6159 freeAsmop(left,NULL,ic,TRUE);
6160 freeAsmop(result,NULL,ic,TRUE);
6163 /*-----------------------------------------------------------------*/
6164 /* AccRol - rotate left accumulator by known count */
6165 /*-----------------------------------------------------------------*/
6166 static void AccRol (int shCount)
6168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6169 shCount &= 0x0007; // shCount : 0..7
6174 pic14_emitcode("rl","a");
6177 pic14_emitcode("rl","a");
6178 pic14_emitcode("rl","a");
6181 pic14_emitcode("swap","a");
6182 pic14_emitcode("rr","a");
6185 pic14_emitcode("swap","a");
6188 pic14_emitcode("swap","a");
6189 pic14_emitcode("rl","a");
6192 pic14_emitcode("rr","a");
6193 pic14_emitcode("rr","a");
6196 pic14_emitcode("rr","a");
6201 /*-----------------------------------------------------------------*/
6202 /* AccLsh - left shift accumulator by known count */
6203 /*-----------------------------------------------------------------*/
6204 static void AccLsh (int shCount)
6206 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6209 pic14_emitcode("add","a,acc");
6212 pic14_emitcode("add","a,acc");
6213 pic14_emitcode("add","a,acc");
6215 /* rotate left accumulator */
6217 /* and kill the lower order bits */
6218 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6223 /*-----------------------------------------------------------------*/
6224 /* AccRsh - right shift accumulator by known count */
6225 /*-----------------------------------------------------------------*/
6226 static void AccRsh (int shCount)
6228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6232 pic14_emitcode("rrc","a");
6234 /* rotate right accumulator */
6235 AccRol(8 - shCount);
6236 /* and kill the higher order bits */
6237 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6243 /*-----------------------------------------------------------------*/
6244 /* AccSRsh - signed right shift accumulator by known count */
6245 /*-----------------------------------------------------------------*/
6246 static void AccSRsh (int shCount)
6249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6252 pic14_emitcode("mov","c,acc.7");
6253 pic14_emitcode("rrc","a");
6254 } else if(shCount == 2){
6255 pic14_emitcode("mov","c,acc.7");
6256 pic14_emitcode("rrc","a");
6257 pic14_emitcode("mov","c,acc.7");
6258 pic14_emitcode("rrc","a");
6260 tlbl = newiTempLabel(NULL);
6261 /* rotate right accumulator */
6262 AccRol(8 - shCount);
6263 /* and kill the higher order bits */
6264 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6265 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6266 pic14_emitcode("orl","a,#0x%02x",
6267 (unsigned char)~SRMask[shCount]);
6268 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6273 /*-----------------------------------------------------------------*/
6274 /* shiftR1Left2Result - shift right one byte from left to result */
6275 /*-----------------------------------------------------------------*/
6276 static void shiftR1Left2ResultSigned (operand *left, int offl,
6277 operand *result, int offr,
6282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6284 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6288 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6290 emitpcode(POC_RRF, popGet(AOP(result),offr));
6292 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6293 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6299 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6301 emitpcode(POC_RRF, popGet(AOP(result),offr));
6303 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6304 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6306 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6307 emitpcode(POC_RRF, popGet(AOP(result),offr));
6313 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6315 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6316 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6319 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6320 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6321 emitpcode(POC_ANDLW, popGetLit(0x1f));
6323 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6324 emitpcode(POC_IORLW, popGetLit(0xe0));
6326 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6330 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6331 emitpcode(POC_ANDLW, popGetLit(0x0f));
6332 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6333 emitpcode(POC_IORLW, popGetLit(0xf0));
6334 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6338 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6340 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6341 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6343 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6344 emitpcode(POC_ANDLW, popGetLit(0x07));
6345 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6346 emitpcode(POC_IORLW, popGetLit(0xf8));
6347 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6352 emitpcode(POC_MOVLW, popGetLit(0x00));
6353 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6354 emitpcode(POC_MOVLW, popGetLit(0xfe));
6355 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6356 emitpcode(POC_IORLW, popGetLit(0x01));
6357 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6359 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6360 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6361 emitpcode(POC_DECF, popGet(AOP(result),offr));
6362 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6363 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6369 emitpcode(POC_MOVLW, popGetLit(0x00));
6370 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6371 emitpcode(POC_MOVLW, popGetLit(0xff));
6372 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6374 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6375 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6376 emitpcode(POC_DECF, popGet(AOP(result),offr));
6384 /*-----------------------------------------------------------------*/
6385 /* shiftR1Left2Result - shift right one byte from left to result */
6386 /*-----------------------------------------------------------------*/
6387 static void shiftR1Left2Result (operand *left, int offl,
6388 operand *result, int offr,
6389 int shCount, int sign)
6393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6395 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6397 /* Copy the msb into the carry if signed. */
6399 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6409 emitpcode(POC_RRF, popGet(AOP(result),offr));
6411 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6412 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6418 emitpcode(POC_RRF, popGet(AOP(result),offr));
6420 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6421 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6424 emitpcode(POC_RRF, popGet(AOP(result),offr));
6429 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6431 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6432 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6435 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6436 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6437 emitpcode(POC_ANDLW, popGetLit(0x1f));
6438 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6442 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6443 emitpcode(POC_ANDLW, popGetLit(0x0f));
6444 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6448 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6449 emitpcode(POC_ANDLW, popGetLit(0x0f));
6450 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6452 emitpcode(POC_RRF, popGet(AOP(result),offr));
6457 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6458 emitpcode(POC_ANDLW, popGetLit(0x80));
6459 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6460 emitpcode(POC_RLF, popGet(AOP(result),offr));
6461 emitpcode(POC_RLF, popGet(AOP(result),offr));
6466 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6467 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6468 emitpcode(POC_RLF, popGet(AOP(result),offr));
6477 /*-----------------------------------------------------------------*/
6478 /* shiftL1Left2Result - shift left one byte from left to result */
6479 /*-----------------------------------------------------------------*/
6480 static void shiftL1Left2Result (operand *left, int offl,
6481 operand *result, int offr, int shCount)
6486 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6488 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6489 DEBUGpic14_emitcode ("; ***","same = %d",same);
6490 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6492 /* shift left accumulator */
6493 //AccLsh(shCount); // don't comment out just yet...
6494 // aopPut(AOP(result),"a",offr);
6498 /* Shift left 1 bit position */
6499 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6501 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6503 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6504 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6508 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6509 emitpcode(POC_ANDLW,popGetLit(0x7e));
6510 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6511 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6514 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6515 emitpcode(POC_ANDLW,popGetLit(0x3e));
6516 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6517 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6518 emitpcode(POC_RLF, popGet(AOP(result),offr));
6521 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6522 emitpcode(POC_ANDLW, popGetLit(0xf0));
6523 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6526 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6527 emitpcode(POC_ANDLW, popGetLit(0xf0));
6528 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6529 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6532 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6533 emitpcode(POC_ANDLW, popGetLit(0x30));
6534 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6535 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6536 emitpcode(POC_RLF, popGet(AOP(result),offr));
6539 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6540 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6541 emitpcode(POC_RRF, popGet(AOP(result),offr));
6545 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6550 /*-----------------------------------------------------------------*/
6551 /* movLeft2Result - move byte from left to result */
6552 /*-----------------------------------------------------------------*/
6553 static void movLeft2Result (operand *left, int offl,
6554 operand *result, int offr)
6557 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6558 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6559 l = aopGet(AOP(left),offl,FALSE,FALSE);
6561 if (*l == '@' && (IS_AOP_PREG(result))) {
6562 pic14_emitcode("mov","a,%s",l);
6563 aopPut(AOP(result),"a",offr);
6565 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6566 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6571 /*-----------------------------------------------------------------*/
6572 /* shiftL2Left2Result - shift left two bytes from left to result */
6573 /*-----------------------------------------------------------------*/
6574 static void shiftL2Left2Result (operand *left, int offl,
6575 operand *result, int offr, int shCount)
6579 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6581 if(pic14_sameRegs(AOP(result), AOP(left))) {
6589 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6590 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6591 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6595 emitpcode(POC_RLF, popGet(AOP(result),offr));
6596 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6602 emitpcode(POC_MOVLW, popGetLit(0x0f));
6603 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6604 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6605 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6606 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6607 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6608 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6610 emitpcode(POC_RLF, popGet(AOP(result),offr));
6611 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6615 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6616 emitpcode(POC_RRF, popGet(AOP(result),offr));
6617 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_RRF, popGet(AOP(result),offr));
6619 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6620 emitpcode(POC_ANDLW,popGetLit(0xc0));
6621 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6622 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6623 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6624 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6627 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6628 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6629 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6630 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6631 emitpcode(POC_RRF, popGet(AOP(result),offr));
6641 /* note, use a mov/add for the shift since the mov has a
6642 chance of getting optimized out */
6643 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6644 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6645 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6646 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6647 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6651 emitpcode(POC_RLF, popGet(AOP(result),offr));
6652 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6659 emitpcode(POC_ANDLW, popGetLit(0xF0));
6660 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6661 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6662 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6663 emitpcode(POC_ANDLW, popGetLit(0xF0));
6664 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6665 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6669 emitpcode(POC_RLF, popGet(AOP(result),offr));
6670 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6675 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6676 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6677 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6679 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_RRF, popGet(AOP(result),offr));
6681 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_ANDLW,popGetLit(0xc0));
6683 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6684 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6685 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6686 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6689 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6690 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6691 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6693 emitpcode(POC_RRF, popGet(AOP(result),offr));
6698 /*-----------------------------------------------------------------*/
6699 /* shiftR2Left2Result - shift right two bytes from left to result */
6700 /*-----------------------------------------------------------------*/
6701 static void shiftR2Left2Result (operand *left, int offl,
6702 operand *result, int offr,
6703 int shCount, int sign)
6707 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6708 same = pic14_sameRegs(AOP(result), AOP(left));
6710 if(same && ((offl + MSB16) == offr)){
6712 /* don't crash result[offr] */
6713 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6714 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6716 movLeft2Result(left,offl, result, offr);
6717 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6719 /* a:x >> shCount (x = lsb(result))*/
6722 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6724 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6733 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6738 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RRF,popGet(AOP(result),offr));
6741 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6742 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6744 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6749 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6752 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6753 emitpcode(POC_RRF,popGet(AOP(result),offr));
6760 emitpcode(POC_MOVLW, popGetLit(0xf0));
6761 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6762 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6764 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6765 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6766 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6767 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6769 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6770 emitpcode(POC_ANDLW, popGetLit(0x0f));
6771 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6773 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6774 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_ANDLW, popGetLit(0xf0));
6776 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6777 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6781 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6782 emitpcode(POC_RRF, popGet(AOP(result),offr));
6786 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6787 emitpcode(POC_BTFSC,
6788 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6789 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6797 emitpcode(POC_RLF, popGet(AOP(result),offr));
6798 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_RLF, popGet(AOP(result),offr));
6801 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6803 emitpcode(POC_ANDLW,popGetLit(0x03));
6805 emitpcode(POC_BTFSC,
6806 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6807 emitpcode(POC_IORLW,popGetLit(0xfc));
6809 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6810 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6811 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6812 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6814 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6815 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6817 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6818 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6819 emitpcode(POC_ANDLW,popGetLit(0x03));
6821 emitpcode(POC_BTFSC,
6822 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6823 emitpcode(POC_IORLW,popGetLit(0xfc));
6825 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6826 emitpcode(POC_RLF, popGet(AOP(result),offr));
6833 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6834 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6835 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6836 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6841 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6846 /*-----------------------------------------------------------------*/
6847 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6848 /*-----------------------------------------------------------------*/
6849 static void shiftLLeftOrResult (operand *left, int offl,
6850 operand *result, int offr, int shCount)
6852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6853 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6854 /* shift left accumulator */
6856 /* or with result */
6857 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6858 /* back to result */
6859 aopPut(AOP(result),"a",offr);
6862 /*-----------------------------------------------------------------*/
6863 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6864 /*-----------------------------------------------------------------*/
6865 static void shiftRLeftOrResult (operand *left, int offl,
6866 operand *result, int offr, int shCount)
6868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6869 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6870 /* shift right accumulator */
6872 /* or with result */
6873 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6874 /* back to result */
6875 aopPut(AOP(result),"a",offr);
6878 /*-----------------------------------------------------------------*/
6879 /* genlshOne - left shift a one byte quantity by known count */
6880 /*-----------------------------------------------------------------*/
6881 static void genlshOne (operand *result, operand *left, int shCount)
6883 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6884 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6887 /*-----------------------------------------------------------------*/
6888 /* genlshTwo - left shift two bytes by known amount != 0 */
6889 /*-----------------------------------------------------------------*/
6890 static void genlshTwo (operand *result,operand *left, int shCount)
6894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6895 size = pic14_getDataSize(result);
6897 /* if shCount >= 8 */
6903 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6905 movLeft2Result(left, LSB, result, MSB16);
6907 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6910 /* 1 <= shCount <= 7 */
6913 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6915 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6919 /*-----------------------------------------------------------------*/
6920 /* shiftLLong - shift left one long from left to result */
6921 /* offl = LSB or MSB16 */
6922 /*-----------------------------------------------------------------*/
6923 static void shiftLLong (operand *left, operand *result, int offr )
6926 int size = AOP_SIZE(result);
6928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6929 if(size >= LSB+offr){
6930 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6932 pic14_emitcode("add","a,acc");
6933 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6934 size >= MSB16+offr && offr != LSB )
6935 pic14_emitcode("xch","a,%s",
6936 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6938 aopPut(AOP(result),"a",LSB+offr);
6941 if(size >= MSB16+offr){
6942 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6943 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6946 pic14_emitcode("rlc","a");
6947 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6948 size >= MSB24+offr && offr != LSB)
6949 pic14_emitcode("xch","a,%s",
6950 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6952 aopPut(AOP(result),"a",MSB16+offr);
6955 if(size >= MSB24+offr){
6956 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6957 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6960 pic14_emitcode("rlc","a");
6961 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6962 size >= MSB32+offr && offr != LSB )
6963 pic14_emitcode("xch","a,%s",
6964 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6966 aopPut(AOP(result),"a",MSB24+offr);
6969 if(size > MSB32+offr){
6970 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6971 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6974 pic14_emitcode("rlc","a");
6975 aopPut(AOP(result),"a",MSB32+offr);
6978 aopPut(AOP(result),zero,LSB);
6981 /*-----------------------------------------------------------------*/
6982 /* genlshFour - shift four byte by a known amount != 0 */
6983 /*-----------------------------------------------------------------*/
6984 static void genlshFour (operand *result, operand *left, int shCount)
6988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6989 size = AOP_SIZE(result);
6991 /* if shifting more that 3 bytes */
6992 if (shCount >= 24 ) {
6995 /* lowest order of left goes to the highest
6996 order of the destination */
6997 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6999 movLeft2Result(left, LSB, result, MSB32);
7000 aopPut(AOP(result),zero,LSB);
7001 aopPut(AOP(result),zero,MSB16);
7002 aopPut(AOP(result),zero,MSB32);
7006 /* more than two bytes */
7007 else if ( shCount >= 16 ) {
7008 /* lower order two bytes goes to higher order two bytes */
7010 /* if some more remaining */
7012 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7014 movLeft2Result(left, MSB16, result, MSB32);
7015 movLeft2Result(left, LSB, result, MSB24);
7017 aopPut(AOP(result),zero,MSB16);
7018 aopPut(AOP(result),zero,LSB);
7022 /* if more than 1 byte */
7023 else if ( shCount >= 8 ) {
7024 /* lower order three bytes goes to higher order three bytes */
7028 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7030 movLeft2Result(left, LSB, result, MSB16);
7032 else{ /* size = 4 */
7034 movLeft2Result(left, MSB24, result, MSB32);
7035 movLeft2Result(left, MSB16, result, MSB24);
7036 movLeft2Result(left, LSB, result, MSB16);
7037 aopPut(AOP(result),zero,LSB);
7039 else if(shCount == 1)
7040 shiftLLong(left, result, MSB16);
7042 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7043 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7044 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7045 aopPut(AOP(result),zero,LSB);
7050 /* 1 <= shCount <= 7 */
7051 else if(shCount <= 2){
7052 shiftLLong(left, result, LSB);
7054 shiftLLong(result, result, LSB);
7056 /* 3 <= shCount <= 7, optimize */
7058 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7059 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7060 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7064 /*-----------------------------------------------------------------*/
7065 /* genLeftShiftLiteral - left shifting by known count */
7066 /*-----------------------------------------------------------------*/
7067 static void genLeftShiftLiteral (operand *left,
7072 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7075 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7076 freeAsmop(right,NULL,ic,TRUE);
7078 aopOp(left,ic,FALSE);
7079 aopOp(result,ic,FALSE);
7081 size = getSize(operandType(result));
7084 pic14_emitcode("; shift left ","result %d, left %d",size,
7088 /* I suppose that the left size >= result size */
7091 movLeft2Result(left, size, result, size);
7095 else if(shCount >= (size * 8))
7097 aopPut(AOP(result),zero,size);
7101 genlshOne (result,left,shCount);
7106 genlshTwo (result,left,shCount);
7110 genlshFour (result,left,shCount);
7114 freeAsmop(left,NULL,ic,TRUE);
7115 freeAsmop(result,NULL,ic,TRUE);
7118 /*-----------------------------------------------------------------*
7119 * genMultiAsm - repeat assembly instruction for size of register.
7120 * if endian == 1, then the high byte (i.e base address + size of
7121 * register) is used first else the low byte is used first;
7122 *-----------------------------------------------------------------*/
7123 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7128 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7141 emitpcode(poc, popGet(AOP(reg),offset));
7146 /*-----------------------------------------------------------------*/
7147 /* genLeftShift - generates code for left shifting */
7148 /*-----------------------------------------------------------------*/
7149 static void genLeftShift (iCode *ic)
7151 operand *left,*right, *result;
7154 symbol *tlbl , *tlbl1;
7157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7159 right = IC_RIGHT(ic);
7161 result = IC_RESULT(ic);
7163 aopOp(right,ic,FALSE);
7165 /* if the shift count is known then do it
7166 as efficiently as possible */
7167 if (AOP_TYPE(right) == AOP_LIT) {
7168 genLeftShiftLiteral (left,right,result,ic);
7172 /* shift count is unknown then we have to form
7173 a loop get the loop count in B : Note: we take
7174 only the lower order byte since shifting
7175 more that 32 bits make no sense anyway, ( the
7176 largest size of an object can be only 32 bits ) */
7179 aopOp(left,ic,FALSE);
7180 aopOp(result,ic,FALSE);
7182 /* now move the left to the result if they are not the
7184 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7185 AOP_SIZE(result) > 1) {
7187 size = AOP_SIZE(result);
7190 l = aopGet(AOP(left),offset,FALSE,TRUE);
7191 if (*l == '@' && (IS_AOP_PREG(result))) {
7193 pic14_emitcode("mov","a,%s",l);
7194 aopPut(AOP(result),"a",offset);
7196 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7197 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7198 //aopPut(AOP(result),l,offset);
7204 size = AOP_SIZE(result);
7206 /* if it is only one byte then */
7208 if(optimized_for_speed) {
7209 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7210 emitpcode(POC_ANDLW, popGetLit(0xf0));
7211 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7212 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7213 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7214 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7215 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7216 emitpcode(POC_RLFW, popGet(AOP(result),0));
7217 emitpcode(POC_ANDLW, popGetLit(0xfe));
7218 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7219 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7220 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7223 tlbl = newiTempLabel(NULL);
7224 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7225 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7226 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7229 emitpcode(POC_COMFW, popGet(AOP(right),0));
7230 emitpcode(POC_RRF, popGet(AOP(result),0));
7231 emitpLabel(tlbl->key);
7232 emitpcode(POC_RLF, popGet(AOP(result),0));
7233 emitpcode(POC_ADDLW, popGetLit(1));
7235 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7240 if (pic14_sameRegs(AOP(left),AOP(result))) {
7242 tlbl = newiTempLabel(NULL);
7243 emitpcode(POC_COMFW, popGet(AOP(right),0));
7244 genMultiAsm(POC_RRF, result, size,1);
7245 emitpLabel(tlbl->key);
7246 genMultiAsm(POC_RLF, result, size,0);
7247 emitpcode(POC_ADDLW, popGetLit(1));
7249 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7253 //tlbl = newiTempLabel(NULL);
7255 //tlbl1 = newiTempLabel(NULL);
7257 //reAdjustPreg(AOP(result));
7259 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7260 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7261 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7263 //pic14_emitcode("add","a,acc");
7264 //aopPut(AOP(result),"a",offset++);
7266 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7268 // pic14_emitcode("rlc","a");
7269 // aopPut(AOP(result),"a",offset++);
7271 //reAdjustPreg(AOP(result));
7273 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7274 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7277 tlbl = newiTempLabel(NULL);
7278 tlbl1= newiTempLabel(NULL);
7280 size = AOP_SIZE(result);
7283 pctemp = popGetTempReg(); /* grab a temporary working register. */
7285 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7287 /* offset should be 0, 1 or 3 */
7288 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7290 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7292 emitpcode(POC_MOVWF, pctemp);
7295 emitpLabel(tlbl->key);
7298 emitpcode(POC_RLF, popGet(AOP(result),0));
7300 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7302 emitpcode(POC_DECFSZ, pctemp);
7303 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7304 emitpLabel(tlbl1->key);
7306 popReleaseTempReg(pctemp);
7310 freeAsmop (right,NULL,ic,TRUE);
7311 freeAsmop(left,NULL,ic,TRUE);
7312 freeAsmop(result,NULL,ic,TRUE);
7315 /*-----------------------------------------------------------------*/
7316 /* genrshOne - right shift a one byte quantity by known count */
7317 /*-----------------------------------------------------------------*/
7318 static void genrshOne (operand *result, operand *left,
7319 int shCount, int sign)
7321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7322 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7325 /*-----------------------------------------------------------------*/
7326 /* genrshTwo - right shift two bytes by known amount != 0 */
7327 /*-----------------------------------------------------------------*/
7328 static void genrshTwo (operand *result,operand *left,
7329 int shCount, int sign)
7331 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7332 /* if shCount >= 8 */
7336 shiftR1Left2Result(left, MSB16, result, LSB,
7339 movLeft2Result(left, MSB16, result, LSB);
7341 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7344 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7345 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7349 /* 1 <= shCount <= 7 */
7351 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7354 /*-----------------------------------------------------------------*/
7355 /* shiftRLong - shift right one long from left to result */
7356 /* offl = LSB or MSB16 */
7357 /*-----------------------------------------------------------------*/
7358 static void shiftRLong (operand *left, int offl,
7359 operand *result, int sign)
7361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7363 pic14_emitcode("clr","c");
7364 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7366 pic14_emitcode("mov","c,acc.7");
7367 pic14_emitcode("rrc","a");
7368 aopPut(AOP(result),"a",MSB32-offl);
7370 /* add sign of "a" */
7371 addSign(result, MSB32, sign);
7373 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7374 pic14_emitcode("rrc","a");
7375 aopPut(AOP(result),"a",MSB24-offl);
7377 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7378 pic14_emitcode("rrc","a");
7379 aopPut(AOP(result),"a",MSB16-offl);
7382 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7383 pic14_emitcode("rrc","a");
7384 aopPut(AOP(result),"a",LSB);
7388 /*-----------------------------------------------------------------*/
7389 /* genrshFour - shift four byte by a known amount != 0 */
7390 /*-----------------------------------------------------------------*/
7391 static void genrshFour (operand *result, operand *left,
7392 int shCount, int sign)
7394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7395 /* if shifting more that 3 bytes */
7396 if(shCount >= 24 ) {
7399 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7401 movLeft2Result(left, MSB32, result, LSB);
7403 addSign(result, MSB16, sign);
7405 else if(shCount >= 16){
7408 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7410 movLeft2Result(left, MSB24, result, LSB);
7411 movLeft2Result(left, MSB32, result, MSB16);
7413 addSign(result, MSB24, sign);
7415 else if(shCount >= 8){
7418 shiftRLong(left, MSB16, result, sign);
7419 else if(shCount == 0){
7420 movLeft2Result(left, MSB16, result, LSB);
7421 movLeft2Result(left, MSB24, result, MSB16);
7422 movLeft2Result(left, MSB32, result, MSB24);
7423 addSign(result, MSB32, sign);
7426 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7427 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7428 /* the last shift is signed */
7429 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7430 addSign(result, MSB32, sign);
7433 else{ /* 1 <= shCount <= 7 */
7435 shiftRLong(left, LSB, result, sign);
7437 shiftRLong(result, LSB, result, sign);
7440 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7441 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7442 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7447 /*-----------------------------------------------------------------*/
7448 /* genRightShiftLiteral - right shifting by known count */
7449 /*-----------------------------------------------------------------*/
7450 static void genRightShiftLiteral (operand *left,
7456 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7460 freeAsmop(right,NULL,ic,TRUE);
7462 aopOp(left,ic,FALSE);
7463 aopOp(result,ic,FALSE);
7466 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7470 lsize = pic14_getDataSize(left);
7471 res_size = pic14_getDataSize(result);
7472 /* test the LEFT size !!! */
7474 /* I suppose that the left size >= result size */
7477 movLeft2Result(left, lsize, result, res_size);
7480 else if(shCount >= (lsize * 8)){
7483 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7485 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7486 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7491 emitpcode(POC_MOVLW, popGetLit(0));
7492 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7493 emitpcode(POC_MOVLW, popGetLit(0xff));
7495 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7500 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7507 genrshOne (result,left,shCount,sign);
7511 genrshTwo (result,left,shCount,sign);
7515 genrshFour (result,left,shCount,sign);
7523 freeAsmop(left,NULL,ic,TRUE);
7524 freeAsmop(result,NULL,ic,TRUE);
7527 /*-----------------------------------------------------------------*/
7528 /* genSignedRightShift - right shift of signed number */
7529 /*-----------------------------------------------------------------*/
7530 static void genSignedRightShift (iCode *ic)
7532 operand *right, *left, *result;
7535 symbol *tlbl, *tlbl1 ;
7538 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7540 /* we do it the hard way put the shift count in b
7541 and loop thru preserving the sign */
7542 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7544 right = IC_RIGHT(ic);
7546 result = IC_RESULT(ic);
7548 aopOp(right,ic,FALSE);
7549 aopOp(left,ic,FALSE);
7550 aopOp(result,ic,FALSE);
7553 if ( AOP_TYPE(right) == AOP_LIT) {
7554 genRightShiftLiteral (left,right,result,ic,1);
7557 /* shift count is unknown then we have to form
7558 a loop get the loop count in B : Note: we take
7559 only the lower order byte since shifting
7560 more that 32 bits make no sense anyway, ( the
7561 largest size of an object can be only 32 bits ) */
7563 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7564 //pic14_emitcode("inc","b");
7565 //freeAsmop (right,NULL,ic,TRUE);
7566 //aopOp(left,ic,FALSE);
7567 //aopOp(result,ic,FALSE);
7569 /* now move the left to the result if they are not the
7571 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7572 AOP_SIZE(result) > 1) {
7574 size = AOP_SIZE(result);
7578 l = aopGet(AOP(left),offset,FALSE,TRUE);
7579 if (*l == '@' && IS_AOP_PREG(result)) {
7581 pic14_emitcode("mov","a,%s",l);
7582 aopPut(AOP(result),"a",offset);
7584 aopPut(AOP(result),l,offset);
7586 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7587 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7593 /* mov the highest order bit to OVR */
7594 tlbl = newiTempLabel(NULL);
7595 tlbl1= newiTempLabel(NULL);
7597 size = AOP_SIZE(result);
7600 pctemp = popGetTempReg(); /* grab a temporary working register. */
7602 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7604 /* offset should be 0, 1 or 3 */
7605 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7607 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7609 emitpcode(POC_MOVWF, pctemp);
7612 emitpLabel(tlbl->key);
7614 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7615 emitpcode(POC_RRF, popGet(AOP(result),offset));
7618 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7621 emitpcode(POC_DECFSZ, pctemp);
7622 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7623 emitpLabel(tlbl1->key);
7625 popReleaseTempReg(pctemp);
7627 size = AOP_SIZE(result);
7629 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7630 pic14_emitcode("rlc","a");
7631 pic14_emitcode("mov","ov,c");
7632 /* if it is only one byte then */
7634 l = aopGet(AOP(left),0,FALSE,FALSE);
7636 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7637 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7638 pic14_emitcode("mov","c,ov");
7639 pic14_emitcode("rrc","a");
7640 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7641 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7642 aopPut(AOP(result),"a",0);
7646 reAdjustPreg(AOP(result));
7647 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7648 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7649 pic14_emitcode("mov","c,ov");
7651 l = aopGet(AOP(result),offset,FALSE,FALSE);
7653 pic14_emitcode("rrc","a");
7654 aopPut(AOP(result),"a",offset--);
7656 reAdjustPreg(AOP(result));
7657 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7658 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7663 freeAsmop(left,NULL,ic,TRUE);
7664 freeAsmop(result,NULL,ic,TRUE);
7665 freeAsmop(right,NULL,ic,TRUE);
7668 /*-----------------------------------------------------------------*/
7669 /* genRightShift - generate code for right shifting */
7670 /*-----------------------------------------------------------------*/
7671 static void genRightShift (iCode *ic)
7673 operand *right, *left, *result;
7677 symbol *tlbl, *tlbl1 ;
7679 /* if signed then we do it the hard way preserve the
7680 sign bit moving it inwards */
7681 retype = getSpec(operandType(IC_RESULT(ic)));
7682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7684 if (!SPEC_USIGN(retype)) {
7685 genSignedRightShift (ic);
7689 /* signed & unsigned types are treated the same : i.e. the
7690 signed is NOT propagated inwards : quoting from the
7691 ANSI - standard : "for E1 >> E2, is equivalent to division
7692 by 2**E2 if unsigned or if it has a non-negative value,
7693 otherwise the result is implementation defined ", MY definition
7694 is that the sign does not get propagated */
7696 right = IC_RIGHT(ic);
7698 result = IC_RESULT(ic);
7700 aopOp(right,ic,FALSE);
7702 /* if the shift count is known then do it
7703 as efficiently as possible */
7704 if (AOP_TYPE(right) == AOP_LIT) {
7705 genRightShiftLiteral (left,right,result,ic, 0);
7709 /* shift count is unknown then we have to form
7710 a loop get the loop count in B : Note: we take
7711 only the lower order byte since shifting
7712 more that 32 bits make no sense anyway, ( the
7713 largest size of an object can be only 32 bits ) */
7715 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7716 pic14_emitcode("inc","b");
7717 aopOp(left,ic,FALSE);
7718 aopOp(result,ic,FALSE);
7720 /* now move the left to the result if they are not the
7722 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7723 AOP_SIZE(result) > 1) {
7725 size = AOP_SIZE(result);
7728 l = aopGet(AOP(left),offset,FALSE,TRUE);
7729 if (*l == '@' && IS_AOP_PREG(result)) {
7731 pic14_emitcode("mov","a,%s",l);
7732 aopPut(AOP(result),"a",offset);
7734 aopPut(AOP(result),l,offset);
7739 tlbl = newiTempLabel(NULL);
7740 tlbl1= newiTempLabel(NULL);
7741 size = AOP_SIZE(result);
7744 /* if it is only one byte then */
7747 tlbl = newiTempLabel(NULL);
7748 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7749 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7750 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7753 emitpcode(POC_COMFW, popGet(AOP(right),0));
7754 emitpcode(POC_RLF, popGet(AOP(result),0));
7755 emitpLabel(tlbl->key);
7756 emitpcode(POC_RRF, popGet(AOP(result),0));
7757 emitpcode(POC_ADDLW, popGetLit(1));
7759 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7764 reAdjustPreg(AOP(result));
7765 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7766 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7769 l = aopGet(AOP(result),offset,FALSE,FALSE);
7771 pic14_emitcode("rrc","a");
7772 aopPut(AOP(result),"a",offset--);
7774 reAdjustPreg(AOP(result));
7776 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7777 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7780 freeAsmop(left,NULL,ic,TRUE);
7781 freeAsmop (right,NULL,ic,TRUE);
7782 freeAsmop(result,NULL,ic,TRUE);
7785 /*-----------------------------------------------------------------*/
7786 /* genUnpackBits - generates code for unpacking bits */
7787 /*-----------------------------------------------------------------*/
7788 static void genUnpackBits (operand *result, char *rname, int ptype)
7795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7796 etype = getSpec(operandType(result));
7798 /* read the first byte */
7803 pic14_emitcode("mov","a,@%s",rname);
7807 pic14_emitcode("movx","a,@%s",rname);
7811 pic14_emitcode("movx","a,@dptr");
7815 pic14_emitcode("clr","a");
7816 pic14_emitcode("movc","a","@a+dptr");
7820 pic14_emitcode("lcall","__gptrget");
7824 /* if we have bitdisplacement then it fits */
7825 /* into this byte completely or if length is */
7826 /* less than a byte */
7827 if ((shCnt = SPEC_BSTR(etype)) ||
7828 (SPEC_BLEN(etype) <= 8)) {
7830 /* shift right acc */
7833 pic14_emitcode("anl","a,#0x%02x",
7834 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7835 aopPut(AOP(result),"a",offset);
7839 /* bit field did not fit in a byte */
7840 rlen = SPEC_BLEN(etype) - 8;
7841 aopPut(AOP(result),"a",offset++);
7848 pic14_emitcode("inc","%s",rname);
7849 pic14_emitcode("mov","a,@%s",rname);
7853 pic14_emitcode("inc","%s",rname);
7854 pic14_emitcode("movx","a,@%s",rname);
7858 pic14_emitcode("inc","dptr");
7859 pic14_emitcode("movx","a,@dptr");
7863 pic14_emitcode("clr","a");
7864 pic14_emitcode("inc","dptr");
7865 pic14_emitcode("movc","a","@a+dptr");
7869 pic14_emitcode("inc","dptr");
7870 pic14_emitcode("lcall","__gptrget");
7875 /* if we are done */
7879 aopPut(AOP(result),"a",offset++);
7884 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7885 aopPut(AOP(result),"a",offset);
7892 /*-----------------------------------------------------------------*/
7893 /* genDataPointerGet - generates code when ptr offset is known */
7894 /*-----------------------------------------------------------------*/
7895 static void genDataPointerGet (operand *left,
7899 int size , offset = 0;
7902 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7905 /* optimization - most of the time, left and result are the same
7906 * address, but different types. for the pic code, we could omit
7910 aopOp(result,ic,TRUE);
7912 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7914 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7916 size = AOP_SIZE(result);
7919 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7923 freeAsmop(left,NULL,ic,TRUE);
7924 freeAsmop(result,NULL,ic,TRUE);
7927 /*-----------------------------------------------------------------*/
7928 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7929 /*-----------------------------------------------------------------*/
7930 static void genNearPointerGet (operand *left,
7935 //regs *preg = NULL ;
7937 sym_link *rtype, *retype;
7938 sym_link *ltype = operandType(left);
7941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7943 rtype = operandType(result);
7944 retype= getSpec(rtype);
7946 aopOp(left,ic,FALSE);
7948 /* if left is rematerialisable and
7949 result is not bit variable type and
7950 the left is pointer to data space i.e
7951 lower 128 bytes of space */
7952 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7953 !IS_BITVAR(retype) &&
7954 DCL_TYPE(ltype) == POINTER) {
7955 //genDataPointerGet (left,result,ic);
7959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7961 /* if the value is already in a pointer register
7962 then don't need anything more */
7963 if (!AOP_INPREG(AOP(left))) {
7964 /* otherwise get a free pointer register */
7965 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7968 preg = getFreePtr(ic,&aop,FALSE);
7969 pic14_emitcode("mov","%s,%s",
7971 aopGet(AOP(left),0,FALSE,TRUE));
7972 rname = preg->name ;
7976 rname = aopGet(AOP(left),0,FALSE,FALSE);
7978 aopOp (result,ic,FALSE);
7980 /* if bitfield then unpack the bits */
7981 if (IS_BITVAR(retype))
7982 genUnpackBits (result,rname,POINTER);
7984 /* we have can just get the values */
7985 int size = AOP_SIZE(result);
7988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7990 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7991 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7993 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7994 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7996 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8000 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8002 pic14_emitcode("mov","a,@%s",rname);
8003 aopPut(AOP(result),"a",offset);
8005 sprintf(buffer,"@%s",rname);
8006 aopPut(AOP(result),buffer,offset);
8010 pic14_emitcode("inc","%s",rname);
8015 /* now some housekeeping stuff */
8017 /* we had to allocate for this iCode */
8018 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 freeAsmop(NULL,aop,ic,TRUE);
8021 /* we did not allocate which means left
8022 already in a pointer register, then
8023 if size > 0 && this could be used again
8024 we have to point it back to where it
8026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8027 if (AOP_SIZE(result) > 1 &&
8028 !OP_SYMBOL(left)->remat &&
8029 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8031 int size = AOP_SIZE(result) - 1;
8033 pic14_emitcode("dec","%s",rname);
8038 freeAsmop(left,NULL,ic,TRUE);
8039 freeAsmop(result,NULL,ic,TRUE);
8043 /*-----------------------------------------------------------------*/
8044 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8045 /*-----------------------------------------------------------------*/
8046 static void genPagedPointerGet (operand *left,
8053 sym_link *rtype, *retype;
8055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8057 rtype = operandType(result);
8058 retype= getSpec(rtype);
8060 aopOp(left,ic,FALSE);
8062 /* if the value is already in a pointer register
8063 then don't need anything more */
8064 if (!AOP_INPREG(AOP(left))) {
8065 /* otherwise get a free pointer register */
8067 preg = getFreePtr(ic,&aop,FALSE);
8068 pic14_emitcode("mov","%s,%s",
8070 aopGet(AOP(left),0,FALSE,TRUE));
8071 rname = preg->name ;
8073 rname = aopGet(AOP(left),0,FALSE,FALSE);
8075 freeAsmop(left,NULL,ic,TRUE);
8076 aopOp (result,ic,FALSE);
8078 /* if bitfield then unpack the bits */
8079 if (IS_BITVAR(retype))
8080 genUnpackBits (result,rname,PPOINTER);
8082 /* we have can just get the values */
8083 int size = AOP_SIZE(result);
8088 pic14_emitcode("movx","a,@%s",rname);
8089 aopPut(AOP(result),"a",offset);
8094 pic14_emitcode("inc","%s",rname);
8098 /* now some housekeeping stuff */
8100 /* we had to allocate for this iCode */
8101 freeAsmop(NULL,aop,ic,TRUE);
8103 /* we did not allocate which means left
8104 already in a pointer register, then
8105 if size > 0 && this could be used again
8106 we have to point it back to where it
8108 if (AOP_SIZE(result) > 1 &&
8109 !OP_SYMBOL(left)->remat &&
8110 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8112 int size = AOP_SIZE(result) - 1;
8114 pic14_emitcode("dec","%s",rname);
8119 freeAsmop(result,NULL,ic,TRUE);
8124 /*-----------------------------------------------------------------*/
8125 /* genFarPointerGet - gget value from far space */
8126 /*-----------------------------------------------------------------*/
8127 static void genFarPointerGet (operand *left,
8128 operand *result, iCode *ic)
8131 sym_link *retype = getSpec(operandType(result));
8133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8135 aopOp(left,ic,FALSE);
8137 /* if the operand is already in dptr
8138 then we do nothing else we move the value to dptr */
8139 if (AOP_TYPE(left) != AOP_STR) {
8140 /* if this is remateriazable */
8141 if (AOP_TYPE(left) == AOP_IMMD)
8142 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8143 else { /* we need to get it byte by byte */
8144 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8145 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8146 if (options.model == MODEL_FLAT24)
8148 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8152 /* so dptr know contains the address */
8153 freeAsmop(left,NULL,ic,TRUE);
8154 aopOp(result,ic,FALSE);
8156 /* if bit then unpack */
8157 if (IS_BITVAR(retype))
8158 genUnpackBits(result,"dptr",FPOINTER);
8160 size = AOP_SIZE(result);
8164 pic14_emitcode("movx","a,@dptr");
8165 aopPut(AOP(result),"a",offset++);
8167 pic14_emitcode("inc","dptr");
8171 freeAsmop(result,NULL,ic,TRUE);
8174 /*-----------------------------------------------------------------*/
8175 /* genCodePointerGet - get value from code space */
8176 /*-----------------------------------------------------------------*/
8177 static void genCodePointerGet (operand *left,
8178 operand *result, iCode *ic)
8181 sym_link *retype = getSpec(operandType(result));
8183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8185 aopOp(left,ic,FALSE);
8187 /* if the operand is already in dptr
8188 then we do nothing else we move the value to dptr */
8189 if (AOP_TYPE(left) != AOP_STR) {
8190 /* if this is remateriazable */
8191 if (AOP_TYPE(left) == AOP_IMMD)
8192 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8193 else { /* we need to get it byte by byte */
8194 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8195 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8196 if (options.model == MODEL_FLAT24)
8198 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8202 /* so dptr know contains the address */
8203 freeAsmop(left,NULL,ic,TRUE);
8204 aopOp(result,ic,FALSE);
8206 /* if bit then unpack */
8207 if (IS_BITVAR(retype))
8208 genUnpackBits(result,"dptr",CPOINTER);
8210 size = AOP_SIZE(result);
8214 pic14_emitcode("clr","a");
8215 pic14_emitcode("movc","a,@a+dptr");
8216 aopPut(AOP(result),"a",offset++);
8218 pic14_emitcode("inc","dptr");
8222 freeAsmop(result,NULL,ic,TRUE);
8225 /*-----------------------------------------------------------------*/
8226 /* genGenPointerGet - gget value from generic pointer space */
8227 /*-----------------------------------------------------------------*/
8228 static void genGenPointerGet (operand *left,
8229 operand *result, iCode *ic)
8232 sym_link *retype = getSpec(operandType(result));
8234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8235 aopOp(left,ic,FALSE);
8236 aopOp(result,ic,FALSE);
8239 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8241 /* if the operand is already in dptr
8242 then we do nothing else we move the value to dptr */
8243 // if (AOP_TYPE(left) != AOP_STR) {
8244 /* if this is remateriazable */
8245 if (AOP_TYPE(left) == AOP_IMMD) {
8246 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8247 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8249 else { /* we need to get it byte by byte */
8251 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8252 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8254 size = AOP_SIZE(result);
8258 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8259 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8261 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8266 /* so dptr know contains the address */
8268 /* if bit then unpack */
8269 //if (IS_BITVAR(retype))
8270 // genUnpackBits(result,"dptr",GPOINTER);
8273 freeAsmop(left,NULL,ic,TRUE);
8274 freeAsmop(result,NULL,ic,TRUE);
8278 /*-----------------------------------------------------------------*/
8279 /* genConstPointerGet - get value from const generic pointer space */
8280 /*-----------------------------------------------------------------*/
8281 static void genConstPointerGet (operand *left,
8282 operand *result, iCode *ic)
8284 //sym_link *retype = getSpec(operandType(result));
8285 symbol *albl = newiTempLabel(NULL);
8286 symbol *blbl = newiTempLabel(NULL);
8289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8290 aopOp(left,ic,FALSE);
8291 aopOp(result,ic,FALSE);
8294 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8296 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8298 emitpcode(POC_CALL,popGetLabel(albl->key));
8299 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8300 emitpLabel(albl->key);
8302 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8304 emitpcode(poc,popGet(AOP(left),1));
8305 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8306 emitpcode(poc,popGet(AOP(left),0));
8307 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8309 emitpLabel(blbl->key);
8311 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8314 freeAsmop(left,NULL,ic,TRUE);
8315 freeAsmop(result,NULL,ic,TRUE);
8318 /*-----------------------------------------------------------------*/
8319 /* genPointerGet - generate code for pointer get */
8320 /*-----------------------------------------------------------------*/
8321 static void genPointerGet (iCode *ic)
8323 operand *left, *result ;
8324 sym_link *type, *etype;
8327 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8330 result = IC_RESULT(ic) ;
8332 /* depending on the type of pointer we need to
8333 move it to the correct pointer register */
8334 type = operandType(left);
8335 etype = getSpec(type);
8337 if (IS_PTR_CONST(type))
8338 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8340 /* if left is of type of pointer then it is simple */
8341 if (IS_PTR(type) && !IS_FUNC(type->next))
8342 p_type = DCL_TYPE(type);
8344 /* we have to go by the storage class */
8345 p_type = PTR_TYPE(SPEC_OCLS(etype));
8347 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8349 if (SPEC_OCLS(etype)->codesp ) {
8350 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8351 //p_type = CPOINTER ;
8354 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8355 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8356 /*p_type = FPOINTER ;*/
8358 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8359 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8360 /* p_type = PPOINTER; */
8362 if (SPEC_OCLS(etype) == idata )
8363 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8364 /* p_type = IPOINTER; */
8366 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8367 /* p_type = POINTER ; */
8370 /* now that we have the pointer type we assign
8371 the pointer values */
8376 genNearPointerGet (left,result,ic);
8380 genPagedPointerGet(left,result,ic);
8384 genFarPointerGet (left,result,ic);
8388 genConstPointerGet (left,result,ic);
8389 //pic14_emitcodePointerGet (left,result,ic);
8393 if (IS_PTR_CONST(type))
8394 genConstPointerGet (left,result,ic);
8396 genGenPointerGet (left,result,ic);
8402 /*-----------------------------------------------------------------*/
8403 /* genPackBits - generates code for packed bit storage */
8404 /*-----------------------------------------------------------------*/
8405 static void genPackBits (sym_link *etype ,
8407 char *rname, int p_type)
8415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8416 blen = SPEC_BLEN(etype);
8417 bstr = SPEC_BSTR(etype);
8419 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8422 /* if the bit lenth is less than or */
8423 /* it exactly fits a byte then */
8424 if (SPEC_BLEN(etype) <= 8 ) {
8425 shCount = SPEC_BSTR(etype) ;
8427 /* shift left acc */
8430 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8435 pic14_emitcode ("mov","b,a");
8436 pic14_emitcode("mov","a,@%s",rname);
8440 pic14_emitcode ("mov","b,a");
8441 pic14_emitcode("movx","a,@dptr");
8445 pic14_emitcode ("push","b");
8446 pic14_emitcode ("push","acc");
8447 pic14_emitcode ("lcall","__gptrget");
8448 pic14_emitcode ("pop","b");
8452 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8453 ((unsigned char)(0xFF << (blen+bstr)) |
8454 (unsigned char)(0xFF >> (8-bstr)) ) );
8455 pic14_emitcode ("orl","a,b");
8456 if (p_type == GPOINTER)
8457 pic14_emitcode("pop","b");
8463 pic14_emitcode("mov","@%s,a",rname);
8467 pic14_emitcode("movx","@dptr,a");
8471 DEBUGpic14_emitcode(";lcall","__gptrput");
8476 if ( SPEC_BLEN(etype) <= 8 )
8479 pic14_emitcode("inc","%s",rname);
8480 rLen = SPEC_BLEN(etype) ;
8482 /* now generate for lengths greater than one byte */
8485 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8495 pic14_emitcode("mov","@%s,a",rname);
8497 pic14_emitcode("mov","@%s,%s",rname,l);
8502 pic14_emitcode("movx","@dptr,a");
8507 DEBUGpic14_emitcode(";lcall","__gptrput");
8510 pic14_emitcode ("inc","%s",rname);
8515 /* last last was not complete */
8517 /* save the byte & read byte */
8520 pic14_emitcode ("mov","b,a");
8521 pic14_emitcode("mov","a,@%s",rname);
8525 pic14_emitcode ("mov","b,a");
8526 pic14_emitcode("movx","a,@dptr");
8530 pic14_emitcode ("push","b");
8531 pic14_emitcode ("push","acc");
8532 pic14_emitcode ("lcall","__gptrget");
8533 pic14_emitcode ("pop","b");
8537 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8538 pic14_emitcode ("orl","a,b");
8541 if (p_type == GPOINTER)
8542 pic14_emitcode("pop","b");
8547 pic14_emitcode("mov","@%s,a",rname);
8551 pic14_emitcode("movx","@dptr,a");
8555 DEBUGpic14_emitcode(";lcall","__gptrput");
8559 /*-----------------------------------------------------------------*/
8560 /* genDataPointerSet - remat pointer to data space */
8561 /*-----------------------------------------------------------------*/
8562 static void genDataPointerSet(operand *right,
8566 int size, offset = 0 ;
8567 char *l, buffer[256];
8569 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8570 aopOp(right,ic,FALSE);
8572 l = aopGet(AOP(result),0,FALSE,TRUE);
8573 size = AOP_SIZE(right);
8575 if ( AOP_TYPE(result) == AOP_PCODE) {
8576 fprintf(stderr,"genDataPointerSet %s, %d\n",
8577 AOP(result)->aopu.pcop->name,
8578 PCOI(AOP(result)->aopu.pcop)->offset);
8582 // tsd, was l+1 - the underline `_' prefix was being stripped
8585 sprintf(buffer,"(%s + %d)",l,offset);
8586 fprintf(stderr,"oops %s\n",buffer);
8588 sprintf(buffer,"%s",l);
8590 if (AOP_TYPE(right) == AOP_LIT) {
8591 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8592 lit = lit >> (8*offset);
8594 pic14_emitcode("movlw","%d",lit);
8595 pic14_emitcode("movwf","%s",buffer);
8597 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8598 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8599 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8602 pic14_emitcode("clrf","%s",buffer);
8603 //emitpcode(POC_CLRF, popRegFromString(buffer));
8604 emitpcode(POC_CLRF, popGet(AOP(result),0));
8607 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8608 pic14_emitcode("movwf","%s",buffer);
8610 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8611 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8612 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8619 freeAsmop(right,NULL,ic,TRUE);
8620 freeAsmop(result,NULL,ic,TRUE);
8623 /*-----------------------------------------------------------------*/
8624 /* genNearPointerSet - pic14_emitcode for near pointer put */
8625 /*-----------------------------------------------------------------*/
8626 static void genNearPointerSet (operand *right,
8633 sym_link *ptype = operandType(result);
8636 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8637 retype= getSpec(operandType(right));
8639 aopOp(result,ic,FALSE);
8642 /* if the result is rematerializable &
8643 in data space & not a bit variable */
8644 //if (AOP_TYPE(result) == AOP_IMMD &&
8645 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8646 DCL_TYPE(ptype) == POINTER &&
8647 !IS_BITVAR(retype)) {
8648 genDataPointerSet (right,result,ic);
8649 freeAsmop(result,NULL,ic,TRUE);
8653 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8654 aopOp(right,ic,FALSE);
8655 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8657 /* if the value is already in a pointer register
8658 then don't need anything more */
8659 if (!AOP_INPREG(AOP(result))) {
8660 /* otherwise get a free pointer register */
8661 //aop = newAsmop(0);
8662 //preg = getFreePtr(ic,&aop,FALSE);
8663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8664 //pic14_emitcode("mov","%s,%s",
8666 // aopGet(AOP(result),0,FALSE,TRUE));
8667 //rname = preg->name ;
8668 //pic14_emitcode("movwf","fsr");
8669 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8670 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8671 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8672 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8676 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8679 /* if bitfield then unpack the bits */
8680 if (IS_BITVAR(retype)) {
8681 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8682 "The programmer is obviously confused");
8683 //genPackBits (retype,right,rname,POINTER);
8687 /* we have can just get the values */
8688 int size = AOP_SIZE(right);
8691 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8693 l = aopGet(AOP(right),offset,FALSE,TRUE);
8696 //pic14_emitcode("mov","@%s,a",rname);
8697 pic14_emitcode("movf","indf,w ;1");
8700 if (AOP_TYPE(right) == AOP_LIT) {
8701 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8703 pic14_emitcode("movlw","%s",l);
8704 pic14_emitcode("movwf","indf ;2");
8706 pic14_emitcode("clrf","indf");
8708 pic14_emitcode("movf","%s,w",l);
8709 pic14_emitcode("movwf","indf ;2");
8711 //pic14_emitcode("mov","@%s,%s",rname,l);
8714 pic14_emitcode("incf","fsr,f ;3");
8715 //pic14_emitcode("inc","%s",rname);
8720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8721 /* now some housekeeping stuff */
8723 /* we had to allocate for this iCode */
8724 freeAsmop(NULL,aop,ic,TRUE);
8726 /* we did not allocate which means left
8727 already in a pointer register, then
8728 if size > 0 && this could be used again
8729 we have to point it back to where it
8731 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8732 if (AOP_SIZE(right) > 1 &&
8733 !OP_SYMBOL(result)->remat &&
8734 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8736 int size = AOP_SIZE(right) - 1;
8738 pic14_emitcode("decf","fsr,f");
8739 //pic14_emitcode("dec","%s",rname);
8743 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8746 freeAsmop(right,NULL,ic,TRUE);
8747 freeAsmop(result,NULL,ic,TRUE);
8750 /*-----------------------------------------------------------------*/
8751 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8752 /*-----------------------------------------------------------------*/
8753 static void genPagedPointerSet (operand *right,
8762 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8764 retype= getSpec(operandType(right));
8766 aopOp(result,ic,FALSE);
8768 /* if the value is already in a pointer register
8769 then don't need anything more */
8770 if (!AOP_INPREG(AOP(result))) {
8771 /* otherwise get a free pointer register */
8773 preg = getFreePtr(ic,&aop,FALSE);
8774 pic14_emitcode("mov","%s,%s",
8776 aopGet(AOP(result),0,FALSE,TRUE));
8777 rname = preg->name ;
8779 rname = aopGet(AOP(result),0,FALSE,FALSE);
8781 freeAsmop(result,NULL,ic,TRUE);
8782 aopOp (right,ic,FALSE);
8784 /* if bitfield then unpack the bits */
8785 if (IS_BITVAR(retype))
8786 genPackBits (retype,right,rname,PPOINTER);
8788 /* we have can just get the values */
8789 int size = AOP_SIZE(right);
8793 l = aopGet(AOP(right),offset,FALSE,TRUE);
8796 pic14_emitcode("movx","@%s,a",rname);
8799 pic14_emitcode("inc","%s",rname);
8805 /* now some housekeeping stuff */
8807 /* we had to allocate for this iCode */
8808 freeAsmop(NULL,aop,ic,TRUE);
8810 /* we did not allocate which means left
8811 already in a pointer register, then
8812 if size > 0 && this could be used again
8813 we have to point it back to where it
8815 if (AOP_SIZE(right) > 1 &&
8816 !OP_SYMBOL(result)->remat &&
8817 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8819 int size = AOP_SIZE(right) - 1;
8821 pic14_emitcode("dec","%s",rname);
8826 freeAsmop(right,NULL,ic,TRUE);
8831 /*-----------------------------------------------------------------*/
8832 /* genFarPointerSet - set value from far space */
8833 /*-----------------------------------------------------------------*/
8834 static void genFarPointerSet (operand *right,
8835 operand *result, iCode *ic)
8838 sym_link *retype = getSpec(operandType(right));
8840 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8841 aopOp(result,ic,FALSE);
8843 /* if the operand is already in dptr
8844 then we do nothing else we move the value to dptr */
8845 if (AOP_TYPE(result) != AOP_STR) {
8846 /* if this is remateriazable */
8847 if (AOP_TYPE(result) == AOP_IMMD)
8848 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8849 else { /* we need to get it byte by byte */
8850 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8851 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8852 if (options.model == MODEL_FLAT24)
8854 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8858 /* so dptr know contains the address */
8859 freeAsmop(result,NULL,ic,TRUE);
8860 aopOp(right,ic,FALSE);
8862 /* if bit then unpack */
8863 if (IS_BITVAR(retype))
8864 genPackBits(retype,right,"dptr",FPOINTER);
8866 size = AOP_SIZE(right);
8870 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8872 pic14_emitcode("movx","@dptr,a");
8874 pic14_emitcode("inc","dptr");
8878 freeAsmop(right,NULL,ic,TRUE);
8881 /*-----------------------------------------------------------------*/
8882 /* genGenPointerSet - set value from generic pointer space */
8883 /*-----------------------------------------------------------------*/
8884 static void genGenPointerSet (operand *right,
8885 operand *result, iCode *ic)
8888 sym_link *retype = getSpec(operandType(right));
8890 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8892 aopOp(result,ic,FALSE);
8893 aopOp(right,ic,FALSE);
8894 size = AOP_SIZE(right);
8896 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8898 /* if the operand is already in dptr
8899 then we do nothing else we move the value to dptr */
8900 if (AOP_TYPE(result) != AOP_STR) {
8901 /* if this is remateriazable */
8902 if (AOP_TYPE(result) == AOP_IMMD) {
8903 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8904 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8906 else { /* we need to get it byte by byte */
8907 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8908 size = AOP_SIZE(right);
8911 /* hack hack! see if this the FSR. If so don't load W */
8912 if(AOP_TYPE(right) != AOP_ACC) {
8914 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8915 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8918 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8920 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8921 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8925 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8926 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8929 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8936 if(aopIdx(AOP(result),0) != 4) {
8938 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8942 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8947 /* so dptr know contains the address */
8950 /* if bit then unpack */
8951 if (IS_BITVAR(retype))
8952 genPackBits(retype,right,"dptr",GPOINTER);
8954 size = AOP_SIZE(right);
8957 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8961 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8962 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8964 if (AOP_TYPE(right) == AOP_LIT)
8965 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8967 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8969 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8976 freeAsmop(right,NULL,ic,TRUE);
8977 freeAsmop(result,NULL,ic,TRUE);
8980 /*-----------------------------------------------------------------*/
8981 /* genPointerSet - stores the value into a pointer location */
8982 /*-----------------------------------------------------------------*/
8983 static void genPointerSet (iCode *ic)
8985 operand *right, *result ;
8986 sym_link *type, *etype;
8989 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8991 right = IC_RIGHT(ic);
8992 result = IC_RESULT(ic) ;
8994 /* depending on the type of pointer we need to
8995 move it to the correct pointer register */
8996 type = operandType(result);
8997 etype = getSpec(type);
8998 /* if left is of type of pointer then it is simple */
8999 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9000 p_type = DCL_TYPE(type);
9003 /* we have to go by the storage class */
9004 p_type = PTR_TYPE(SPEC_OCLS(etype));
9006 /* if (SPEC_OCLS(etype)->codesp ) { */
9007 /* p_type = CPOINTER ; */
9010 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9011 /* p_type = FPOINTER ; */
9013 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9014 /* p_type = PPOINTER ; */
9016 /* if (SPEC_OCLS(etype) == idata ) */
9017 /* p_type = IPOINTER ; */
9019 /* p_type = POINTER ; */
9022 /* now that we have the pointer type we assign
9023 the pointer values */
9028 genNearPointerSet (right,result,ic);
9032 genPagedPointerSet (right,result,ic);
9036 genFarPointerSet (right,result,ic);
9040 genGenPointerSet (right,result,ic);
9044 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9045 "genPointerSet: illegal pointer type");
9049 /*-----------------------------------------------------------------*/
9050 /* genIfx - generate code for Ifx statement */
9051 /*-----------------------------------------------------------------*/
9052 static void genIfx (iCode *ic, iCode *popIc)
9054 operand *cond = IC_COND(ic);
9057 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9059 aopOp(cond,ic,FALSE);
9061 /* get the value into acc */
9062 if (AOP_TYPE(cond) != AOP_CRY)
9063 pic14_toBoolean(cond);
9066 /* the result is now in the accumulator */
9067 freeAsmop(cond,NULL,ic,TRUE);
9069 /* if there was something to be popped then do it */
9073 /* if the condition is a bit variable */
9074 if (isbit && IS_ITEMP(cond) &&
9076 genIfxJump(ic,SPIL_LOC(cond)->rname);
9077 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9080 if (isbit && !IS_ITEMP(cond))
9081 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9089 /*-----------------------------------------------------------------*/
9090 /* genAddrOf - generates code for address of */
9091 /*-----------------------------------------------------------------*/
9092 static void genAddrOf (iCode *ic)
9094 operand *right, *result, *left;
9097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9100 //aopOp(IC_RESULT(ic),ic,FALSE);
9102 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9103 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9104 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9106 DEBUGpic14_AopType(__LINE__,left,right,result);
9108 size = AOP_SIZE(IC_RESULT(ic));
9112 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9113 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9117 freeAsmop(left,NULL,ic,FALSE);
9118 freeAsmop(result,NULL,ic,TRUE);
9123 /*-----------------------------------------------------------------*/
9124 /* genFarFarAssign - assignment when both are in far space */
9125 /*-----------------------------------------------------------------*/
9126 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9128 int size = AOP_SIZE(right);
9131 /* first push the right side on to the stack */
9133 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9135 pic14_emitcode ("push","acc");
9138 freeAsmop(right,NULL,ic,FALSE);
9139 /* now assign DPTR to result */
9140 aopOp(result,ic,FALSE);
9141 size = AOP_SIZE(result);
9143 pic14_emitcode ("pop","acc");
9144 aopPut(AOP(result),"a",--offset);
9146 freeAsmop(result,NULL,ic,FALSE);
9151 /*-----------------------------------------------------------------*/
9152 /* genAssign - generate code for assignment */
9153 /*-----------------------------------------------------------------*/
9154 static void genAssign (iCode *ic)
9156 operand *result, *right;
9157 int size, offset,know_W;
9158 unsigned long lit = 0L;
9160 result = IC_RESULT(ic);
9161 right = IC_RIGHT(ic) ;
9163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9165 /* if they are the same */
9166 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9169 aopOp(right,ic,FALSE);
9170 aopOp(result,ic,TRUE);
9172 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9174 /* if they are the same registers */
9175 if (pic14_sameRegs(AOP(right),AOP(result)))
9178 /* if the result is a bit */
9179 if (AOP_TYPE(result) == AOP_CRY) {
9181 /* if the right size is a literal then
9182 we know what the value is */
9183 if (AOP_TYPE(right) == AOP_LIT) {
9185 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9186 popGet(AOP(result),0));
9188 if (((int) operandLitValue(right)))
9189 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9190 AOP(result)->aopu.aop_dir,
9191 AOP(result)->aopu.aop_dir);
9193 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9194 AOP(result)->aopu.aop_dir,
9195 AOP(result)->aopu.aop_dir);
9199 /* the right is also a bit variable */
9200 if (AOP_TYPE(right) == AOP_CRY) {
9201 emitpcode(POC_BCF, popGet(AOP(result),0));
9202 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9203 emitpcode(POC_BSF, popGet(AOP(result),0));
9205 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9206 AOP(result)->aopu.aop_dir,
9207 AOP(result)->aopu.aop_dir);
9208 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9209 AOP(right)->aopu.aop_dir,
9210 AOP(right)->aopu.aop_dir);
9211 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9212 AOP(result)->aopu.aop_dir,
9213 AOP(result)->aopu.aop_dir);
9218 emitpcode(POC_BCF, popGet(AOP(result),0));
9219 pic14_toBoolean(right);
9221 emitpcode(POC_BSF, popGet(AOP(result),0));
9222 //aopPut(AOP(result),"a",0);
9226 /* bit variables done */
9228 size = AOP_SIZE(result);
9230 if(AOP_TYPE(right) == AOP_LIT)
9231 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9233 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9235 if(aopIdx(AOP(result),0) == 4) {
9236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9237 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9238 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9241 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9247 if(AOP_TYPE(right) == AOP_LIT) {
9249 if(know_W != (lit&0xff))
9250 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9252 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9254 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9258 } else if (AOP_TYPE(right) == AOP_CRY) {
9259 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9261 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9262 emitpcode(POC_INCF, popGet(AOP(result),0));
9265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9266 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9267 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9275 freeAsmop (right,NULL,ic,FALSE);
9276 freeAsmop (result,NULL,ic,TRUE);
9279 /*-----------------------------------------------------------------*/
9280 /* genJumpTab - genrates code for jump table */
9281 /*-----------------------------------------------------------------*/
9282 static void genJumpTab (iCode *ic)
9287 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9289 aopOp(IC_JTCOND(ic),ic,FALSE);
9290 /* get the condition into accumulator */
9291 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9293 /* multiply by three */
9294 pic14_emitcode("add","a,acc");
9295 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9297 jtab = newiTempLabel(NULL);
9298 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9299 pic14_emitcode("jmp","@a+dptr");
9300 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9302 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9303 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9305 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9306 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9307 emitpLabel(jtab->key);
9309 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9311 /* now generate the jump labels */
9312 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9313 jtab = setNextItem(IC_JTLABELS(ic))) {
9314 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9315 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9321 /*-----------------------------------------------------------------*/
9322 /* genMixedOperation - gen code for operators between mixed types */
9323 /*-----------------------------------------------------------------*/
9325 TSD - Written for the PIC port - but this unfortunately is buggy.
9326 This routine is good in that it is able to efficiently promote
9327 types to different (larger) sizes. Unfortunately, the temporary
9328 variables that are optimized out by this routine are sometimes
9329 used in other places. So until I know how to really parse the
9330 iCode tree, I'm going to not be using this routine :(.
9332 static int genMixedOperation (iCode *ic)
9335 operand *result = IC_RESULT(ic);
9336 sym_link *ctype = operandType(IC_LEFT(ic));
9337 operand *right = IC_RIGHT(ic);
9343 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9345 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9351 nextright = IC_RIGHT(nextic);
9352 nextleft = IC_LEFT(nextic);
9353 nextresult = IC_RESULT(nextic);
9355 aopOp(right,ic,FALSE);
9356 aopOp(result,ic,FALSE);
9357 aopOp(nextright, nextic, FALSE);
9358 aopOp(nextleft, nextic, FALSE);
9359 aopOp(nextresult, nextic, FALSE);
9361 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9367 pic14_emitcode(";remove right +","");
9369 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9375 pic14_emitcode(";remove left +","");
9379 big = AOP_SIZE(nextleft);
9380 small = AOP_SIZE(nextright);
9382 switch(nextic->op) {
9385 pic14_emitcode(";optimize a +","");
9386 /* if unsigned or not an integral type */
9387 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9388 pic14_emitcode(";add a bit to something","");
9391 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9393 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9394 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9395 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9397 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9405 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9406 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9407 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9410 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9412 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9413 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9414 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9415 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9416 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9419 pic14_emitcode("rlf","known_zero,w");
9426 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9427 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9428 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9430 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9440 freeAsmop(right,NULL,ic,TRUE);
9441 freeAsmop(result,NULL,ic,TRUE);
9442 freeAsmop(nextright,NULL,ic,TRUE);
9443 freeAsmop(nextleft,NULL,ic,TRUE);
9445 nextic->generated = 1;
9452 /*-----------------------------------------------------------------*/
9453 /* genCast - gen code for casting */
9454 /*-----------------------------------------------------------------*/
9455 static void genCast (iCode *ic)
9457 operand *result = IC_RESULT(ic);
9458 sym_link *ctype = operandType(IC_LEFT(ic));
9459 sym_link *rtype = operandType(IC_RIGHT(ic));
9460 operand *right = IC_RIGHT(ic);
9463 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9464 /* if they are equivalent then do nothing */
9465 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9468 aopOp(right,ic,FALSE) ;
9469 aopOp(result,ic,FALSE);
9471 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9473 /* if the result is a bit */
9474 if (AOP_TYPE(result) == AOP_CRY) {
9475 /* if the right size is a literal then
9476 we know what the value is */
9477 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9478 if (AOP_TYPE(right) == AOP_LIT) {
9480 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9481 popGet(AOP(result),0));
9483 if (((int) operandLitValue(right)))
9484 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9485 AOP(result)->aopu.aop_dir,
9486 AOP(result)->aopu.aop_dir);
9488 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9489 AOP(result)->aopu.aop_dir,
9490 AOP(result)->aopu.aop_dir);
9495 /* the right is also a bit variable */
9496 if (AOP_TYPE(right) == AOP_CRY) {
9499 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9501 pic14_emitcode("clrc","");
9502 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9503 AOP(right)->aopu.aop_dir,
9504 AOP(right)->aopu.aop_dir);
9505 aopPut(AOP(result),"c",0);
9510 if (AOP_TYPE(right) == AOP_REG) {
9511 emitpcode(POC_BCF, popGet(AOP(result),0));
9512 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9513 emitpcode(POC_BSF, popGet(AOP(result),0));
9515 pic14_toBoolean(right);
9516 aopPut(AOP(result),"a",0);
9520 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9522 size = AOP_SIZE(result);
9524 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9526 emitpcode(POC_CLRF, popGet(AOP(result),0));
9527 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9528 emitpcode(POC_INCF, popGet(AOP(result),0));
9531 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9536 /* if they are the same size : or less */
9537 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9539 /* if they are in the same place */
9540 if (pic14_sameRegs(AOP(right),AOP(result)))
9543 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9544 if (IS_PTR_CONST(rtype))
9545 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9546 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9547 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9549 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9550 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9551 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9552 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9553 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9554 if(AOP_SIZE(result) <2)
9555 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9559 /* if they in different places then copy */
9560 size = AOP_SIZE(result);
9563 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9564 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9566 //aopPut(AOP(result),
9567 // aopGet(AOP(right),offset,FALSE,FALSE),
9577 /* if the result is of type pointer */
9578 if (IS_PTR(ctype)) {
9581 sym_link *type = operandType(right);
9582 sym_link *etype = getSpec(type);
9583 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9585 /* pointer to generic pointer */
9586 if (IS_GENPTR(ctype)) {
9590 p_type = DCL_TYPE(type);
9592 /* we have to go by the storage class */
9593 p_type = PTR_TYPE(SPEC_OCLS(etype));
9595 /* if (SPEC_OCLS(etype)->codesp ) */
9596 /* p_type = CPOINTER ; */
9598 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9599 /* p_type = FPOINTER ; */
9601 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9602 /* p_type = PPOINTER; */
9604 /* if (SPEC_OCLS(etype) == idata ) */
9605 /* p_type = IPOINTER ; */
9607 /* p_type = POINTER ; */
9610 /* the first two bytes are known */
9611 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9612 size = GPTRSIZE - 1;
9615 if(offset < AOP_SIZE(right)) {
9616 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9617 if ((AOP_TYPE(right) == AOP_PCODE) &&
9618 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9619 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9620 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9623 aopGet(AOP(right),offset,FALSE,FALSE),
9627 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9630 /* the last byte depending on type */
9634 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9637 pic14_emitcode(";BUG!? ","%d",__LINE__);
9641 pic14_emitcode(";BUG!? ","%d",__LINE__);
9645 pic14_emitcode(";BUG!? ","%d",__LINE__);
9650 /* this should never happen */
9651 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9652 "got unknown pointer type");
9655 //aopPut(AOP(result),l, GPTRSIZE - 1);
9659 /* just copy the pointers */
9660 size = AOP_SIZE(result);
9664 aopGet(AOP(right),offset,FALSE,FALSE),
9673 /* so we now know that the size of destination is greater
9674 than the size of the source.
9675 Now, if the next iCode is an operator then we might be
9676 able to optimize the operation without performing a cast.
9678 if(genMixedOperation(ic))
9681 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9683 /* we move to result for the size of source */
9684 size = AOP_SIZE(right);
9687 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9688 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9692 /* now depending on the sign of the destination */
9693 size = AOP_SIZE(result) - AOP_SIZE(right);
9694 /* if unsigned or not an integral type */
9695 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9697 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9699 /* we need to extend the sign :{ */
9702 /* Save one instruction of casting char to int */
9703 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9704 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9705 emitpcode(POC_DECF, popGet(AOP(result),offset));
9707 emitpcodeNULLop(POC_CLRW);
9710 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9712 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9714 emitpcode(POC_MOVLW, popGetLit(0xff));
9717 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9722 freeAsmop(right,NULL,ic,TRUE);
9723 freeAsmop(result,NULL,ic,TRUE);
9727 /*-----------------------------------------------------------------*/
9728 /* genDjnz - generate decrement & jump if not zero instrucion */
9729 /*-----------------------------------------------------------------*/
9730 static int genDjnz (iCode *ic, iCode *ifx)
9733 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9738 /* if the if condition has a false label
9739 then we cannot save */
9743 /* if the minus is not of the form
9745 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9746 !IS_OP_LITERAL(IC_RIGHT(ic)))
9749 if (operandLitValue(IC_RIGHT(ic)) != 1)
9752 /* if the size of this greater than one then no
9754 if (getSize(operandType(IC_RESULT(ic))) > 1)
9757 /* otherwise we can save BIG */
9758 lbl = newiTempLabel(NULL);
9759 lbl1= newiTempLabel(NULL);
9761 aopOp(IC_RESULT(ic),ic,FALSE);
9763 if (IS_AOP_PREG(IC_RESULT(ic))) {
9764 pic14_emitcode("dec","%s",
9765 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9766 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9767 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9771 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9772 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9774 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9775 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9778 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9779 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9780 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9781 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9784 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9789 /*-----------------------------------------------------------------*/
9790 /* genReceive - generate code for a receive iCode */
9791 /*-----------------------------------------------------------------*/
9792 static void genReceive (iCode *ic)
9794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9796 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9797 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9798 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9800 int size = getSize(operandType(IC_RESULT(ic)));
9801 int offset = fReturnSizePic - size;
9803 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9804 fReturn[fReturnSizePic - offset - 1] : "acc"));
9807 aopOp(IC_RESULT(ic),ic,FALSE);
9808 size = AOP_SIZE(IC_RESULT(ic));
9811 pic14_emitcode ("pop","acc");
9812 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9817 aopOp(IC_RESULT(ic),ic,FALSE);
9819 assignResultValue(IC_RESULT(ic));
9822 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9825 /*-----------------------------------------------------------------*/
9826 /* genpic14Code - generate code for pic14 based controllers */
9827 /*-----------------------------------------------------------------*/
9829 * At this point, ralloc.c has gone through the iCode and attempted
9830 * to optimize in a way suitable for a PIC. Now we've got to generate
9831 * PIC instructions that correspond to the iCode.
9833 * Once the instructions are generated, we'll pass through both the
9834 * peep hole optimizer and the pCode optimizer.
9835 *-----------------------------------------------------------------*/
9837 void genpic14Code (iCode *lic)
9842 lineHead = lineCurr = NULL;
9844 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9847 /* if debug information required */
9848 if (options.debug && currFunc) {
9850 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9852 if (IS_STATIC(currFunc->etype)) {
9853 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9854 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9856 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9857 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9864 for (ic = lic ; ic ; ic = ic->next ) {
9866 DEBUGpic14_emitcode(";ic","");
9867 if ( cln != ic->lineno ) {
9868 if ( options.debug ) {
9870 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9871 FileBaseName(ic->filename),ic->lineno,
9872 ic->level,ic->block);
9876 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9877 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9878 printCLine(ic->filename, ic->lineno));
9881 newpCodeCSource(ic->lineno,
9883 printCLine(ic->filename, ic->lineno)));
9887 /* if the result is marked as
9888 spilt and rematerializable or code for
9889 this has already been generated then
9891 if (resultRemat(ic) || ic->generated )
9894 /* depending on the operation */
9913 /* IPOP happens only when trying to restore a
9914 spilt live range, if there is an ifx statement
9915 following this pop then the if statement might
9916 be using some of the registers being popped which
9917 would destory the contents of the register so
9918 we need to check for this condition and handle it */
9920 ic->next->op == IFX &&
9921 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9922 genIfx (ic->next,ic);
9940 genEndFunction (ic);
9960 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9977 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9981 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9988 /* note these two are xlated by algebraic equivalence
9989 during parsing SDCC.y */
9990 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9991 "got '>=' or '<=' shouldn't have come here");
9995 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10007 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10011 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10015 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10039 genRightShift (ic);
10042 case GET_VALUE_AT_ADDRESS:
10047 if (POINTER_SET(ic))
10074 addSet(&_G.sendSet,ic);
10083 /* now we are ready to call the
10084 peep hole optimizer */
10085 if (!options.nopeep) {
10086 peepHole (&lineHead);
10088 /* now do the actual printing */
10089 printLine (lineHead,codeOutFile);
10092 DFPRINTF((stderr,"printing pBlock\n\n"));
10093 printpBlock(stdout,pb);