1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic16
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
8 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
29 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
30 Made everything static
31 -------------------------------------------------------------------------*/
37 #include "SDCCglobl.h"
41 #include "SDCCpeeph.h"
49 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
50 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
51 void pic16_genMult8X8_8 (operand *, operand *,operand *);
52 void pic16_genMult16X16_16(operand *, operand *, operand *);
53 void pic16_genMult32X32_32(operand *, operand *, operand *);
54 pCode *pic16_AssembleLine(char *line, int peeps);
55 extern void pic16_printpBlock(FILE *of, pBlock *pb);
56 static asmop *newAsmop (short type);
57 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
58 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
59 static void mov2w (asmop *aop, int offset);
60 static int aopIdx (asmop *aop, int offset);
62 static int labelOffset=0;
63 extern int pic16_debug_verbose;
64 static int optimized_for_speed = 0;
70 /* max_key keeps track of the largest label number used in
71 a function. This is then used to adjust the label offset
72 for the next function.
75 static int GpsuedoStkPtr=0;
77 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
78 unsigned int pic16aopLiteral (value *val, int offset);
79 const char *pic16_AopType(short type);
80 static iCode *ifxForOp ( operand *op, iCode *ic );
82 void pic16_pushpCodeOp(pCodeOp *pcop);
83 void pic16_poppCodeOp(pCodeOp *pcop);
87 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
89 /* this is the down and dirty file with all kinds of
90 kludgy & hacky stuff. This is what it is all about
91 CODE GENERATION for a specific MCU . some of the
92 routines may be reusable, will have to see */
94 static char *zero = "#0x00";
95 static char *one = "#0x01";
96 static char *spname = "sp";
100 * Function return value policy (MSB-->LSB):
102 * 16 bits -> PRODL:WREG
103 * 24 bits -> PRODH:PRODL:WREG
104 * 32 bits -> FSR0L:PRODH:PRODL:WREG
105 * >32 bits -> on stack, and FSR0 points to the beginning
110 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
111 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
112 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
113 static char **fReturn = fReturnpic16;
115 static char *accUse[] = {"WREG"};
117 //static short rbank = -1;
130 /* Resolved ifx structure. This structure stores information
131 about an iCode ifx that makes it easier to generate code.
133 typedef struct resolvedIfx {
134 symbol *lbl; /* pointer to a label */
135 int condition; /* true or false ifx */
136 int generated; /* set true when the code associated with the ifx
140 extern int pic16_ptrRegReq ;
141 extern int pic16_nRegs;
142 extern FILE *codeOutFile;
143 static void saverbank (int, iCode *,bool);
145 static lineNode *lineHead = NULL;
146 static lineNode *lineCurr = NULL;
148 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
149 0xE0, 0xC0, 0x80, 0x00};
150 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
151 0x07, 0x03, 0x01, 0x00};
155 /*-----------------------------------------------------------------*/
156 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
157 /* exponent of 2 is returned, otherwise -1 is */
159 /* note that this is similar to the function `powof2' in SDCCsymt */
163 /*-----------------------------------------------------------------*/
164 static int my_powof2 (unsigned long num)
167 if( (num & (num-1)) == 0) {
180 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
182 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
184 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
185 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
186 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
187 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
188 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
189 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
190 ((result) ? AOP_SIZE(result) : 0));
193 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
196 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
198 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
199 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
200 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
201 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
202 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
203 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
207 void pic16_emitpcomment (char *fmt, ...)
210 char lb[INITIAL_INLINEASM];
216 vsprintf(lb+1,fmt,ap);
218 while (isspace(*lbp)) lbp++;
221 lineCurr = (lineCurr ?
222 connectLine(lineCurr,newLineNode(lb)) :
223 (lineHead = newLineNode(lb)));
224 lineCurr->isInline = _G.inLine;
225 lineCurr->isDebug = _G.debugLine;
227 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
230 // fprintf(stderr, "%s\n", lb);
233 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
236 char lb[INITIAL_INLINEASM];
239 if(!pic16_debug_verbose)
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
262 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
265 // fprintf(stderr, "%s\n", lb);
268 void pic16_emitpLabel(int key)
270 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
273 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
277 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
279 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
281 // fprintf(stderr, "%s\n", pcop->name);
284 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
287 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
293 #define pic16_emitcode DEBUGpic16_emitcode
295 /*-----------------------------------------------------------------*/
296 /* pic16_emitcode - writes the code into a file : for now it is simple */
297 /*-----------------------------------------------------------------*/
298 void pic16_emitcode (char *inst,char *fmt, ...)
301 char lb[INITIAL_INLINEASM];
308 sprintf(lb,"%s\t",inst);
310 sprintf(lb,"%s",inst);
311 vsprintf(lb+(strlen(lb)),fmt,ap);
315 while (isspace(*lbp)) lbp++;
318 lineCurr = (lineCurr ?
319 connectLine(lineCurr,newLineNode(lb)) :
320 (lineHead = newLineNode(lb)));
321 lineCurr->isInline = _G.inLine;
322 lineCurr->isDebug = _G.debugLine;
324 // VR fprintf(stderr, "lb = <%s>\n", lbp);
326 // if(pic16_debug_verbose)
327 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
334 /*-----------------------------------------------------------------*/
335 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
336 /*-----------------------------------------------------------------*/
337 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
339 bool r0iu = FALSE , r1iu = FALSE;
340 bool r0ou = FALSE , r1ou = FALSE;
342 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
344 /* the logic: if r0 & r1 used in the instruction
345 then we are in trouble otherwise */
347 /* first check if r0 & r1 are used by this
348 instruction, in which case we are in trouble */
349 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
350 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
355 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
356 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
358 /* if no usage of r0 then return it */
359 if (!r0iu && !r0ou) {
360 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
361 (*aopp)->type = AOP_R0;
363 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
366 /* if no usage of r1 then return it */
367 if (!r1iu && !r1ou) {
368 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
369 (*aopp)->type = AOP_R1;
371 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
374 /* now we know they both have usage */
375 /* if r0 not used in this instruction */
377 /* push it if not already pushed */
379 //pic16_emitcode ("push","%s",
380 // pic16_regWithIdx(R0_IDX)->dname);
384 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
385 (*aopp)->type = AOP_R0;
387 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
390 /* if r1 not used then */
393 /* push it if not already pushed */
395 //pic16_emitcode ("push","%s",
396 // pic16_regWithIdx(R1_IDX)->dname);
400 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
401 (*aopp)->type = AOP_R1;
402 return pic16_regWithIdx(R1_IDX);
406 /* I said end of world but not quite end of world yet */
407 /* if this is a result then we can push it on the stack*/
409 (*aopp)->type = AOP_STK;
413 /* other wise this is true end of the world */
414 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
415 "getFreePtr should never reach here");
419 /*-----------------------------------------------------------------*/
420 /* newAsmop - creates a new asmOp */
421 /*-----------------------------------------------------------------*/
422 static asmop *newAsmop (short type)
426 aop = Safe_calloc(1,sizeof(asmop));
431 static void genSetDPTR(int n)
435 pic16_emitcode(";", "Select standard DPTR");
436 pic16_emitcode("mov", "dps, #0x00");
440 pic16_emitcode(";", "Select alternate DPTR");
441 pic16_emitcode("mov", "dps, #0x01");
445 /*-----------------------------------------------------------------*/
446 /* resolveIfx - converts an iCode ifx into a form more useful for */
447 /* generating code */
448 /*-----------------------------------------------------------------*/
449 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
452 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
458 resIfx->condition = 1; /* assume that the ifx is true */
459 resIfx->generated = 0; /* indicate that the ifx has not been used */
462 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
465 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
466 __FUNCTION__,__LINE__,resIfx->lbl->key);
471 resIfx->lbl = IC_TRUE(ifx);
473 resIfx->lbl = IC_FALSE(ifx);
474 resIfx->condition = 0;
478 DEBUGpic16_emitcode("; ***","ifx true is non-null");
480 DEBUGpic16_emitcode("; ***","ifx false is non-null");
484 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
488 /*-----------------------------------------------------------------*/
489 /* pointerCode - returns the code for a pointer type */
490 /*-----------------------------------------------------------------*/
491 static int pointerCode (sym_link *etype)
494 return PTR_TYPE(SPEC_OCLS(etype));
498 /*-----------------------------------------------------------------*/
499 /* aopForSym - for a true symbol */
500 /*-----------------------------------------------------------------*/
501 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
504 memmap *space= SPEC_OCLS(sym->etype);
506 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
507 /* if already has one */
509 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
513 /* if symbol was initially placed onStack then we must re-place it
514 * to direct memory, since pic16 does not have a specific stack */
517 SPEC_OCLS( sym->etype ) = data;
523 /* assign depending on the storage class */
524 /* if it is on the stack or indirectly addressable */
525 /* space we need to assign either r0 or r1 to it */
526 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
528 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
529 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
531 sym->aop = aop = newAsmop(0);
532 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
533 aop->size = getSize(sym->type);
535 /* now assign the address of the variable to
536 the pointer register */
537 if (aop->type != AOP_STK) {
541 pic16_emitcode("push","acc");
543 pic16_emitcode("mov","a,_bp");
544 pic16_emitcode("add","a,#0x%02x",
546 ((char)(sym->stack - _G.nRegsSaved )) :
547 ((char)sym->stack)) & 0xff);
548 pic16_emitcode("mov","%s,a",
549 aop->aopu.aop_ptr->name);
552 pic16_emitcode("pop","acc");
554 pic16_emitcode("mov","%s,#%s",
555 aop->aopu.aop_ptr->name,
557 aop->paged = space->paged;
559 aop->aopu.aop_stk = sym->stack;
564 if (sym->onStack && options.stack10bit)
566 /* It's on the 10 bit stack, which is located in
570 //DEBUGpic16_emitcode(";","%d",__LINE__);
573 pic16_emitcode("push","acc");
575 pic16_emitcode("mov","a,_bp");
576 pic16_emitcode("add","a,#0x%02x",
578 ((char)(sym->stack - _G.nRegsSaved )) :
579 ((char)sym->stack)) & 0xff);
582 pic16_emitcode ("mov","dpx1,#0x40");
583 pic16_emitcode ("mov","dph1,#0x00");
584 pic16_emitcode ("mov","dpl1, a");
588 pic16_emitcode("pop","acc");
590 sym->aop = aop = newAsmop(AOP_DPTR2);
591 aop->size = getSize(sym->type);
595 //DEBUGpic16_emitcode(";","%d",__LINE__);
596 /* if in bit space */
597 if (IN_BITSPACE(space)) {
598 sym->aop = aop = newAsmop (AOP_CRY);
599 aop->aopu.aop_dir = sym->rname ;
600 aop->size = getSize(sym->type);
601 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
604 /* if it is in direct space */
605 if (IN_DIRSPACE(space)) {
606 sym->aop = aop = newAsmop (AOP_DIR);
607 aop->aopu.aop_dir = sym->rname ;
608 aop->size = getSize(sym->type);
609 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
610 pic16_allocDirReg( IC_LEFT(ic) );
615 /* special case for a function */
616 if (IS_FUNC(sym->type)) {
617 sym->aop = aop = newAsmop(AOP_IMMD);
618 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
619 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
620 strcpy(aop->aopu.aop_immd,sym->rname);
621 aop->size = FPTRSIZE;
622 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
628 /* only remaining is far space */
629 /* in which case DPTR gets the address */
630 sym->aop = aop = newAsmop(AOP_PCODE);
632 /* change the next if to 1 to revert to good old immediate code */
633 if(IN_CODESPACE(space)) {
634 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
635 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
636 PCOI(aop->aopu.pcop)->index = 0;
638 /* try to allocate via direct register */
639 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset); // Patch 8
640 // aop->size = getSize( sym->type );
643 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
644 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
647 if(!pic16_allocDirReg (IC_LEFT(ic)))
651 if(IN_DIRSPACE( space ))
653 else if(IN_CODESPACE( space ))
654 aop->size = FPTRSIZE;
655 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
656 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
661 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
663 /* if it is in code space */
664 if (IN_CODESPACE(space))
670 /*-----------------------------------------------------------------*/
671 /* aopForRemat - rematerialzes an object */
672 /*-----------------------------------------------------------------*/
673 static asmop *aopForRemat (operand *op) // x symbol *sym)
675 symbol *sym = OP_SYMBOL(op);
676 iCode *ic = NULL, *oldic;
677 asmop *aop = newAsmop(AOP_PCODE);
683 ic = sym->rematiCode;
685 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
687 if(IS_OP_POINTER(op)) {
688 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
694 // pic16_emitpcomment("ic: %s\n", printILine(ic));
697 val += (int) operandLitValue(IC_RIGHT(ic));
698 } else if (ic->op == '-') {
699 val -= (int) operandLitValue(IC_RIGHT(ic));
703 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
706 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
708 if(!op->isaddr)viaimmd++; else viaimmd=0;
710 /* set the following if to 1 to revert to good old immediate code */
711 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
714 pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__);
716 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
719 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
721 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
724 PCOI(aop->aopu.pcop)->index = val;
726 pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__);
728 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
729 // aop->size = AOP_SIZE( IC_LEFT(ic) );
733 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
734 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
736 val, IS_PTR_CONST(operandType(op)));
738 val, IS_CODEPTR(operandType(op)));
741 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
743 pic16_allocDirReg (IC_LEFT(ic));
745 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
751 static int aopIdx (asmop *aop, int offset)
756 if(aop->type != AOP_REG)
759 return aop->aopu.aop_reg[offset]->rIdx;
762 /*-----------------------------------------------------------------*/
763 /* regsInCommon - two operands have some registers in common */
764 /*-----------------------------------------------------------------*/
765 static bool regsInCommon (operand *op1, operand *op2)
770 /* if they have registers in common */
771 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
774 sym1 = OP_SYMBOL(op1);
775 sym2 = OP_SYMBOL(op2);
777 if (sym1->nRegs == 0 || sym2->nRegs == 0)
780 for (i = 0 ; i < sym1->nRegs ; i++) {
785 for (j = 0 ; j < sym2->nRegs ;j++ ) {
789 if (sym2->regs[j] == sym1->regs[i])
797 /*-----------------------------------------------------------------*/
798 /* operandsEqu - equivalent */
799 /*-----------------------------------------------------------------*/
800 static bool operandsEqu ( operand *op1, operand *op2)
804 /* if they not symbols */
805 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
808 sym1 = OP_SYMBOL(op1);
809 sym2 = OP_SYMBOL(op2);
811 /* if both are itemps & one is spilt
812 and the other is not then false */
813 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
814 sym1->isspilt != sym2->isspilt )
817 /* if they are the same */
821 if (strcmp(sym1->rname,sym2->rname) == 0)
825 /* if left is a tmp & right is not */
829 (sym1->usl.spillLoc == sym2))
836 (sym2->usl.spillLoc == sym1))
842 /*-----------------------------------------------------------------*/
843 /* pic16_sameRegs - two asmops have the same registers */
844 /*-----------------------------------------------------------------*/
845 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
852 if (aop1->type != AOP_REG ||
853 aop2->type != AOP_REG )
856 if (aop1->size != aop2->size )
859 for (i = 0 ; i < aop1->size ; i++ )
860 if (aop1->aopu.aop_reg[i] !=
861 aop2->aopu.aop_reg[i] )
867 /*-----------------------------------------------------------------*/
868 /* pic16_aopOp - allocates an asmop for an operand : */
869 /*-----------------------------------------------------------------*/
870 void pic16_aopOp (operand *op, iCode *ic, bool result)
879 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
881 /* if this a literal */
882 if (IS_OP_LITERAL(op)) {
883 op->aop = aop = newAsmop(AOP_LIT);
884 aop->aopu.aop_lit = op->operand.valOperand;
885 aop->size = getSize(operandType(op));
890 sym_link *type = operandType(op);
892 if(IS_PTR_CONST(type))
896 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
899 /* if already has a asmop then continue */
903 /* if the underlying symbol has a aop */
904 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
905 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
906 op->aop = OP_SYMBOL(op)->aop;
910 /* if this is a true symbol */
911 if (IS_TRUE_SYMOP(op)) {
912 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
913 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
917 /* this is a temporary : this has
923 e) can be a return use only */
927 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
928 /* if the type is a conditional */
929 if (sym->regType == REG_CND) {
930 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
935 /* if it is spilt then two situations
937 b) has a spill location */
938 if (sym->isspilt || sym->nRegs == 0) {
940 DEBUGpic16_emitcode(";","%d",__LINE__);
941 /* rematerialize it NOW */
944 sym->aop = op->aop = aop =
946 aop->size = getSize(sym->type);
947 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
954 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
955 aop->size = getSize(sym->type);
956 for ( i = 0 ; i < 1 ; i++ ) {
957 aop->aopu.aop_str[i] = accUse[i];
958 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
960 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
961 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
969 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
970 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
971 //pic16_allocDirReg (IC_LEFT(ic));
972 aop->size = getSize(sym->type);
977 aop = op->aop = sym->aop = newAsmop(AOP_STR);
978 aop->size = getSize(sym->type);
979 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
980 aop->aopu.aop_str[i] = fReturn[i];
982 DEBUGpic16_emitcode(";","%d",__LINE__);
986 /* else spill location */
987 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
988 /* force a new aop if sizes differ */
989 sym->usl.spillLoc->aop = NULL;
991 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
992 __FUNCTION__,__LINE__,
993 sym->usl.spillLoc->rname,
994 sym->rname, sym->usl.spillLoc->offset);
996 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
997 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
998 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1000 sym->usl.spillLoc->offset);
1001 aop->size = getSize(sym->type);
1007 sym_link *type = operandType(op);
1009 if(IS_PTR_CONST(type))
1011 if(IS_CODEPTR(type))
1013 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1016 /* must be in a register */
1017 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1018 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1019 aop->size = sym->nRegs;
1020 for ( i = 0 ; i < sym->nRegs ;i++)
1021 aop->aopu.aop_reg[i] = sym->regs[i];
1024 /*-----------------------------------------------------------------*/
1025 /* pic16_freeAsmop - free up the asmop given to an operand */
1026 /*----------------------------------------------------------------*/
1027 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1044 /* depending on the asmop type only three cases need work AOP_RO
1045 , AOP_R1 && AOP_STK */
1047 switch (aop->type) {
1051 pic16_emitcode ("pop","ar0");
1055 bitVectUnSetBit(ic->rUsed,R0_IDX);
1061 pic16_emitcode ("pop","ar1");
1065 bitVectUnSetBit(ic->rUsed,R1_IDX);
1071 int stk = aop->aopu.aop_stk + aop->size;
1072 bitVectUnSetBit(ic->rUsed,R0_IDX);
1073 bitVectUnSetBit(ic->rUsed,R1_IDX);
1075 getFreePtr(ic,&aop,FALSE);
1077 if (options.stack10bit)
1079 /* I'm not sure what to do here yet... */
1082 "*** Warning: probably generating bad code for "
1083 "10 bit stack mode.\n");
1087 pic16_emitcode ("mov","a,_bp");
1088 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1089 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1091 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1095 pic16_emitcode("pop","acc");
1096 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1098 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1101 pic16_freeAsmop(op,NULL,ic,TRUE);
1103 pic16_emitcode("pop","ar0");
1108 pic16_emitcode("pop","ar1");
1116 /* all other cases just dealloc */
1120 OP_SYMBOL(op)->aop = NULL;
1121 /* if the symbol has a spill */
1123 SPIL_LOC(op)->aop = NULL;
1128 /*-----------------------------------------------------------------*/
1129 /* pic16_aopGet - for fetching value of the aop */
1130 /*-----------------------------------------------------------------*/
1131 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1136 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1138 /* offset is greater than size then zero */
1139 if (offset > (aop->size - 1) &&
1140 aop->type != AOP_LIT)
1143 /* depending on type */
1144 switch (aop->type) {
1148 DEBUGpic16_emitcode(";","%d",__LINE__);
1149 /* if we need to increment it */
1150 while (offset > aop->coff) {
1151 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1155 while (offset < aop->coff) {
1156 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1160 aop->coff = offset ;
1162 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1163 return (dname ? "acc" : "a");
1165 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1166 rs = Safe_calloc(1,strlen(s)+1);
1172 DEBUGpic16_emitcode(";","%d",__LINE__);
1173 if (aop->type == AOP_DPTR2)
1178 while (offset > aop->coff) {
1179 pic16_emitcode ("inc","dptr");
1183 while (offset < aop->coff) {
1184 pic16_emitcode("lcall","__decdptr");
1190 pic16_emitcode("clr","a");
1191 pic16_emitcode("movc","a,@a+dptr");
1194 pic16_emitcode("movx","a,@dptr");
1197 if (aop->type == AOP_DPTR2)
1202 return (dname ? "acc" : "a");
1207 sprintf (s,"%s",aop->aopu.aop_immd);
1210 sprintf(s,"(%s >> %d)",
1215 aop->aopu.aop_immd);
1216 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1217 rs = Safe_calloc(1,strlen(s)+1);
1223 sprintf(s,"(%s + %d)",
1226 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1228 sprintf(s,"%s",aop->aopu.aop_dir);
1229 rs = Safe_calloc(1,strlen(s)+1);
1235 // return aop->aopu.aop_reg[offset]->dname;
1237 return aop->aopu.aop_reg[offset]->name;
1240 //pic16_emitcode(";","%d",__LINE__);
1241 return aop->aopu.aop_dir;
1244 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1245 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1247 return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1250 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1251 rs = Safe_calloc(1,strlen(s)+1);
1256 aop->coff = offset ;
1257 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1260 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1262 return aop->aopu.aop_str[offset];
1266 pCodeOp *pcop = aop->aopu.pcop;
1267 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1269 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1270 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1271 sprintf(s,"%s", pcop->name);
1273 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1276 rs = Safe_calloc(1,strlen(s)+1);
1282 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1283 "aopget got unsupported aop->type");
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1290 /*-----------------------------------------------------------------*/
1291 pCodeOp *pic16_popGetTempReg(void)
1296 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1301 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1302 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1303 PCOR(pcop)->r->wasUsed=1;
1304 PCOR(pcop)->r->isFree=0;
1306 /* push value on stack */
1307 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1315 /*-----------------------------------------------------------------*/
1316 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1317 /*-----------------------------------------------------------------*/
1318 void pic16_popReleaseTempReg(pCodeOp *pcop)
1320 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1322 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1323 PCOR(pcop)->r->isFree = 1;
1325 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1328 /*-----------------------------------------------------------------*/
1329 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1330 /*-----------------------------------------------------------------*/
1331 pCodeOp *pic16_popGetLabel(unsigned int key)
1334 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1339 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1342 /*-----------------------------------------------------------------*/
1343 /* pic16_popCopyReg - copy a pcode operator */
1344 /*-----------------------------------------------------------------*/
1345 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1349 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1350 pcor->pcop.type = pc->pcop.type;
1352 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1353 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1355 pcor->pcop.name = NULL;
1358 pcor->rIdx = pc->rIdx;
1361 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1366 /*-----------------------------------------------------------------*/
1367 /* pic16_popGetLit - asm operator to pcode operator conversion */
1368 /*-----------------------------------------------------------------*/
1369 pCodeOp *pic16_popGetLit(unsigned int lit)
1371 return pic16_newpCodeOpLit(lit);
1374 /*-----------------------------------------------------------------*/
1375 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1376 /*-----------------------------------------------------------------*/
1377 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1379 return pic16_newpCodeOpLit2(lit, arg2);
1383 /*-----------------------------------------------------------------*/
1384 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1385 /*-----------------------------------------------------------------*/
1386 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1388 return pic16_newpCodeOpImmd(name, offset,index, 0);
1392 /*-----------------------------------------------------------------*/
1393 /* pic16_popGet - asm operator to pcode operator conversion */
1394 /*-----------------------------------------------------------------*/
1395 pCodeOp *pic16_popGetWithString(char *str)
1401 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1405 pcop = pic16_newpCodeOp(str,PO_STR);
1410 /*-----------------------------------------------------------------*/
1411 /* pic16_popRegFromString - */
1412 /*-----------------------------------------------------------------*/
1413 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1416 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1417 pcop->type = PO_DIR;
1419 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1420 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1425 pcop->name = Safe_calloc(1,strlen(str)+1);
1426 strcpy(pcop->name,str);
1428 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1430 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1431 if(PCOR(pcop)->r == NULL) {
1432 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1433 // __FUNCTION__, __LINE__, str, size, offset);
1434 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1436 //fprintf(stderr, "allocating new register -> %s\n", str);
1438 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1440 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1442 PCOR(pcop)->instance = offset;
1447 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1451 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1453 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1454 PCOR(pcop)->rIdx = rIdx;
1455 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1456 PCOR(pcop)->r->isFree = 0;
1457 PCOR(pcop)->r->wasUsed = 1;
1459 pcop->type = PCOR(pcop)->r->pc_type;
1464 /*---------------------------------------------------------------------------------*/
1465 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1467 /*---------------------------------------------------------------------------------*/
1468 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1473 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1475 /* comment the following check, so errors to throw up */
1476 // if(!pcop2)return NULL;
1478 temp = pic16_popGet(aop_dst, offset);
1479 pcop2->pcop2 = temp;
1486 /*--------------------------------------------------------------------------------.-*/
1487 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1488 /* VR 030601 , adapted by Hans Dorn */
1489 /*--------------------------------------------------------------------------------.-*/
1490 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1494 pcop2 = (pCodeOpReg2 *)src;
1502 /*---------------------------------------------------------------------------------*/
1503 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1504 /* movff instruction */
1505 /*---------------------------------------------------------------------------------*/
1506 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1511 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1512 pcop2->pcop2 = pic16_popCopyReg(dst);
1514 /* the pCodeOp may be already allocated */
1515 pcop2 = (pCodeOpReg2 *)(src);
1516 pcop2->pcop2 = (pCodeOp *)(dst);
1523 /*-----------------------------------------------------------------*/
1524 /* pic16_popGet - asm operator to pcode operator conversion */
1525 /*-----------------------------------------------------------------*/
1526 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1528 //char *s = buffer ;
1532 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1533 /* offset is greater than
1536 // if (offset > (aop->size - 1) &&
1537 // aop->type != AOP_LIT)
1538 // return NULL; //zero;
1540 /* depending on type */
1541 switch (aop->type) {
1547 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1548 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1555 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1556 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1560 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1562 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1564 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1566 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1567 PCOR(pcop)->rIdx = rIdx;
1568 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1569 PCOR(pcop)->r->wasUsed=1;
1570 PCOR(pcop)->r->isFree=0;
1572 PCOR(pcop)->instance = offset;
1573 pcop->type = PCOR(pcop)->r->pc_type;
1574 // rs = aop->aopu.aop_reg[offset]->name;
1575 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1579 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1580 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1586 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1587 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1591 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1593 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1595 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1596 PCOR(pcop)->rIdx = rIdx;
1597 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1598 PCOR(pcop)->r->wasUsed=1;
1599 PCOR(pcop)->r->isFree=0;
1601 PCOR(pcop)->instance = offset;
1602 pcop->type = PCOR(pcop)->r->pc_type;
1603 rs = aop->aopu.aop_reg[offset]->name;
1604 DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1609 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1611 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1612 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1613 //if(PCOR(pcop)->r == NULL)
1614 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1618 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1619 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1622 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1623 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1626 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1627 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1628 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1629 pcop->type = PCOR(pcop)->r->pc_type;
1630 pcop->name = PCOR(pcop)->r->name;
1636 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1638 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1639 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1641 switch( aop->aopu.pcop->type ) {
1642 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1643 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1645 assert( 0 ); /* should never reach here */;
1648 PCOI(pcop)->offset = offset;
1653 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1654 "pic16_popGet got unsupported aop->type");
1657 /*-----------------------------------------------------------------*/
1658 /* pic16_aopPut - puts a string for a aop */
1659 /*-----------------------------------------------------------------*/
1660 void pic16_aopPut (asmop *aop, char *s, int offset)
1665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1667 if (aop->size && offset > ( aop->size - 1)) {
1668 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1669 "pic16_aopPut got offset > aop->size");
1673 /* will assign value to value */
1674 /* depending on where it is ofcourse */
1675 switch (aop->type) {
1678 sprintf(d,"(%s + %d)",
1679 aop->aopu.aop_dir,offset);
1680 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1683 sprintf(d,"%s",aop->aopu.aop_dir);
1686 DEBUGpic16_emitcode(";","%d",__LINE__);
1688 pic16_emitcode("movf","%s,w",s);
1689 pic16_emitcode("movwf","%s",d);
1692 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1693 if(offset >= aop->size) {
1694 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1697 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1700 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1707 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1708 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1711 strcmp(s,"r0") == 0 ||
1712 strcmp(s,"r1") == 0 ||
1713 strcmp(s,"r2") == 0 ||
1714 strcmp(s,"r3") == 0 ||
1715 strcmp(s,"r4") == 0 ||
1716 strcmp(s,"r5") == 0 ||
1717 strcmp(s,"r6") == 0 ||
1718 strcmp(s,"r7") == 0 )
1719 pic16_emitcode("mov","%s,%s ; %d",
1720 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1724 if(strcmp(s,"W")==0 )
1725 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1727 pic16_emitcode("movwf","%s",
1728 aop->aopu.aop_reg[offset]->name);
1730 if(strcmp(s,zero)==0) {
1731 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1733 } else if(strcmp(s,"W")==0) {
1734 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1735 pcop->type = PO_GPR_REGISTER;
1737 PCOR(pcop)->rIdx = -1;
1738 PCOR(pcop)->r = NULL;
1740 DEBUGpic16_emitcode(";","%d",__LINE__);
1741 pcop->name = Safe_strdup(s);
1742 pic16_emitpcode(POC_MOVFW,pcop);
1743 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1744 } else if(strcmp(s,one)==0) {
1745 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1746 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1748 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1756 if (aop->type == AOP_DPTR2)
1762 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1763 "pic16_aopPut writting to code space");
1767 while (offset > aop->coff) {
1769 pic16_emitcode ("inc","dptr");
1772 while (offset < aop->coff) {
1774 pic16_emitcode("lcall","__decdptr");
1779 /* if not in accumulater */
1782 pic16_emitcode ("movx","@dptr,a");
1784 if (aop->type == AOP_DPTR2)
1792 while (offset > aop->coff) {
1794 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1796 while (offset < aop->coff) {
1798 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1804 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1809 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1811 if (strcmp(s,"r0") == 0 ||
1812 strcmp(s,"r1") == 0 ||
1813 strcmp(s,"r2") == 0 ||
1814 strcmp(s,"r3") == 0 ||
1815 strcmp(s,"r4") == 0 ||
1816 strcmp(s,"r5") == 0 ||
1817 strcmp(s,"r6") == 0 ||
1818 strcmp(s,"r7") == 0 ) {
1820 sprintf(buffer,"a%s",s);
1821 pic16_emitcode("mov","@%s,%s",
1822 aop->aopu.aop_ptr->name,buffer);
1824 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1829 if (strcmp(s,"a") == 0)
1830 pic16_emitcode("push","acc");
1832 pic16_emitcode("push","%s",s);
1837 /* if bit variable */
1838 if (!aop->aopu.aop_dir) {
1839 pic16_emitcode("clr","a");
1840 pic16_emitcode("rlc","a");
1843 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1846 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1849 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1851 lbl = newiTempLabel(NULL);
1853 if (strcmp(s,"a")) {
1856 pic16_emitcode("clr","c");
1857 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1858 pic16_emitcode("cpl","c");
1859 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1860 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1867 if (strcmp(aop->aopu.aop_str[offset],s))
1868 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1873 if (!offset && (strcmp(s,"acc") == 0))
1876 if (strcmp(aop->aopu.aop_str[offset],s))
1877 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1881 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1882 "pic16_aopPut got unsupported aop->type");
1888 /*-----------------------------------------------------------------*/
1889 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1890 /*-----------------------------------------------------------------*/
1891 static void mov2w (asmop *aop, int offset)
1897 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1899 if ( aop->type == AOP_PCODE ||
1900 aop->type == AOP_LIT )
1901 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1903 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1908 /* push pcop into stack */
1909 void pic16_pushpCodeOp(pCodeOp *pcop)
1911 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1915 /* pop pcop from stack */
1916 void pic16_poppCodeOp(pCodeOp *pcop)
1918 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1922 /*-----------------------------------------------------------------*/
1923 /* pushw - pushes wreg to stack */
1924 /*-----------------------------------------------------------------*/
1927 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1928 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1932 /*-----------------------------------------------------------------*/
1933 /* pushaop - pushes aop to stack */
1934 /*-----------------------------------------------------------------*/
1935 void pushaop(asmop *aop, int offset)
1937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1938 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1941 /*-----------------------------------------------------------------*/
1942 /* popaop - pops aop from stack */
1943 /*-----------------------------------------------------------------*/
1944 void popaop(asmop *aop, int offset)
1946 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1947 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1950 void popaopidx(asmop *aop, int offset, int index)
1954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1956 if(STACK_MODEL_LARGE)ofs++;
1958 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1959 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1962 /*-----------------------------------------------------------------*/
1963 /* reAdjustPreg - points a register back to where it should */
1964 /*-----------------------------------------------------------------*/
1965 static void reAdjustPreg (asmop *aop)
1969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1971 if ((size = aop->size) <= 1)
1974 switch (aop->type) {
1978 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1982 if (aop->type == AOP_DPTR2)
1988 pic16_emitcode("lcall","__decdptr");
1991 if (aop->type == AOP_DPTR2)
2003 /*-----------------------------------------------------------------*/
2004 /* opIsGptr: returns non-zero if the passed operand is */
2005 /* a generic pointer type. */
2006 /*-----------------------------------------------------------------*/
2007 static int opIsGptr(operand *op)
2009 sym_link *type = operandType(op);
2011 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2012 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2020 /*-----------------------------------------------------------------*/
2021 /* pic16_getDataSize - get the operand data size */
2022 /*-----------------------------------------------------------------*/
2023 int pic16_getDataSize(operand *op)
2025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2028 return AOP_SIZE(op);
2030 // tsd- in the pic port, the genptr size is 1, so this code here
2031 // fails. ( in the 8051 port, the size was 4).
2034 size = AOP_SIZE(op);
2035 if (size == GPTRSIZE)
2037 sym_link *type = operandType(op);
2038 if (IS_GENPTR(type))
2040 /* generic pointer; arithmetic operations
2041 * should ignore the high byte (pointer type).
2044 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2051 /*-----------------------------------------------------------------*/
2052 /* pic16_outAcc - output Acc */
2053 /*-----------------------------------------------------------------*/
2054 void pic16_outAcc(operand *result)
2057 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2058 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2061 size = pic16_getDataSize(result);
2063 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2066 /* unsigned or positive */
2068 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2073 /*-----------------------------------------------------------------*/
2074 /* pic16_outBitC - output a bit C */
2075 /*-----------------------------------------------------------------*/
2076 void pic16_outBitC(operand *result)
2079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2080 /* if the result is bit */
2081 if (AOP_TYPE(result) == AOP_CRY)
2082 pic16_aopPut(AOP(result),"c",0);
2084 pic16_emitcode("clr","a ; %d", __LINE__);
2085 pic16_emitcode("rlc","a");
2086 pic16_outAcc(result);
2090 /*-----------------------------------------------------------------*/
2091 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2092 /*-----------------------------------------------------------------*/
2093 void pic16_toBoolean(operand *oper)
2095 int size = AOP_SIZE(oper) - 1;
2098 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 if ( AOP_TYPE(oper) != AOP_ACC) {
2101 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2104 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2109 #if !defined(GEN_Not)
2110 /*-----------------------------------------------------------------*/
2111 /* genNot - generate code for ! operation */
2112 /*-----------------------------------------------------------------*/
2113 static void pic16_genNot (iCode *ic)
2118 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2119 /* assign asmOps to operand & result */
2120 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2121 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2123 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2124 /* if in bit space then a special case */
2125 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2126 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2127 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2128 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2130 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2131 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2132 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2137 size = AOP_SIZE(IC_LEFT(ic));
2139 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2140 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2141 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2144 pic16_toBoolean(IC_LEFT(ic));
2146 tlbl = newiTempLabel(NULL);
2147 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2148 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2149 pic16_outBitC(IC_RESULT(ic));
2152 /* release the aops */
2153 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2154 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2159 #if !defined(GEN_Cpl)
2160 /*-----------------------------------------------------------------*/
2161 /* genCpl - generate code for complement */
2162 /*-----------------------------------------------------------------*/
2163 static void pic16_genCpl (iCode *ic)
2169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2170 /* assign asmOps to operand & result */
2171 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2172 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2174 /* if both are in bit space then
2176 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2177 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2179 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2180 pic16_emitcode("cpl","c");
2181 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2185 size = AOP_SIZE(IC_RESULT(ic));
2188 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2190 pic16_emitcode("cpl","a");
2191 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2193 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2194 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2196 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2197 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2205 /* release the aops */
2206 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2207 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2211 /*-----------------------------------------------------------------*/
2212 /* genUminusFloat - unary minus for floating points */
2213 /*-----------------------------------------------------------------*/
2214 static void genUminusFloat(operand *op,operand *result)
2216 int size ,offset =0 ;
2219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2220 /* for this we just need to flip the
2221 first it then copy the rest in place */
2222 size = AOP_SIZE(op) - 1;
2223 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2227 pic16_emitcode("cpl","acc.7");
2228 pic16_aopPut(AOP(result),"a",3);
2231 pic16_aopPut(AOP(result),
2232 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2238 /*-----------------------------------------------------------------*/
2239 /* genUminus - unary minus code generation */
2240 /*-----------------------------------------------------------------*/
2241 static void genUminus (iCode *ic)
2244 sym_link *optype, *rtype;
2247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2249 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2250 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2252 /* if both in bit space then special
2254 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2255 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2257 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2258 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2259 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2264 optype = operandType(IC_LEFT(ic));
2265 rtype = operandType(IC_RESULT(ic));
2267 /* if float then do float stuff */
2268 if (IS_FLOAT(optype)) {
2269 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2273 /* otherwise subtract from zero by taking the 2's complement */
2274 size = AOP_SIZE(IC_LEFT(ic));
2276 for(i=0; i<size; i++) {
2277 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2278 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2280 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2285 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2286 for(i=1; i<size; i++) {
2288 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2292 /* release the aops */
2293 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2294 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2297 /*-----------------------------------------------------------------*/
2298 /* saveRegisters - will look for a call and save the registers */
2299 /*-----------------------------------------------------------------*/
2300 static void saveRegisters(iCode *lic)
2307 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2309 for (ic = lic ; ic ; ic = ic->next)
2310 if (ic->op == CALL || ic->op == PCALL)
2314 fprintf(stderr,"found parameter push with no function call\n");
2318 /* if the registers have been saved already then
2320 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2323 /* find the registers in use at this time
2324 and push them away to safety */
2325 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2329 if (options.useXstack) {
2330 if (bitVectBitValue(rsave,R0_IDX))
2331 pic16_emitcode("mov","b,r0");
2332 pic16_emitcode("mov","r0,%s",spname);
2333 for (i = 0 ; i < pic16_nRegs ; i++) {
2334 if (bitVectBitValue(rsave,i)) {
2336 pic16_emitcode("mov","a,b");
2338 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2339 pic16_emitcode("movx","@r0,a");
2340 pic16_emitcode("inc","r0");
2343 pic16_emitcode("mov","%s,r0",spname);
2344 if (bitVectBitValue(rsave,R0_IDX))
2345 pic16_emitcode("mov","r0,b");
2347 //for (i = 0 ; i < pic16_nRegs ; i++) {
2348 // if (bitVectBitValue(rsave,i))
2349 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2352 dtype = operandType(IC_LEFT(ic));
2353 if (currFunc && dtype &&
2354 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2355 IFFUNC_ISISR(currFunc->type) &&
2358 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2361 /*-----------------------------------------------------------------*/
2362 /* unsaveRegisters - pop the pushed registers */
2363 /*-----------------------------------------------------------------*/
2364 static void unsaveRegisters (iCode *ic)
2369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2370 /* find the registers in use at this time
2371 and push them away to safety */
2372 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2375 if (options.useXstack) {
2376 pic16_emitcode("mov","r0,%s",spname);
2377 for (i = pic16_nRegs ; i >= 0 ; i--) {
2378 if (bitVectBitValue(rsave,i)) {
2379 pic16_emitcode("dec","r0");
2380 pic16_emitcode("movx","a,@r0");
2382 pic16_emitcode("mov","b,a");
2384 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2388 pic16_emitcode("mov","%s,r0",spname);
2389 if (bitVectBitValue(rsave,R0_IDX))
2390 pic16_emitcode("mov","r0,b");
2392 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2393 // if (bitVectBitValue(rsave,i))
2394 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2400 /*-----------------------------------------------------------------*/
2402 /*-----------------------------------------------------------------*/
2403 static void pushSide(operand * oper, int size)
2406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2408 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2409 if (AOP_TYPE(oper) != AOP_REG &&
2410 AOP_TYPE(oper) != AOP_DIR &&
2412 pic16_emitcode("mov","a,%s",l);
2413 pic16_emitcode("push","acc");
2415 pic16_emitcode("push","%s",l);
2420 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2422 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2424 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2425 pic16_emitpcode(POC_MOVFW, src);
2426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2428 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2429 src, pic16_popGet(AOP(op), offset)));
2434 /*-----------------------------------------------------------------*/
2435 /* assignResultValue - assign results to oper, rescall==1 is */
2436 /* called from genCall() or genPCall() */
2437 /*-----------------------------------------------------------------*/
2438 static void assignResultValue(operand * oper, int rescall)
2440 int size = AOP_SIZE(oper);
2442 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2443 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2446 /* assign result from a call/pcall function() */
2448 /* function results are stored in a special order,
2449 * see top of file with Function return policy, or manual */
2452 /* 8-bits, result in WREG */
2453 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2456 /* 16-bits, result in PRODL:WREG */
2457 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2461 /* 24-bits, result in PRODH:PRODL:WREG */
2462 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2466 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2467 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2470 /* >32-bits, result on stack, and FSR0 points to beginning.
2471 * Fix stack when done */
2474 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2475 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2477 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2482 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2483 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2484 if(STACK_MODEL_LARGE) {
2486 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2490 if(!GpsuedoStkPtr) {
2491 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2492 /* The last byte in the assignment is in W */
2494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2499 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2500 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2502 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2510 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2520 /*-----------------------------------------------------------------*/
2521 /* genIpush - genrate code for pushing this gets a little complex */
2522 /*-----------------------------------------------------------------*/
2523 static void genIpush (iCode *ic)
2526 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2528 int size, offset = 0 ;
2532 /* if this is not a parm push : ie. it is spill push
2533 and spill push is always done on the local stack */
2534 if (!ic->parmPush) {
2536 /* and the item is spilt then do nothing */
2537 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2540 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2541 size = AOP_SIZE(IC_LEFT(ic));
2542 /* push it on the stack */
2544 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2549 pic16_emitcode("push","%s",l);
2554 /* this is a paramter push: in this case we call
2555 the routine to find the call and save those
2556 registers that need to be saved */
2559 /* then do the push */
2560 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2563 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2564 size = AOP_SIZE(IC_LEFT(ic));
2567 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2568 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2569 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2571 pic16_emitcode("mov","a,%s",l);
2572 pic16_emitcode("push","acc");
2574 pic16_emitcode("push","%s",l);
2577 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2581 /*-----------------------------------------------------------------*/
2582 /* genIpop - recover the registers: can happen only for spilling */
2583 /*-----------------------------------------------------------------*/
2584 static void genIpop (iCode *ic)
2586 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2591 /* if the temp was not pushed then */
2592 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2595 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2596 size = AOP_SIZE(IC_LEFT(ic));
2599 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2602 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2606 /*-----------------------------------------------------------------*/
2607 /* unsaverbank - restores the resgister bank from stack */
2608 /*-----------------------------------------------------------------*/
2609 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2611 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2617 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2619 if (options.useXstack) {
2621 r = getFreePtr(ic,&aop,FALSE);
2624 pic16_emitcode("mov","%s,_spx",r->name);
2625 pic16_emitcode("movx","a,@%s",r->name);
2626 pic16_emitcode("mov","psw,a");
2627 pic16_emitcode("dec","%s",r->name);
2630 pic16_emitcode ("pop","psw");
2633 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2634 if (options.useXstack) {
2635 pic16_emitcode("movx","a,@%s",r->name);
2636 //pic16_emitcode("mov","(%s+%d),a",
2637 // regspic16[i].base,8*bank+regspic16[i].offset);
2638 pic16_emitcode("dec","%s",r->name);
2641 pic16_emitcode("pop",""); //"(%s+%d)",
2642 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2645 if (options.useXstack) {
2647 pic16_emitcode("mov","_spx,%s",r->name);
2648 pic16_freeAsmop(NULL,aop,ic,TRUE);
2654 /*-----------------------------------------------------------------*/
2655 /* saverbank - saves an entire register bank on the stack */
2656 /*-----------------------------------------------------------------*/
2657 static void saverbank (int bank, iCode *ic, bool pushPsw)
2659 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2666 if (options.useXstack) {
2669 r = getFreePtr(ic,&aop,FALSE);
2670 pic16_emitcode("mov","%s,_spx",r->name);
2674 for (i = 0 ; i < pic16_nRegs ;i++) {
2675 if (options.useXstack) {
2676 pic16_emitcode("inc","%s",r->name);
2677 //pic16_emitcode("mov","a,(%s+%d)",
2678 // regspic16[i].base,8*bank+regspic16[i].offset);
2679 pic16_emitcode("movx","@%s,a",r->name);
2681 pic16_emitcode("push","");// "(%s+%d)",
2682 //regspic16[i].base,8*bank+regspic16[i].offset);
2686 if (options.useXstack) {
2687 pic16_emitcode("mov","a,psw");
2688 pic16_emitcode("movx","@%s,a",r->name);
2689 pic16_emitcode("inc","%s",r->name);
2690 pic16_emitcode("mov","_spx,%s",r->name);
2691 pic16_freeAsmop (NULL,aop,ic,TRUE);
2694 pic16_emitcode("push","psw");
2696 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2704 /*-----------------------------------------------------------------*/
2705 /* genCall - generates a call statement */
2706 /*-----------------------------------------------------------------*/
2707 static void genCall (iCode *ic)
2712 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2714 /* if caller saves & we have not saved then */
2718 /* if we are calling a function that is not using
2719 * the same register bank then we need to save the
2720 * destination registers on the stack */
2721 dtype = operandType(IC_LEFT(ic));
2722 if (currFunc && dtype &&
2723 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2724 IFFUNC_ISISR(currFunc->type) &&
2727 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2729 /* if send set is not empty the assign */
2733 /* For the Pic port, there is no data stack.
2734 * So parameters passed to functions are stored
2735 * in registers. (The pCode optimizer will get
2736 * rid of most of these :). */
2738 int psuedoStkPtr=-1;
2739 int firstTimeThruLoop = 1;
2741 _G.sendSet = reverseSet(_G.sendSet);
2743 /* First figure how many parameters are getting passed */
2744 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2745 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2746 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2747 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2750 stackParms = psuedoStkPtr;
2752 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2753 int size, offset = 0;
2755 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2756 size = AOP_SIZE(IC_LEFT(sic));
2759 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2760 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2761 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2763 if(!firstTimeThruLoop) {
2764 /* If this is not the first time we've been through the loop
2765 * then we need to save the parameter in a temporary
2766 * register. The last byte of the last parameter is
2770 --psuedoStkPtr; // sanity check
2773 firstTimeThruLoop=0;
2775 mov2w (AOP(IC_LEFT(sic)), offset);
2778 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2784 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2785 OP_SYMBOL(IC_LEFT(ic))->rname :
2786 OP_SYMBOL(IC_LEFT(ic))->name));
2789 /* if we need assign a result value */
2790 if ((IS_ITEMP(IC_RESULT(ic)) &&
2791 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2792 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2793 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2796 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2799 assignResultValue(IC_RESULT(ic), 1);
2801 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2802 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2804 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2808 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2809 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2810 if(STACK_MODEL_LARGE) {
2812 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2816 /* adjust the stack for parameters if required */
2817 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2819 if (ic->parmBytes) {
2822 if (ic->parmBytes > 3) {
2823 pic16_emitcode("mov","a,%s",spname);
2824 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2825 pic16_emitcode("mov","%s,a",spname);
2827 for ( i = 0 ; i < ic->parmBytes ;i++)
2828 pic16_emitcode("dec","%s",spname);
2832 /* if register bank was saved then pop them */
2834 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2836 /* if we hade saved some registers then unsave them */
2837 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2838 unsaveRegisters (ic);
2844 /*-----------------------------------------------------------------*/ // patch 14
2845 /* genPcall - generates a call by pointer statement */
2846 /*-----------------------------------------------------------------*/
2848 // new version, created from genCall
2850 static void genPcall (iCode *ic)
2854 symbol *retlbl = newiTempLabel(NULL);
2855 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
2857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2859 /* if caller saves & we have not saved then */
2863 /* if we are calling a function that is not using
2864 * the same register bank then we need to save the
2865 * destination registers on the stack */
2866 dtype = operandType(IC_LEFT(ic));
2867 if (currFunc && dtype &&
2868 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2869 IFFUNC_ISISR(currFunc->type) &&
2872 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2874 /* if send set is not empty the assign */
2878 /* For the Pic port, there is no data stack.
2879 * So parameters passed to functions are stored
2880 * in registers. (The pCode optimizer will get
2881 * rid of most of these :). */
2883 int psuedoStkPtr=-1;
2884 int firstTimeThruLoop = 1;
2886 _G.sendSet = reverseSet(_G.sendSet);
2888 /* First figure how many parameters are getting passed */
2889 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2890 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2891 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2892 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2895 stackParms = psuedoStkPtr;
2897 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2898 int size, offset = 0;
2900 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2901 size = AOP_SIZE(IC_LEFT(sic));
2904 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2905 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2906 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2908 if(!firstTimeThruLoop) {
2909 /* If this is not the first time we've been through the loop
2910 * then we need to save the parameter in a temporary
2911 * register. The last byte of the last parameter is
2915 --psuedoStkPtr; // sanity check
2918 firstTimeThruLoop=0;
2920 mov2w (AOP(IC_LEFT(sic)), offset);
2923 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2928 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2930 // push return address
2931 // push $ on return stack, then replace with retlbl
2933 // Note: retlbl is supplied as dummy operand to PUSH
2934 // This has the nice side effect of keeping the label from being optimized out :o)
2935 pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key));
2937 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
2938 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
2939 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
2940 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
2941 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
2942 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
2944 /* make the call by writing the pointer into pc */
2945 // FIXME Disabled writes to PCLATU because of gpsim problems
2947 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
2950 "WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
2951 Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
2954 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
2955 // note: MOVFF to PCL not allowed
2956 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
2957 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
2959 /* return address is here: (X) */
2960 pic16_emitpLabel(retlbl->key);
2962 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2965 /* if we need assign a result value */
2966 if ((IS_ITEMP(IC_RESULT(ic)) &&
2967 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2968 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2969 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2972 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2975 assignResultValue(IC_RESULT(ic), 1);
2977 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2978 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2980 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2984 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2985 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2986 if(STACK_MODEL_LARGE) {
2988 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2992 /* adjust the stack for parameters if required */
2993 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2995 if (ic->parmBytes) {
2998 if (ic->parmBytes > 3) {
2999 pic16_emitcode("mov","a,%s",spname);
3000 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3001 pic16_emitcode("mov","%s,a",spname);
3003 for ( i = 0 ; i < ic->parmBytes ;i++)
3004 pic16_emitcode("dec","%s",spname);
3007 /* if register bank was saved then pop them */
3009 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3011 /* if we hade saved some registers then unsave them */
3012 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3013 unsaveRegisters (ic);
3018 // old version, kept for reference
3020 /*-----------------------------------------------------------------*/
3021 /* genPcall - generates a call by pointer statement */
3022 /*-----------------------------------------------------------------*/
3023 static void genPcall (iCode *ic)
3026 symbol *rlbl = newiTempLabel(NULL);
3029 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3030 /* if caller saves & we have not saved then */
3034 /* if we are calling a function that is not using
3035 the same register bank then we need to save the
3036 destination registers on the stack */
3037 dtype = operandType(IC_LEFT(ic));
3038 if (currFunc && dtype &&
3039 IFFUNC_ISISR(currFunc->type) &&
3040 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3041 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3044 /* push the return address on to the stack */
3045 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
3046 pic16_emitcode("push","acc");
3047 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
3048 pic16_emitcode("push","acc");
3050 if (options.model == MODEL_FLAT24)
3052 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
3053 pic16_emitcode("push","acc");
3056 /* now push the calling address */
3057 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3059 pushSide(IC_LEFT(ic), FPTRSIZE);
3061 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3063 /* if send set is not empty the assign */
3067 for (sic = setFirstItem(_G.sendSet) ; sic ;
3068 sic = setNextItem(_G.sendSet)) {
3069 int size, offset = 0;
3070 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3071 size = AOP_SIZE(IC_LEFT(sic));
3073 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
3075 if (strcmp(l,fReturn[offset]))
3076 pic16_emitcode("mov","%s,%s",
3081 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3086 pic16_emitcode("ret","");
3087 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
3090 /* if we need assign a result value */
3091 if ((IS_ITEMP(IC_RESULT(ic)) &&
3092 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3093 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
3094 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3097 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3100 assignResultValue(IC_RESULT(ic), 1);
3102 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3105 /* adjust the stack for parameters if
3107 if (ic->parmBytes) {
3109 if (ic->parmBytes > 3) {
3110 pic16_emitcode("mov","a,%s",spname);
3111 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3112 pic16_emitcode("mov","%s,a",spname);
3114 for ( i = 0 ; i < ic->parmBytes ;i++)
3115 pic16_emitcode("dec","%s",spname);
3119 /* if register bank was saved then unsave them */
3120 if (currFunc && dtype &&
3121 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3122 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3124 /* if we hade saved some registers then
3127 unsaveRegisters (ic);
3133 /*-----------------------------------------------------------------*/
3134 /* resultRemat - result is rematerializable */
3135 /*-----------------------------------------------------------------*/
3136 static int resultRemat (iCode *ic)
3138 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3139 if (SKIP_IC(ic) || ic->op == IFX)
3142 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3143 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3144 if (sym->remat && !POINTER_SET(ic))
3151 #if defined(__BORLANDC__) || defined(_MSC_VER)
3152 #define STRCASECMP stricmp
3154 #define STRCASECMP strcasecmp
3158 /*-----------------------------------------------------------------*/
3159 /* inExcludeList - return 1 if the string is in exclude Reg list */
3160 /*-----------------------------------------------------------------*/
3161 static bool inExcludeList(char *s)
3163 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3167 if (options.excludeRegs[i] &&
3168 STRCASECMP(options.excludeRegs[i],"none") == 0)
3171 for ( i = 0 ; options.excludeRegs[i]; i++) {
3172 if (options.excludeRegs[i] &&
3173 STRCASECMP(s,options.excludeRegs[i]) == 0)
3180 /*-----------------------------------------------------------------*/
3181 /* genFunction - generated code for function entry */
3182 /*-----------------------------------------------------------------*/
3183 static void genFunction (iCode *ic)
3188 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
3190 labelOffset += (max_key+4);
3195 ftype = operandType(IC_LEFT(ic));
3196 sym = OP_SYMBOL(IC_LEFT(ic));
3198 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3199 /* create an absolute section at the interrupt vector:
3200 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3208 sym = OP_SYMBOL( IC_LEFT(ic));
3210 if(interrupts[i]->name
3211 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3218 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3219 __FILE__, __LINE__, sym->name);
3222 _G.interruptvector = found;
3225 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3226 asym = newSymbol(asymname, 0);
3228 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3229 pic16_addpBlock( apb );
3231 pic16_addpCode2pBlock(apb,
3232 pic16_newpCodeCharP(";-----------------------------------------"));
3235 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3237 pic16_addpCode2pBlock(apb,
3238 pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3240 /* mark the end of this tiny function */
3241 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3246 abSym = Safe_calloc(1, sizeof(absSym));
3247 abSym->name = Safe_strdup( asymname );
3249 switch( _G.interruptvector ) {
3250 case 0: abSym->address = 0x000000; break;
3251 case 1: abSym->address = 0x000008; break;
3252 case 2: abSym->address = 0x000018; break;
3255 addSet(&absSymSet, abSym);
3260 /* create the function header */
3261 pic16_emitcode(";","-----------------------------------------");
3262 pic16_emitcode(";"," function %s",sym->name);
3263 pic16_emitcode(";","-----------------------------------------");
3265 pic16_emitcode("","%s:",sym->rname);
3266 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3272 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3273 if(!strcmp(ab->name, sym->name)) {
3274 pic16_pBlockConvert2Absolute(pb);
3281 if(IFFUNC_ISNAKED(ftype)) {
3282 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3286 /* if critical function then turn interrupts off */
3287 if (IFFUNC_ISCRITICAL(ftype))
3288 pic16_emitcode("clr","ea");
3290 /* if this is an interrupt service routine then
3291 * save acc, b, dpl, dph */
3292 if (IFFUNC_ISISR(sym->type)) {
3294 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3295 if(!(_G.interruptvector == 1)) {
3297 /* do not save WREG,STATUS,BSR for high priority interrupts
3298 * because they are stored in the hardware shadow registers already */
3300 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3301 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3302 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3305 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3306 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3307 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3308 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3310 // pic16_pBlockConvert2ISR(pb);
3312 /* if any registers used */
3313 if (sym->regsUsed) {
3314 /* save the registers used */
3315 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3316 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3317 if (bitVectBitValue(sym->regsUsed,i)) {
3318 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3319 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3320 // pic16_regWithIdx(i)->name);
3322 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3328 /* emit code to setup stack frame if user enabled,
3329 * and function is not main() */
3331 // fprintf(stderr, "function name: %s\n", sym->name);
3332 if(strcmp(sym->name, "main")) {
3333 if(/*!options.ommitFramePtr || */sym->regsUsed) {
3334 /* setup the stack frame */
3335 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3336 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3337 if(STACK_MODEL_LARGE)
3338 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3342 /* if callee-save to be used for this function
3343 * then save the registers being used in this function */
3344 // if (IFFUNC_CALLEESAVES(sym->type))
3348 // fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
3350 // pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3352 /* if any registers used */
3353 if (sym->regsUsed) {
3354 /* save the registers used */
3355 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3356 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3357 if (bitVectBitValue(sym->regsUsed,i)) {
3359 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3360 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3361 // pic16_regWithIdx(i)->name);
3363 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3365 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3366 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3367 // &pic16_pc_postdec1, 0));
3379 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3381 if (options.useXstack) {
3382 pic16_emitcode("mov","r0,%s",spname);
3383 pic16_emitcode("mov","a,_bp");
3384 pic16_emitcode("movx","@r0,a");
3385 pic16_emitcode("inc","%s",spname);
3387 /* set up the stack */
3388 pic16_emitcode ("push","_bp"); /* save the callers stack */
3390 pic16_emitcode ("mov","_bp,%s",spname);
3393 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3395 /* adjust the stack for the function */
3400 werror(W_STACK_OVERFLOW,sym->name);
3402 if (i > 3 && sym->recvSize < 4) {
3403 pic16_emitcode ("mov","a,sp");
3404 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3405 pic16_emitcode ("mov","sp,a");
3408 pic16_emitcode("inc","sp");
3412 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3414 pic16_emitcode ("mov","a,_spx");
3415 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3416 pic16_emitcode ("mov","_spx,a");
3421 /*-----------------------------------------------------------------*/
3422 /* genEndFunction - generates epilogue for functions */
3423 /*-----------------------------------------------------------------*/
3424 static void genEndFunction (iCode *ic)
3426 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3430 if(IFFUNC_ISNAKED(sym->type)) {
3431 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3436 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3438 pic16_emitcode ("mov","%s,_bp",spname);
3442 /* if use external stack but some variables were
3443 added to the local stack then decrement the
3445 if (options.useXstack && sym->stack) {
3446 pic16_emitcode("mov","a,sp");
3447 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3448 pic16_emitcode("mov","sp,a");
3453 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3454 if (options.useXstack) {
3455 pic16_emitcode("mov","r0,%s",spname);
3456 pic16_emitcode("movx","a,@r0");
3457 pic16_emitcode("mov","_bp,a");
3458 pic16_emitcode("dec","%s",spname);
3462 pic16_emitcode ("pop","_bp");
3467 if (IFFUNC_ISISR(sym->type)) {
3468 /* now we need to restore the registers */
3469 /* if any registers used */
3470 if (sym->regsUsed) {
3473 /* restore registers used */
3474 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3475 for ( i = sym->regsUsed->size; i >= 0; i--) {
3476 if (bitVectBitValue(sym->regsUsed,i)) {
3478 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3479 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3480 // pic16_regWithIdx(i)->name);
3482 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3484 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3485 // &pic16_pc_preinc1,
3486 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3492 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3493 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3494 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3495 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3497 if(!(_G.interruptvector == 1)) {
3498 /* do not restore interrupt vector for WREG,STATUS,BSR
3499 * for high priority interrupt, see genFunction */
3501 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3502 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3503 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3506 _G.interruptvector = 0; /* sanity check */
3508 // pic16_pBlockConvert2ISR(pb);
3511 /* if debug then send end of function */
3512 /* if (options.debug && currFunc) */
3515 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3516 FileBaseName(ic->filename),currFunc->lastLine,
3517 ic->level,ic->block);
3518 if (IS_STATIC(currFunc->etype))
3519 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3521 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3525 pic16_emitpcodeNULLop(POC_RETFIE);
3527 if (IFFUNC_ISCRITICAL(sym->type))
3528 pic16_emitcode("setb","ea");
3531 // pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3533 /* if any registers used */
3534 if (sym->regsUsed) {
3536 /* save the registers used */
3537 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3538 for ( i = sym->regsUsed->size; i >= 0; i--) {
3539 if (bitVectBitValue(sym->regsUsed,i)) {
3541 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3542 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3543 // pic16_regWithIdx(i)->name);
3545 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3547 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3548 // &pic16_pc_preinc1,
3549 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3556 pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
3557 /* if debug then send end of function */
3560 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3561 FileBaseName(ic->filename),currFunc->lastLine,
3562 ic->level,ic->block);
3563 if (IS_STATIC(currFunc->etype))
3564 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3566 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3570 /* insert code to restore stack frame, if user enabled it
3571 * and function is not main() */
3574 if(strcmp(sym->name, "main")) {
3575 if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
3576 /* restore stack frame */
3577 if(STACK_MODEL_LARGE)
3578 pic16_emitpcode(POC_MOVFF,
3579 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3580 pic16_emitpcode(POC_MOVFF,
3581 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3585 pic16_emitcode ("return","");
3586 pic16_emitpcodeNULLop(POC_RETURN);
3588 /* Mark the end of a function */
3589 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3595 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3597 // (AOP(left)->aopu.pcop->type == PO_DIR)?
3599 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3600 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
3601 pic16_emitpcode(POC_MOVWF, dest);
3603 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3604 pic16_popGet(AOP(op), offset), dest));
3608 /*-----------------------------------------------------------------*/
3609 /* genRet - generate code for return statement */
3610 /*-----------------------------------------------------------------*/
3611 static void genRet (iCode *ic)
3616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3617 /* if we have no return value then
3618 * just generate the "ret" */
3623 /* we have something to return then
3624 * move the return value into place */
3625 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3626 size = AOP_SIZE(IC_LEFT(ic));
3630 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3631 // pic16_emitpcode(POC_MOVFF,
3632 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3635 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3636 // pic16_emitpcode(POC_MOVFF,
3637 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3640 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3641 // pic16_emitpcode(POC_MOVFF,
3642 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3645 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3647 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3648 // pic16_emitpcode(POC_MOVFF,
3649 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3652 /* >32-bits, setup stack and FSR0 */
3654 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3655 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3657 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3659 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3664 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3665 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3667 if(STACK_MODEL_LARGE) {
3668 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3669 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3671 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3676 /* old code, left here for reference -- VR */
3680 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3682 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3683 pic16_emitpcomment("push %s",l);
3686 DEBUGpic16_emitcode(";", "%d", __LINE__);
3687 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3688 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3690 if (strcmp(fReturn[offset],l)) {
3691 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3692 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3693 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3695 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3699 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3709 if (strcmp(fReturn[pushed],"a"))
3710 pic16_emitcode("pop",fReturn[pushed]);
3712 pic16_emitcode("pop","acc");
3718 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3721 /* generate a jump to the return label
3722 * if the next is not the return statement */
3723 if (!(ic->next && ic->next->op == LABEL
3724 && IC_LABEL(ic->next) == returnLabel)) {
3726 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3727 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3731 /*-----------------------------------------------------------------*/
3732 /* genLabel - generates a label */
3733 /*-----------------------------------------------------------------*/
3734 static void genLabel (iCode *ic)
3738 /* special case never generate */
3739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3740 if (IC_LABEL(ic) == entryLabel)
3743 pic16_emitpLabel(IC_LABEL(ic)->key);
3744 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3747 /*-----------------------------------------------------------------*/
3748 /* genGoto - generates a goto */
3749 /*-----------------------------------------------------------------*/
3751 static void genGoto (iCode *ic)
3753 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3754 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3758 /*-----------------------------------------------------------------*/
3759 /* genMultbits :- multiplication of bits */
3760 /*-----------------------------------------------------------------*/
3761 static void genMultbits (operand *left,
3765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3767 if(!pic16_sameRegs(AOP(result),AOP(right)))
3768 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3770 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3771 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3772 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3777 /*-----------------------------------------------------------------*/
3778 /* genMultOneByte : 8 bit multiplication & division */
3779 /*-----------------------------------------------------------------*/
3780 static void genMultOneByte (operand *left,
3785 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3786 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3787 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3789 /* (if two literals, the value is computed before) */
3790 /* if one literal, literal on the right */
3791 if (AOP_TYPE(left) == AOP_LIT){
3797 /* size is already checked in genMult == 1 */
3798 // size = AOP_SIZE(result);
3800 if (AOP_TYPE(right) == AOP_LIT){
3801 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3802 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3803 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3804 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3806 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3807 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3808 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3809 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3812 pic16_genMult8X8_8 (left, right,result);
3816 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3817 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3818 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3819 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3821 if (SPEC_USIGN(opetype)){
3822 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3823 pic16_genUMult8X8_16 (left, right, result, NULL);
3826 /* for filling the MSBs */
3827 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3828 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3832 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3834 pic16_emitcode("mov","a,b");
3836 /* adjust the MSB if left or right neg */
3838 /* if one literal */
3839 if (AOP_TYPE(right) == AOP_LIT){
3840 pic16_emitcode("multiply ","right is a lit");
3841 /* AND literal negative */
3842 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3843 /* adjust MSB (c==0 after mul) */
3844 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3848 pic16_genSMult8X8_16 (left, right, result, NULL);
3852 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3854 pic16_emitcode("rlc","a");
3855 pic16_emitcode("subb","a,acc");
3863 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3864 //pic16_aopPut(AOP(result),"a",offset++);
3871 /*-----------------------------------------------------------------*/
3872 /* genMultOneWord : 16 bit multiplication */
3873 /*-----------------------------------------------------------------*/
3874 static void genMultOneWord (operand *left,
3879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3880 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3881 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3883 /* (if two literals, the value is computed before)
3884 * if one literal, literal on the right */
3885 if (AOP_TYPE(left) == AOP_LIT){
3891 /* size is checked already == 2 */
3892 // size = AOP_SIZE(result);
3894 if (AOP_TYPE(right) == AOP_LIT) {
3895 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3896 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3897 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3898 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3900 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3901 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3902 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3903 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3906 pic16_genMult16X16_16(left, right,result);
3909 /*-----------------------------------------------------------------*/
3910 /* genMultOneLong : 32 bit multiplication */
3911 /*-----------------------------------------------------------------*/
3912 static void genMultOneLong (operand *left,
3917 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3918 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3919 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3921 /* (if two literals, the value is computed before)
3922 * if one literal, literal on the right */
3923 if (AOP_TYPE(left) == AOP_LIT){
3929 /* size is checked already == 4 */
3930 // size = AOP_SIZE(result);
3932 if (AOP_TYPE(right) == AOP_LIT) {
3933 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3934 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3935 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3936 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3938 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3939 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3940 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3941 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3944 pic16_genMult32X32_32(left, right,result);
3949 /*-----------------------------------------------------------------*/
3950 /* genMult - generates code for multiplication */
3951 /*-----------------------------------------------------------------*/
3952 static void genMult (iCode *ic)
3954 operand *left = IC_LEFT(ic);
3955 operand *right = IC_RIGHT(ic);
3956 operand *result= IC_RESULT(ic);
3958 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3959 /* assign the amsops */
3960 pic16_aopOp (left,ic,FALSE);
3961 pic16_aopOp (right,ic,FALSE);
3962 pic16_aopOp (result,ic,TRUE);
3964 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3966 /* special cases first *
3968 if (AOP_TYPE(left) == AOP_CRY
3969 && AOP_TYPE(right)== AOP_CRY) {
3970 genMultbits(left,right,result);
3974 /* if both are of size == 1 */
3975 if(AOP_SIZE(left) == 1
3976 && AOP_SIZE(right) == 1) {
3977 genMultOneByte(left,right,result);
3981 /* if both are of size == 2 */
3982 if(AOP_SIZE(left) == 2
3983 && AOP_SIZE(right) == 2) {
3984 genMultOneWord(left, right, result);
3988 /* if both are of size == 4 */
3989 if(AOP_SIZE(left) == 4
3990 && AOP_SIZE(right) == 4) {
3991 genMultOneLong(left, right, result);
3995 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
3998 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
3999 /* should have been converted to function call */
4003 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4004 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4005 pic16_freeAsmop(result,NULL,ic,TRUE);
4008 /*-----------------------------------------------------------------*/
4009 /* genDivbits :- division of bits */
4010 /*-----------------------------------------------------------------*/
4011 static void genDivbits (operand *left,
4018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4019 /* the result must be bit */
4020 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4021 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4025 pic16_emitcode("div","ab");
4026 pic16_emitcode("rrc","a");
4027 pic16_aopPut(AOP(result),"c",0);
4030 /*-----------------------------------------------------------------*/
4031 /* genDivOneByte : 8 bit division */
4032 /*-----------------------------------------------------------------*/
4033 static void genDivOneByte (operand *left,
4037 sym_link *opetype = operandType(result);
4042 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4043 size = AOP_SIZE(result) - 1;
4045 /* signed or unsigned */
4046 if (SPEC_USIGN(opetype)) {
4047 /* unsigned is easy */
4048 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4049 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4051 pic16_emitcode("div","ab");
4052 pic16_aopPut(AOP(result),"a",0);
4054 pic16_aopPut(AOP(result),zero,offset++);
4058 /* signed is a little bit more difficult */
4060 /* save the signs of the operands */
4061 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4063 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4064 pic16_emitcode("push","acc"); /* save it on the stack */
4066 /* now sign adjust for both left & right */
4067 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4069 lbl = newiTempLabel(NULL);
4070 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4071 pic16_emitcode("cpl","a");
4072 pic16_emitcode("inc","a");
4073 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4074 pic16_emitcode("mov","b,a");
4076 /* sign adjust left side */
4077 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4080 lbl = newiTempLabel(NULL);
4081 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4082 pic16_emitcode("cpl","a");
4083 pic16_emitcode("inc","a");
4084 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4086 /* now the division */
4087 pic16_emitcode("div","ab");
4088 /* we are interested in the lower order
4090 pic16_emitcode("mov","b,a");
4091 lbl = newiTempLabel(NULL);
4092 pic16_emitcode("pop","acc");
4093 /* if there was an over flow we don't
4094 adjust the sign of the result */
4095 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4096 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4098 pic16_emitcode("clr","a");
4099 pic16_emitcode("subb","a,b");
4100 pic16_emitcode("mov","b,a");
4101 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4103 /* now we are done */
4104 pic16_aopPut(AOP(result),"b",0);
4106 pic16_emitcode("mov","c,b.7");
4107 pic16_emitcode("subb","a,acc");
4110 pic16_aopPut(AOP(result),"a",offset++);
4114 /*-----------------------------------------------------------------*/
4115 /* genDiv - generates code for division */
4116 /*-----------------------------------------------------------------*/
4117 static void genDiv (iCode *ic)
4119 operand *left = IC_LEFT(ic);
4120 operand *right = IC_RIGHT(ic);
4121 operand *result= IC_RESULT(ic);
4123 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4124 /* assign the amsops */
4125 pic16_aopOp (left,ic,FALSE);
4126 pic16_aopOp (right,ic,FALSE);
4127 pic16_aopOp (result,ic,TRUE);
4129 /* special cases first */
4131 if (AOP_TYPE(left) == AOP_CRY &&
4132 AOP_TYPE(right)== AOP_CRY) {
4133 genDivbits(left,right,result);
4137 /* if both are of size == 1 */
4138 if (AOP_SIZE(left) == 1 &&
4139 AOP_SIZE(right) == 1 ) {
4140 genDivOneByte(left,right,result);
4144 /* should have been converted to function call */
4147 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4148 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4149 pic16_freeAsmop(result,NULL,ic,TRUE);
4152 /*-----------------------------------------------------------------*/
4153 /* genModbits :- modulus of bits */
4154 /*-----------------------------------------------------------------*/
4155 static void genModbits (operand *left,
4162 /* the result must be bit */
4163 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4164 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4168 pic16_emitcode("div","ab");
4169 pic16_emitcode("mov","a,b");
4170 pic16_emitcode("rrc","a");
4171 pic16_aopPut(AOP(result),"c",0);
4174 /*-----------------------------------------------------------------*/
4175 /* genModOneByte : 8 bit modulus */
4176 /*-----------------------------------------------------------------*/
4177 static void genModOneByte (operand *left,
4181 sym_link *opetype = operandType(result);
4185 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4186 /* signed or unsigned */
4187 if (SPEC_USIGN(opetype)) {
4188 /* unsigned is easy */
4189 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4190 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4192 pic16_emitcode("div","ab");
4193 pic16_aopPut(AOP(result),"b",0);
4197 /* signed is a little bit more difficult */
4199 /* save the signs of the operands */
4200 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4203 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4204 pic16_emitcode("push","acc"); /* save it on the stack */
4206 /* now sign adjust for both left & right */
4207 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4210 lbl = newiTempLabel(NULL);
4211 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4212 pic16_emitcode("cpl","a");
4213 pic16_emitcode("inc","a");
4214 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4215 pic16_emitcode("mov","b,a");
4217 /* sign adjust left side */
4218 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4221 lbl = newiTempLabel(NULL);
4222 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4223 pic16_emitcode("cpl","a");
4224 pic16_emitcode("inc","a");
4225 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4227 /* now the multiplication */
4228 pic16_emitcode("div","ab");
4229 /* we are interested in the lower order
4231 lbl = newiTempLabel(NULL);
4232 pic16_emitcode("pop","acc");
4233 /* if there was an over flow we don't
4234 adjust the sign of the result */
4235 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4236 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4238 pic16_emitcode("clr","a");
4239 pic16_emitcode("subb","a,b");
4240 pic16_emitcode("mov","b,a");
4241 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4243 /* now we are done */
4244 pic16_aopPut(AOP(result),"b",0);
4248 /*-----------------------------------------------------------------*/
4249 /* genMod - generates code for division */
4250 /*-----------------------------------------------------------------*/
4251 static void genMod (iCode *ic)
4253 operand *left = IC_LEFT(ic);
4254 operand *right = IC_RIGHT(ic);
4255 operand *result= IC_RESULT(ic);
4257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4258 /* assign the amsops */
4259 pic16_aopOp (left,ic,FALSE);
4260 pic16_aopOp (right,ic,FALSE);
4261 pic16_aopOp (result,ic,TRUE);
4263 /* special cases first */
4265 if (AOP_TYPE(left) == AOP_CRY &&
4266 AOP_TYPE(right)== AOP_CRY) {
4267 genModbits(left,right,result);
4271 /* if both are of size == 1 */
4272 if (AOP_SIZE(left) == 1 &&
4273 AOP_SIZE(right) == 1 ) {
4274 genModOneByte(left,right,result);
4278 /* should have been converted to function call */
4282 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4283 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4284 pic16_freeAsmop(result,NULL,ic,TRUE);
4287 /*-----------------------------------------------------------------*/
4288 /* genIfxJump :- will create a jump depending on the ifx */
4289 /*-----------------------------------------------------------------*/
4291 note: May need to add parameter to indicate when a variable is in bit space.
4293 static void genIfxJump (iCode *ic, char *jval)
4296 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4297 /* if true label then we jump if condition
4299 if ( IC_TRUE(ic) ) {
4301 if(strcmp(jval,"a") == 0)
4303 else if (strcmp(jval,"c") == 0)
4306 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4307 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
4310 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4311 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
4315 /* false label is present */
4316 if(strcmp(jval,"a") == 0)
4318 else if (strcmp(jval,"c") == 0)
4321 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4322 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
4325 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4326 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
4331 /* mark the icode as generated */
4335 /*-----------------------------------------------------------------*/
4337 /*-----------------------------------------------------------------*/
4338 static void genSkip(iCode *ifx,int status_bit)
4340 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4344 if ( IC_TRUE(ifx) ) {
4345 switch(status_bit) {
4360 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4361 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4365 switch(status_bit) {
4379 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4380 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4386 /*-----------------------------------------------------------------*/
4388 /*-----------------------------------------------------------------*/
4389 static void genSkipc(resolvedIfx *rifx)
4391 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4401 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4402 rifx->generated = 1;
4405 /*-----------------------------------------------------------------*/
4407 /*-----------------------------------------------------------------*/
4408 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4410 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4415 if( (rifx->condition ^ invert_condition) & 1)
4420 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4421 rifx->generated = 1;
4425 /*-----------------------------------------------------------------*/
4427 /*-----------------------------------------------------------------*/
4428 static void genSkipz(iCode *ifx, int condition)
4439 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4441 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4444 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4446 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4451 /*-----------------------------------------------------------------*/
4453 /*-----------------------------------------------------------------*/
4454 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4460 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4462 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4465 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4466 rifx->generated = 1;
4470 /*-----------------------------------------------------------------*/
4471 /* genChkZeroes :- greater or less than comparison */
4472 /* For each byte in a literal that is zero, inclusive or the */
4473 /* the corresponding byte in the operand with W */
4474 /* returns true if any of the bytes are zero */
4475 /*-----------------------------------------------------------------*/
4476 static int genChkZeroes(operand *op, int lit, int size)
4483 i = (lit >> (size*8)) & 0xff;
4487 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4489 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4498 /*-----------------------------------------------------------------*/
4499 /* genCmp :- greater or less than comparison */
4500 /*-----------------------------------------------------------------*/
4501 static void genCmp (operand *left,operand *right,
4502 operand *result, iCode *ifx, int sign)
4504 int size; //, offset = 0 ;
4505 unsigned long lit = 0L,i = 0;
4506 resolvedIfx rFalseIfx;
4507 // resolvedIfx rTrueIfx;
4509 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4512 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4513 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4517 resolveIfx(&rFalseIfx,ifx);
4518 truelbl = newiTempLabel(NULL);
4519 size = max(AOP_SIZE(left),AOP_SIZE(right));
4521 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4525 /* if literal is on the right then swap with left */
4526 if ((AOP_TYPE(right) == AOP_LIT)) {
4527 operand *tmp = right ;
4528 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4529 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4532 lit = (lit - 1) & mask;
4535 rFalseIfx.condition ^= 1;
4538 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4539 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4543 //if(IC_TRUE(ifx) == NULL)
4544 /* if left & right are bit variables */
4545 if (AOP_TYPE(left) == AOP_CRY &&
4546 AOP_TYPE(right) == AOP_CRY ) {
4547 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4548 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4550 /* subtract right from left if at the
4551 end the carry flag is set then we know that
4552 left is greater than right */
4554 symbol *lbl = newiTempLabel(NULL);
4557 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4558 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
4562 if(AOP_TYPE(right) == AOP_LIT) {
4564 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4566 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4573 genSkipCond(&rFalseIfx,left,size-1,7);
4575 /* no need to compare to 0...*/
4576 /* NOTE: this is a de-generate compare that most certainly
4577 * creates some dead code. */
4578 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4580 if(ifx) ifx->generated = 1;
4587 //i = (lit >> (size*8)) & 0xff;
4588 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4590 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4592 i = ((0-lit) & 0xff);
4595 /* lit is 0x7f, all signed chars are less than
4596 * this except for 0x7f itself */
4597 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4598 genSkipz2(&rFalseIfx,0);
4600 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4601 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4602 genSkipc(&rFalseIfx);
4607 genSkipz2(&rFalseIfx,1);
4609 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4610 genSkipc(&rFalseIfx);
4614 if(ifx) ifx->generated = 1;
4618 /* chars are out of the way. now do ints and longs */
4621 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4628 genSkipCond(&rFalseIfx,left,size,7);
4629 if(ifx) ifx->generated = 1;
4634 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4636 //rFalseIfx.condition ^= 1;
4637 //genSkipCond(&rFalseIfx,left,size,7);
4638 //rFalseIfx.condition ^= 1;
4640 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4641 if(rFalseIfx.condition)
4642 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4644 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4646 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4647 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4648 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4651 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4653 if(rFalseIfx.condition) {
4655 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4661 genSkipc(&rFalseIfx);
4662 pic16_emitpLabel(truelbl->key);
4663 if(ifx) ifx->generated = 1;
4670 if( (lit & 0xff) == 0) {
4671 /* lower byte is zero */
4672 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4673 i = ((lit >> 8) & 0xff) ^0x80;
4674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4675 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4676 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4677 genSkipc(&rFalseIfx);
4680 if(ifx) ifx->generated = 1;
4685 /* Special cases for signed longs */
4686 if( (lit & 0xffffff) == 0) {
4687 /* lower byte is zero */
4688 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4689 i = ((lit >> 8*3) & 0xff) ^0x80;
4690 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4691 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4692 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4693 genSkipc(&rFalseIfx);
4696 if(ifx) ifx->generated = 1;
4704 if(lit & (0x80 << (size*8))) {
4705 /* lit is negative */
4706 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4708 //genSkipCond(&rFalseIfx,left,size,7);
4710 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4712 if(rFalseIfx.condition)
4713 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4715 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4719 /* lit is positive */
4720 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4721 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4722 if(rFalseIfx.condition)
4723 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4725 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4730 This works, but is only good for ints.
4731 It also requires a "known zero" register.
4732 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4733 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4734 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4735 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4736 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4737 genSkipc(&rFalseIfx);
4739 pic16_emitpLabel(truelbl->key);
4740 if(ifx) ifx->generated = 1;
4744 /* There are no more special cases, so perform a general compare */
4746 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4747 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4751 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4753 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4755 //rFalseIfx.condition ^= 1;
4756 genSkipc(&rFalseIfx);
4758 pic16_emitpLabel(truelbl->key);
4760 if(ifx) ifx->generated = 1;
4767 /* sign is out of the way. So now do an unsigned compare */
4768 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4771 /* General case - compare to an unsigned literal on the right.*/
4773 i = (lit >> (size*8)) & 0xff;
4774 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4775 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4777 i = (lit >> (size*8)) & 0xff;
4780 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4782 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4784 /* this byte of the lit is zero,
4785 *if it's not the last then OR in the variable */
4787 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4792 pic16_emitpLabel(lbl->key);
4793 // pic16_emitpLabel(truelbl->key);
4794 //if(emitFinalCheck)
4795 genSkipc(&rFalseIfx);
4797 pic16_emitpLabel(truelbl->key);
4799 if(ifx) ifx->generated = 1;
4806 if(AOP_TYPE(left) == AOP_LIT) {
4807 //symbol *lbl = newiTempLabel(NULL);
4809 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4812 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4815 if((lit == 0) && (sign == 0)){
4818 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4820 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4822 genSkipz2(&rFalseIfx,0);
4823 if(ifx) ifx->generated = 1;
4830 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4831 /* degenerate compare can never be true */
4832 if(rFalseIfx.condition == 0)
4833 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4835 if(ifx) ifx->generated = 1;
4840 /* signed comparisons to a literal byte */
4842 int lp1 = (lit+1) & 0xff;
4844 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4847 rFalseIfx.condition ^= 1;
4848 genSkipCond(&rFalseIfx,right,0,7);
4851 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4852 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4853 genSkipz2(&rFalseIfx,1);
4856 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4857 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4858 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4859 rFalseIfx.condition ^= 1;
4860 genSkipc(&rFalseIfx);
4864 /* unsigned comparisons to a literal byte */
4866 switch(lit & 0xff ) {
4868 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4869 genSkipz2(&rFalseIfx,0);
4872 rFalseIfx.condition ^= 1;
4873 genSkipCond(&rFalseIfx,right,0,7);
4877 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4878 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4880 rFalseIfx.condition ^= 1;
4881 if (AOP_TYPE(result) == AOP_CRY)
4882 genSkipc(&rFalseIfx);
4884 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4885 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4891 if(ifx) ifx->generated = 1;
4897 /* Size is greater than 1 */
4905 /* this means lit = 0xffffffff, or -1 */
4908 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4909 rFalseIfx.condition ^= 1;
4910 genSkipCond(&rFalseIfx,right,size,7);
4911 if(ifx) ifx->generated = 1;
4918 if(rFalseIfx.condition) {
4919 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4920 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4923 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4925 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4929 if(rFalseIfx.condition) {
4930 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4931 pic16_emitpLabel(truelbl->key);
4933 rFalseIfx.condition ^= 1;
4934 genSkipCond(&rFalseIfx,right,s,7);
4937 if(ifx) ifx->generated = 1;
4941 if((size == 1) && (0 == (lp1&0xff))) {
4942 /* lower byte of signed word is zero */
4943 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4944 i = ((lp1 >> 8) & 0xff) ^0x80;
4945 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4946 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4947 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4948 rFalseIfx.condition ^= 1;
4949 genSkipc(&rFalseIfx);
4952 if(ifx) ifx->generated = 1;
4956 if(lit & (0x80 << (size*8))) {
4957 /* Lit is less than zero */
4958 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4959 //rFalseIfx.condition ^= 1;
4960 //genSkipCond(&rFalseIfx,left,size,7);
4961 //rFalseIfx.condition ^= 1;
4962 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4963 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4965 if(rFalseIfx.condition)
4966 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4968 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4972 /* Lit is greater than or equal to zero */
4973 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4974 //rFalseIfx.condition ^= 1;
4975 //genSkipCond(&rFalseIfx,right,size,7);
4976 //rFalseIfx.condition ^= 1;
4978 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4979 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4981 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4982 if(rFalseIfx.condition)
4983 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4985 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4990 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4991 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4995 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4997 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4999 rFalseIfx.condition ^= 1;
5000 //rFalseIfx.condition = 1;
5001 genSkipc(&rFalseIfx);
5003 pic16_emitpLabel(truelbl->key);
5005 if(ifx) ifx->generated = 1;
5010 /* compare word or long to an unsigned literal on the right.*/
5015 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5018 break; /* handled above */
5021 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5023 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5024 genSkipz2(&rFalseIfx,0);
5028 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5030 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5033 if(rFalseIfx.condition)
5034 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5036 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5040 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5042 rFalseIfx.condition ^= 1;
5043 genSkipc(&rFalseIfx);
5046 pic16_emitpLabel(truelbl->key);
5048 if(ifx) ifx->generated = 1;
5054 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5055 i = (lit >> (size*8)) & 0xff;
5057 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5058 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5061 i = (lit >> (size*8)) & 0xff;
5064 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5066 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5068 /* this byte of the lit is zero,
5069 * if it's not the last then OR in the variable */
5071 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5076 pic16_emitpLabel(lbl->key);
5078 rFalseIfx.condition ^= 1;
5080 genSkipc(&rFalseIfx);
5084 pic16_emitpLabel(truelbl->key);
5085 if(ifx) ifx->generated = 1;
5089 /* Compare two variables */
5091 DEBUGpic16_emitcode(";sign","%d",sign);
5095 /* Sigh. thus sucks... */
5097 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5098 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5099 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5100 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5101 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5102 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5104 /* Signed char comparison */
5105 /* Special thanks to Nikolai Golovchenko for this snippet */
5106 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5107 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5108 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5109 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5110 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5111 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5113 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5114 genSkipc(&rFalseIfx);
5116 if(ifx) ifx->generated = 1;
5122 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5123 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5127 /* The rest of the bytes of a multi-byte compare */
5131 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5134 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5135 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5140 pic16_emitpLabel(lbl->key);
5142 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5143 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5144 (AOP_TYPE(result) == AOP_REG)) {
5145 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5146 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5148 genSkipc(&rFalseIfx);
5150 //genSkipc(&rFalseIfx);
5151 if(ifx) ifx->generated = 1;
5158 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5159 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5160 pic16_outBitC(result);
5162 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5163 /* if the result is used in the next
5164 ifx conditional branch then generate
5165 code a little differently */
5167 genIfxJump (ifx,"c");
5169 pic16_outBitC(result);
5170 /* leave the result in acc */
5175 /*-----------------------------------------------------------------*/
5176 /* genCmpGt :- greater than comparison */
5177 /*-----------------------------------------------------------------*/
5178 static void genCmpGt (iCode *ic, iCode *ifx)
5180 operand *left, *right, *result;
5181 sym_link *letype , *retype;
5184 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5186 right= IC_RIGHT(ic);
5187 result = IC_RESULT(ic);
5189 letype = getSpec(operandType(left));
5190 retype =getSpec(operandType(right));
5191 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5192 /* assign the amsops */
5193 pic16_aopOp (left,ic,FALSE);
5194 pic16_aopOp (right,ic,FALSE);
5195 pic16_aopOp (result,ic,TRUE);
5197 genCmp(right, left, result, ifx, sign);
5199 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5200 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5201 pic16_freeAsmop(result,NULL,ic,TRUE);
5204 /*-----------------------------------------------------------------*/
5205 /* genCmpLt - less than comparisons */
5206 /*-----------------------------------------------------------------*/
5207 static void genCmpLt (iCode *ic, iCode *ifx)
5209 operand *left, *right, *result;
5210 sym_link *letype , *retype;
5213 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5215 right= IC_RIGHT(ic);
5216 result = IC_RESULT(ic);
5218 letype = getSpec(operandType(left));
5219 retype =getSpec(operandType(right));
5220 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5222 /* assign the amsops */
5223 pic16_aopOp (left,ic,FALSE);
5224 pic16_aopOp (right,ic,FALSE);
5225 pic16_aopOp (result,ic,TRUE);
5227 genCmp(left, right, result, ifx, sign);
5229 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5230 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5231 pic16_freeAsmop(result,NULL,ic,TRUE);
5234 /*-----------------------------------------------------------------*/
5235 /* genc16bit2lit - compare a 16 bit value to a literal */
5236 /*-----------------------------------------------------------------*/
5237 static void genc16bit2lit(operand *op, int lit, int offset)
5241 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5242 if( (lit&0xff) == 0)
5247 switch( BYTEofLONG(lit,i)) {
5249 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5252 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5255 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5258 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5259 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5264 switch( BYTEofLONG(lit,i)) {
5266 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5270 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5274 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5277 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5279 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5285 /*-----------------------------------------------------------------*/
5286 /* gencjneshort - compare and jump if not equal */
5287 /*-----------------------------------------------------------------*/
5288 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5290 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5292 int res_offset = 0; /* the result may be a different size then left or right */
5293 int res_size = AOP_SIZE(result);
5295 symbol *lbl, *lbl_done;
5297 unsigned long lit = 0L;
5298 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5300 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5301 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5303 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5304 resolveIfx(&rIfx,ifx);
5305 lbl = newiTempLabel(NULL);
5306 lbl_done = newiTempLabel(NULL);
5309 /* if the left side is a literal or
5310 if the right is in a pointer register and left
5312 if ((AOP_TYPE(left) == AOP_LIT) ||
5313 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5318 if(AOP_TYPE(right) == AOP_LIT)
5319 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5321 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5322 preserve_result = 1;
5324 if(result && !preserve_result)
5327 for(i = 0; i < AOP_SIZE(result); i++)
5328 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5332 /* if the right side is a literal then anything goes */
5333 if (AOP_TYPE(right) == AOP_LIT &&
5334 AOP_TYPE(left) != AOP_DIR ) {
5337 genc16bit2lit(left, lit, 0);
5339 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5345 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5346 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5348 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5352 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5354 if(res_offset < res_size-1)
5362 /* if the right side is in a register or in direct space or
5363 if the left is a pointer register & right is not */
5364 else if (AOP_TYPE(right) == AOP_REG ||
5365 AOP_TYPE(right) == AOP_DIR ||
5366 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5367 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5368 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5369 int lbl_key = lbl->key;
5372 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5373 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5375 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5376 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5377 __FUNCTION__,__LINE__);
5381 /* switch(size) { */
5383 /* genc16bit2lit(left, lit, 0); */
5385 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5390 if((AOP_TYPE(left) == AOP_DIR) &&
5391 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5393 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5394 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5396 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5398 switch (lit & 0xff) {
5400 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5403 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5404 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5405 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5409 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5410 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5411 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5412 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5416 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5417 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5422 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5425 if(AOP_TYPE(result) == AOP_CRY) {
5426 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5431 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5433 /* fix me. probably need to check result size too */
5434 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5439 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5440 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5447 if(res_offset < res_size-1)
5452 } else if(AOP_TYPE(right) == AOP_REG &&
5453 AOP_TYPE(left) != AOP_DIR){
5456 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5457 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5458 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5463 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5465 if(res_offset < res_size-1)
5470 /* right is a pointer reg need both a & b */
5472 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5474 pic16_emitcode("mov","b,%s",l);
5475 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5476 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5481 if(result && preserve_result)
5484 for(i = 0; i < AOP_SIZE(result); i++)
5485 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5488 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
5490 if(result && preserve_result)
5491 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
5494 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5496 pic16_emitpLabel(lbl->key);
5498 if(result && preserve_result)
5501 for(i = 0; i < AOP_SIZE(result); i++)
5502 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5504 pic16_emitpLabel(lbl_done->key);
5507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5514 /*-----------------------------------------------------------------*/
5515 /* gencjne - compare and jump if not equal */
5516 /*-----------------------------------------------------------------*/
5517 static void gencjne(operand *left, operand *right, iCode *ifx)
5519 symbol *tlbl = newiTempLabel(NULL);
5521 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5522 gencjneshort(left, right, lbl);
5524 pic16_emitcode("mov","a,%s",one);
5525 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5526 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5527 pic16_emitcode("clr","a");
5528 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5530 pic16_emitpLabel(lbl->key);
5531 pic16_emitpLabel(tlbl->key);
5536 /*-----------------------------------------------------------------*/
5537 /* genCmpEq - generates code for equal to */
5538 /*-----------------------------------------------------------------*/
5539 static void genCmpEq (iCode *ic, iCode *ifx)
5541 operand *left, *right, *result;
5542 unsigned long lit = 0L;
5544 symbol *falselbl = newiTempLabel(NULL);
5547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5550 DEBUGpic16_emitcode ("; ifx is non-null","");
5552 DEBUGpic16_emitcode ("; ifx is null","");
5554 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5555 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5556 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5558 size = max(AOP_SIZE(left),AOP_SIZE(right));
5560 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5562 /* if literal, literal on the right or
5563 if the right is in a pointer register and left
5565 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5566 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5567 operand *tmp = right ;
5573 if(ifx && !AOP_SIZE(result)){
5575 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5576 /* if they are both bit variables */
5577 if (AOP_TYPE(left) == AOP_CRY &&
5578 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5579 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5580 if(AOP_TYPE(right) == AOP_LIT){
5581 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5583 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5584 pic16_emitcode("cpl","c");
5585 } else if(lit == 1L) {
5586 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5588 pic16_emitcode("clr","c");
5590 /* AOP_TYPE(right) == AOP_CRY */
5592 symbol *lbl = newiTempLabel(NULL);
5593 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5594 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5595 pic16_emitcode("cpl","c");
5596 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5598 /* if true label then we jump if condition
5600 tlbl = newiTempLabel(NULL);
5601 if ( IC_TRUE(ifx) ) {
5602 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5603 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5605 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5606 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5608 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5611 /* left and right are both bit variables, result is carry */
5614 resolveIfx(&rIfx,ifx);
5616 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5617 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5618 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5619 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5624 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5626 /* They're not both bit variables. Is the right a literal? */
5627 if(AOP_TYPE(right) == AOP_LIT) {
5628 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5633 switch(lit & 0xff) {
5635 if ( IC_TRUE(ifx) ) {
5636 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5638 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5640 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5641 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5645 if ( IC_TRUE(ifx) ) {
5646 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5648 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5650 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5651 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5655 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5657 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5662 /* end of size == 1 */
5666 genc16bit2lit(left,lit,offset);
5669 /* end of size == 2 */
5674 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5675 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5676 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5677 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5680 /* search for patterns that can be optimized */
5682 genc16bit2lit(left,lit,0);
5686 emitSKPZ; // if hi word unequal
5688 emitSKPNZ; // if hi word equal
5690 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5691 genc16bit2lit(left,lit,2);
5694 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5695 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5699 pic16_emitpLabel(falselbl->key);
5708 } else if(AOP_TYPE(right) == AOP_CRY ) {
5709 /* we know the left is not a bit, but that the right is */
5710 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5711 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5712 pic16_popGet(AOP(right),offset));
5713 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5715 /* if the two are equal, then W will be 0 and the Z bit is set
5716 * we could test Z now, or go ahead and check the high order bytes if
5717 * the variable we're comparing is larger than a byte. */
5720 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5722 if ( IC_TRUE(ifx) ) {
5724 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5725 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5728 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5729 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5733 /* They're both variables that are larger than bits */
5736 tlbl = newiTempLabel(NULL);
5739 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5740 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5742 if ( IC_TRUE(ifx) ) {
5746 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5748 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5749 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5753 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5756 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5757 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5762 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5764 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5765 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5769 if(s>1 && IC_TRUE(ifx)) {
5770 pic16_emitpLabel(tlbl->key);
5771 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5775 /* mark the icode as generated */
5780 /* if they are both bit variables */
5781 if (AOP_TYPE(left) == AOP_CRY &&
5782 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5783 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5784 if(AOP_TYPE(right) == AOP_LIT){
5785 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5787 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5788 pic16_emitcode("cpl","c");
5789 } else if(lit == 1L) {
5790 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5792 pic16_emitcode("clr","c");
5794 /* AOP_TYPE(right) == AOP_CRY */
5796 symbol *lbl = newiTempLabel(NULL);
5797 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5798 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5799 pic16_emitcode("cpl","c");
5800 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5803 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5804 pic16_outBitC(result);
5808 genIfxJump (ifx,"c");
5811 /* if the result is used in an arithmetic operation
5812 then put the result in place */
5813 pic16_outBitC(result);
5816 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5817 gencjne(left,right,result,ifx);
5820 gencjne(left,right,newiTempLabel(NULL));
5822 if(IC_TRUE(ifx)->key)
5823 gencjne(left,right,IC_TRUE(ifx)->key);
5825 gencjne(left,right,IC_FALSE(ifx)->key);
5829 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5830 pic16_aopPut(AOP(result),"a",0);
5835 genIfxJump (ifx,"a");
5839 /* if the result is used in an arithmetic operation
5840 then put the result in place */
5842 if (AOP_TYPE(result) != AOP_CRY)
5843 pic16_outAcc(result);
5845 /* leave the result in acc */
5849 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5850 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5851 pic16_freeAsmop(result,NULL,ic,TRUE);
5854 /*-----------------------------------------------------------------*/
5855 /* ifxForOp - returns the icode containing the ifx for operand */
5856 /*-----------------------------------------------------------------*/
5857 static iCode *ifxForOp ( operand *op, iCode *ic )
5859 /* if true symbol then needs to be assigned */
5860 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5861 if (IS_TRUE_SYMOP(op))
5864 /* if this has register type condition and
5865 the next instruction is ifx with the same operand
5866 and live to of the operand is upto the ifx only then */
5868 ic->next->op == IFX &&
5869 IC_COND(ic->next)->key == op->key &&
5870 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5874 ic->next->op == IFX &&
5875 IC_COND(ic->next)->key == op->key) {
5876 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5880 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5882 ic->next->op == IFX)
5883 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5886 ic->next->op == IFX &&
5887 IC_COND(ic->next)->key == op->key) {
5888 DEBUGpic16_emitcode ("; "," key is okay");
5889 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5890 OP_SYMBOL(op)->liveTo,
5895 /* the code below is completely untested
5896 * it just allows ulong2fs.c compile -- VR */
5899 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
5900 __FILE__, __FUNCTION__, __LINE__);
5902 /* if this has register type condition and
5903 the next instruction is ifx with the same operand
5904 and live to of the operand is upto the ifx only then */
5906 ic->next->op == IFX &&
5907 IC_COND(ic->next)->key == op->key &&
5908 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5912 ic->next->op == IFX &&
5913 IC_COND(ic->next)->key == op->key) {
5914 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5918 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
5919 __FILE__, __FUNCTION__, __LINE__);
5921 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
5925 /*-----------------------------------------------------------------*/
5926 /* genAndOp - for && operation */
5927 /*-----------------------------------------------------------------*/
5928 static void genAndOp (iCode *ic)
5930 operand *left,*right, *result;
5933 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5934 /* note here that && operations that are in an
5935 if statement are taken away by backPatchLabels
5936 only those used in arthmetic operations remain */
5937 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5938 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5939 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5941 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5943 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5944 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5945 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5947 /* if both are bit variables */
5948 /* if (AOP_TYPE(left) == AOP_CRY && */
5949 /* AOP_TYPE(right) == AOP_CRY ) { */
5950 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5951 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5952 /* pic16_outBitC(result); */
5954 /* tlbl = newiTempLabel(NULL); */
5955 /* pic16_toBoolean(left); */
5956 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5957 /* pic16_toBoolean(right); */
5958 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5959 /* pic16_outBitAcc(result); */
5962 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5963 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5964 pic16_freeAsmop(result,NULL,ic,TRUE);
5968 /*-----------------------------------------------------------------*/
5969 /* genOrOp - for || operation */
5970 /*-----------------------------------------------------------------*/
5973 modified this code, but it doesn't appear to ever get called
5976 static void genOrOp (iCode *ic)
5978 operand *left,*right, *result;
5981 /* note here that || operations that are in an
5982 if statement are taken away by backPatchLabels
5983 only those used in arthmetic operations remain */
5984 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5985 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5986 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5987 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5989 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5991 /* if both are bit variables */
5992 if (AOP_TYPE(left) == AOP_CRY &&
5993 AOP_TYPE(right) == AOP_CRY ) {
5994 pic16_emitcode("clrc","");
5995 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5996 AOP(left)->aopu.aop_dir,
5997 AOP(left)->aopu.aop_dir);
5998 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5999 AOP(right)->aopu.aop_dir,
6000 AOP(right)->aopu.aop_dir);
6001 pic16_emitcode("setc","");
6004 tlbl = newiTempLabel(NULL);
6005 pic16_toBoolean(left);
6007 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
6008 pic16_toBoolean(right);
6009 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
6011 pic16_outBitAcc(result);
6014 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6015 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6016 pic16_freeAsmop(result,NULL,ic,TRUE);
6019 /*-----------------------------------------------------------------*/
6020 /* isLiteralBit - test if lit == 2^n */
6021 /*-----------------------------------------------------------------*/
6022 static int isLiteralBit(unsigned long lit)
6024 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6025 0x100L,0x200L,0x400L,0x800L,
6026 0x1000L,0x2000L,0x4000L,0x8000L,
6027 0x10000L,0x20000L,0x40000L,0x80000L,
6028 0x100000L,0x200000L,0x400000L,0x800000L,
6029 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6030 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6033 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6034 for(idx = 0; idx < 32; idx++)
6040 /*-----------------------------------------------------------------*/
6041 /* continueIfTrue - */
6042 /*-----------------------------------------------------------------*/
6043 static void continueIfTrue (iCode *ic)
6045 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6047 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6051 /*-----------------------------------------------------------------*/
6053 /*-----------------------------------------------------------------*/
6054 static void jumpIfTrue (iCode *ic)
6056 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6058 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6062 /*-----------------------------------------------------------------*/
6063 /* jmpTrueOrFalse - */
6064 /*-----------------------------------------------------------------*/
6065 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6067 // ugly but optimized by peephole
6068 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6070 symbol *nlbl = newiTempLabel(NULL);
6071 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6072 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6073 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6074 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6077 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6078 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6083 /*-----------------------------------------------------------------*/
6084 /* genAnd - code for and */
6085 /*-----------------------------------------------------------------*/
6086 static void genAnd (iCode *ic, iCode *ifx)
6088 operand *left, *right, *result;
6090 unsigned long lit = 0L;
6095 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6096 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6097 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6098 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6100 resolveIfx(&rIfx,ifx);
6102 /* if left is a literal & right is not then exchange them */
6103 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6104 AOP_NEEDSACC(left)) {
6105 operand *tmp = right ;
6110 /* if result = right then exchange them */
6111 if(pic16_sameRegs(AOP(result),AOP(right))){
6112 operand *tmp = right ;
6117 /* if right is bit then exchange them */
6118 if (AOP_TYPE(right) == AOP_CRY &&
6119 AOP_TYPE(left) != AOP_CRY){
6120 operand *tmp = right ;
6124 if(AOP_TYPE(right) == AOP_LIT)
6125 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6127 size = AOP_SIZE(result);
6129 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6132 // result = bit & yy;
6133 if (AOP_TYPE(left) == AOP_CRY){
6134 // c = bit & literal;
6135 if(AOP_TYPE(right) == AOP_LIT){
6137 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6140 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6143 if(size && (AOP_TYPE(result) == AOP_CRY)){
6144 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6147 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6151 pic16_emitcode("clr","c");
6154 if (AOP_TYPE(right) == AOP_CRY){
6156 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6157 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6160 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6162 pic16_emitcode("rrc","a");
6163 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6169 pic16_outBitC(result);
6171 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6172 genIfxJump(ifx, "c");
6176 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6177 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6178 if((AOP_TYPE(right) == AOP_LIT) &&
6179 (AOP_TYPE(result) == AOP_CRY) &&
6180 (AOP_TYPE(left) != AOP_CRY)){
6181 int posbit = isLiteralBit(lit);
6185 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6188 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6194 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6195 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6197 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6198 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6201 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6202 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6203 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6210 symbol *tlbl = newiTempLabel(NULL);
6211 int sizel = AOP_SIZE(left);
6213 pic16_emitcode("setb","c");
6215 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
6216 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6218 if((posbit = isLiteralBit(bytelit)) != 0)
6219 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
6221 if(bytelit != 0x0FFL)
6222 pic16_emitcode("anl","a,%s",
6223 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
6224 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6229 // bit = left & literal
6231 pic16_emitcode("clr","c");
6232 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6234 // if(left & literal)
6237 jmpTrueOrFalse(ifx, tlbl);
6241 pic16_outBitC(result);
6245 /* if left is same as result */
6246 if(pic16_sameRegs(AOP(result),AOP(left))){
6248 for(;size--; offset++,lit>>=8) {
6249 if(AOP_TYPE(right) == AOP_LIT){
6250 switch(lit & 0xff) {
6252 /* and'ing with 0 has clears the result */
6253 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6254 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6257 /* and'ing with 0xff is a nop when the result and left are the same */
6262 int p = my_powof2( (~lit) & 0xff );
6264 /* only one bit is set in the literal, so use a bcf instruction */
6265 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
6266 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6269 pic16_emitcode("movlw","0x%x", (lit & 0xff));
6270 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6271 if(know_W != (lit&0xff))
6272 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6274 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6279 if (AOP_TYPE(left) == AOP_ACC) {
6280 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6282 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6283 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6290 // left & result in different registers
6291 if(AOP_TYPE(result) == AOP_CRY){
6293 // if(size), result in bit
6294 // if(!size && ifx), conditional oper: if(left & right)
6295 symbol *tlbl = newiTempLabel(NULL);
6296 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
6298 pic16_emitcode("setb","c");
6300 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6301 pic16_emitcode("anl","a,%s",
6302 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6303 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6308 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6309 pic16_outBitC(result);
6311 jmpTrueOrFalse(ifx, tlbl);
6313 for(;(size--);offset++) {
6315 // result = left & right
6316 if(AOP_TYPE(right) == AOP_LIT){
6317 int t = (lit >> (offset*8)) & 0x0FFL;
6320 pic16_emitcode("clrf","%s",
6321 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6322 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6325 pic16_emitcode("movf","%s,w",
6326 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6327 pic16_emitcode("movwf","%s",
6328 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6329 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6330 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6333 pic16_emitcode("movlw","0x%x",t);
6334 pic16_emitcode("andwf","%s,w",
6335 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6336 pic16_emitcode("movwf","%s",
6337 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6339 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6340 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6341 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6346 if (AOP_TYPE(left) == AOP_ACC) {
6347 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6348 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6350 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6351 pic16_emitcode("andwf","%s,w",
6352 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6353 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6354 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6356 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6357 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6363 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6364 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6365 pic16_freeAsmop(result,NULL,ic,TRUE);
6368 /*-----------------------------------------------------------------*/
6369 /* genOr - code for or */
6370 /*-----------------------------------------------------------------*/
6371 static void genOr (iCode *ic, iCode *ifx)
6373 operand *left, *right, *result;
6375 unsigned long lit = 0L;
6377 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6379 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6380 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6381 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6383 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6385 /* if left is a literal & right is not then exchange them */
6386 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6387 AOP_NEEDSACC(left)) {
6388 operand *tmp = right ;
6393 /* if result = right then exchange them */
6394 if(pic16_sameRegs(AOP(result),AOP(right))){
6395 operand *tmp = right ;
6400 /* if right is bit then exchange them */
6401 if (AOP_TYPE(right) == AOP_CRY &&
6402 AOP_TYPE(left) != AOP_CRY){
6403 operand *tmp = right ;
6408 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6410 if(AOP_TYPE(right) == AOP_LIT)
6411 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6413 size = AOP_SIZE(result);
6417 if (AOP_TYPE(left) == AOP_CRY){
6418 if(AOP_TYPE(right) == AOP_LIT){
6419 // c = bit & literal;
6421 // lit != 0 => result = 1
6422 if(AOP_TYPE(result) == AOP_CRY){
6424 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6425 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6426 // AOP(result)->aopu.aop_dir,
6427 // AOP(result)->aopu.aop_dir);
6429 continueIfTrue(ifx);
6433 // lit == 0 => result = left
6434 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6436 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6439 if (AOP_TYPE(right) == AOP_CRY){
6440 if(pic16_sameRegs(AOP(result),AOP(left))){
6442 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6443 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6444 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6446 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6447 AOP(result)->aopu.aop_dir,
6448 AOP(result)->aopu.aop_dir);
6449 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6450 AOP(right)->aopu.aop_dir,
6451 AOP(right)->aopu.aop_dir);
6452 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6453 AOP(result)->aopu.aop_dir,
6454 AOP(result)->aopu.aop_dir);
6456 if( AOP_TYPE(result) == AOP_ACC) {
6457 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6458 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6459 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6460 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6464 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6465 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6466 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6467 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6469 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6470 AOP(result)->aopu.aop_dir,
6471 AOP(result)->aopu.aop_dir);
6472 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6473 AOP(right)->aopu.aop_dir,
6474 AOP(right)->aopu.aop_dir);
6475 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6476 AOP(left)->aopu.aop_dir,
6477 AOP(left)->aopu.aop_dir);
6478 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6479 AOP(result)->aopu.aop_dir,
6480 AOP(result)->aopu.aop_dir);
6485 symbol *tlbl = newiTempLabel(NULL);
6486 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6489 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6490 if( AOP_TYPE(right) == AOP_ACC) {
6491 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6493 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6494 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6499 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6500 pic16_emitcode(";XXX setb","c");
6501 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6502 AOP(left)->aopu.aop_dir,tlbl->key+100);
6503 pic16_toBoolean(right);
6504 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6505 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6506 jmpTrueOrFalse(ifx, tlbl);
6510 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6517 pic16_outBitC(result);
6519 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6520 genIfxJump(ifx, "c");
6524 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6525 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6526 if((AOP_TYPE(right) == AOP_LIT) &&
6527 (AOP_TYPE(result) == AOP_CRY) &&
6528 (AOP_TYPE(left) != AOP_CRY)){
6530 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6533 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6535 continueIfTrue(ifx);
6538 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6539 // lit = 0, result = boolean(left)
6541 pic16_emitcode(";XXX setb","c");
6542 pic16_toBoolean(right);
6544 symbol *tlbl = newiTempLabel(NULL);
6545 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6547 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6549 genIfxJump (ifx,"a");
6553 pic16_outBitC(result);
6557 /* if left is same as result */
6558 if(pic16_sameRegs(AOP(result),AOP(left))){
6560 for(;size--; offset++,lit>>=8) {
6561 if(AOP_TYPE(right) == AOP_LIT){
6562 if((lit & 0xff) == 0)
6563 /* or'ing with 0 has no effect */
6566 int p = my_powof2(lit & 0xff);
6568 /* only one bit is set in the literal, so use a bsf instruction */
6569 pic16_emitpcode(POC_BSF,
6570 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6572 if(know_W != (lit & 0xff))
6573 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6574 know_W = lit & 0xff;
6575 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6580 if (AOP_TYPE(left) == AOP_ACC) {
6581 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6582 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6584 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6585 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6587 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6588 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6594 // left & result in different registers
6595 if(AOP_TYPE(result) == AOP_CRY){
6597 // if(size), result in bit
6598 // if(!size && ifx), conditional oper: if(left | right)
6599 symbol *tlbl = newiTempLabel(NULL);
6600 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6601 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6605 pic16_emitcode(";XXX setb","c");
6607 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6608 pic16_emitcode(";XXX orl","a,%s",
6609 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6610 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6615 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6616 pic16_outBitC(result);
6618 jmpTrueOrFalse(ifx, tlbl);
6619 } else for(;(size--);offset++){
6621 // result = left & right
6622 if(AOP_TYPE(right) == AOP_LIT){
6623 int t = (lit >> (offset*8)) & 0x0FFL;
6626 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6627 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6629 pic16_emitcode("movf","%s,w",
6630 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6631 pic16_emitcode("movwf","%s",
6632 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6635 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6636 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6637 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6639 pic16_emitcode("movlw","0x%x",t);
6640 pic16_emitcode("iorwf","%s,w",
6641 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6642 pic16_emitcode("movwf","%s",
6643 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6649 // faster than result <- left, anl result,right
6650 // and better if result is SFR
6651 if (AOP_TYPE(left) == AOP_ACC) {
6652 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6653 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6655 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6656 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6658 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6659 pic16_emitcode("iorwf","%s,w",
6660 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6662 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6663 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6668 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6669 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6670 pic16_freeAsmop(result,NULL,ic,TRUE);
6673 /*-----------------------------------------------------------------*/
6674 /* genXor - code for xclusive or */
6675 /*-----------------------------------------------------------------*/
6676 static void genXor (iCode *ic, iCode *ifx)
6678 operand *left, *right, *result;
6680 unsigned long lit = 0L;
6682 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6684 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6685 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6686 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6688 /* if left is a literal & right is not ||
6689 if left needs acc & right does not */
6690 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6691 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6692 operand *tmp = right ;
6697 /* if result = right then exchange them */
6698 if(pic16_sameRegs(AOP(result),AOP(right))){
6699 operand *tmp = right ;
6704 /* if right is bit then exchange them */
6705 if (AOP_TYPE(right) == AOP_CRY &&
6706 AOP_TYPE(left) != AOP_CRY){
6707 operand *tmp = right ;
6711 if(AOP_TYPE(right) == AOP_LIT)
6712 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6714 size = AOP_SIZE(result);
6718 if (AOP_TYPE(left) == AOP_CRY){
6719 if(AOP_TYPE(right) == AOP_LIT){
6720 // c = bit & literal;
6722 // lit>>1 != 0 => result = 1
6723 if(AOP_TYPE(result) == AOP_CRY){
6725 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6726 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6728 continueIfTrue(ifx);
6731 pic16_emitcode("setb","c");
6735 // lit == 0, result = left
6736 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6738 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6740 // lit == 1, result = not(left)
6741 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6742 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6743 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6744 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6747 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6748 pic16_emitcode("cpl","c");
6755 symbol *tlbl = newiTempLabel(NULL);
6756 if (AOP_TYPE(right) == AOP_CRY){
6758 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6761 int sizer = AOP_SIZE(right);
6763 // if val>>1 != 0, result = 1
6764 pic16_emitcode("setb","c");
6766 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6768 // test the msb of the lsb
6769 pic16_emitcode("anl","a,#0xfe");
6770 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6774 pic16_emitcode("rrc","a");
6776 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6777 pic16_emitcode("cpl","c");
6778 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6783 pic16_outBitC(result);
6785 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6786 genIfxJump(ifx, "c");
6790 if(pic16_sameRegs(AOP(result),AOP(left))){
6791 /* if left is same as result */
6792 for(;size--; offset++) {
6793 if(AOP_TYPE(right) == AOP_LIT){
6794 int t = (lit >> (offset*8)) & 0x0FFL;
6798 if (IS_AOP_PREG(left)) {
6799 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6800 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6801 pic16_aopPut(AOP(result),"a",offset);
6803 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6804 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6805 pic16_emitcode("xrl","%s,%s",
6806 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6807 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6810 if (AOP_TYPE(left) == AOP_ACC)
6811 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6813 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6814 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6816 if (IS_AOP_PREG(left)) {
6817 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6818 pic16_aopPut(AOP(result),"a",offset);
6820 pic16_emitcode("xrl","%s,a",
6821 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6827 // left & result in different registers
6828 if(AOP_TYPE(result) == AOP_CRY){
6830 // if(size), result in bit
6831 // if(!size && ifx), conditional oper: if(left ^ right)
6832 symbol *tlbl = newiTempLabel(NULL);
6833 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6835 pic16_emitcode("setb","c");
6837 if((AOP_TYPE(right) == AOP_LIT) &&
6838 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6839 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6841 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6842 pic16_emitcode("xrl","a,%s",
6843 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6845 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6850 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6851 pic16_outBitC(result);
6853 jmpTrueOrFalse(ifx, tlbl);
6854 } else for(;(size--);offset++){
6856 // result = left & right
6857 if(AOP_TYPE(right) == AOP_LIT){
6858 int t = (lit >> (offset*8)) & 0x0FFL;
6861 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6862 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6863 pic16_emitcode("movf","%s,w",
6864 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6865 pic16_emitcode("movwf","%s",
6866 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6869 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6870 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6871 pic16_emitcode("comf","%s,w",
6872 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6873 pic16_emitcode("movwf","%s",
6874 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6877 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6878 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6879 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6880 pic16_emitcode("movlw","0x%x",t);
6881 pic16_emitcode("xorwf","%s,w",
6882 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6883 pic16_emitcode("movwf","%s",
6884 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6890 // faster than result <- left, anl result,right
6891 // and better if result is SFR
6892 if (AOP_TYPE(left) == AOP_ACC) {
6893 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6894 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6896 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6897 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6898 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6899 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6901 if ( AOP_TYPE(result) != AOP_ACC){
6902 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6903 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6909 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6910 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6911 pic16_freeAsmop(result,NULL,ic,TRUE);
6914 /*-----------------------------------------------------------------*/
6915 /* genInline - write the inline code out */
6916 /*-----------------------------------------------------------------*/
6917 static void genInline (iCode *ic)
6919 char *buffer, *bp, *bp1;
6921 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6923 _G.inLine += (!options.asmpeep);
6925 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6926 strcpy(buffer,IC_INLINE(ic));
6928 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
6930 /* emit each line as a code */
6936 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6944 /* print label, use this special format with NULL directive
6945 * to denote that the argument should not be indented with tab */
6946 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
6953 if ((bp1 != bp) && *bp1)
6954 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6959 _G.inLine -= (!options.asmpeep);
6962 /*-----------------------------------------------------------------*/
6963 /* genRRC - rotate right with carry */
6964 /*-----------------------------------------------------------------*/
6965 static void genRRC (iCode *ic)
6967 operand *left , *result ;
6968 int size, offset = 0, same;
6970 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6972 /* rotate right with carry */
6974 result=IC_RESULT(ic);
6975 pic16_aopOp (left,ic,FALSE);
6976 pic16_aopOp (result,ic,FALSE);
6978 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6980 same = pic16_sameRegs(AOP(result),AOP(left));
6982 size = AOP_SIZE(result);
6984 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6986 /* get the lsb and put it into the carry */
6987 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6994 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6996 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6997 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7003 pic16_freeAsmop(left,NULL,ic,TRUE);
7004 pic16_freeAsmop(result,NULL,ic,TRUE);
7007 /*-----------------------------------------------------------------*/
7008 /* genRLC - generate code for rotate left with carry */
7009 /*-----------------------------------------------------------------*/
7010 static void genRLC (iCode *ic)
7012 operand *left , *result ;
7013 int size, offset = 0;
7016 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7017 /* rotate right with carry */
7019 result=IC_RESULT(ic);
7020 pic16_aopOp (left,ic,FALSE);
7021 pic16_aopOp (result,ic,FALSE);
7023 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7025 same = pic16_sameRegs(AOP(result),AOP(left));
7027 /* move it to the result */
7028 size = AOP_SIZE(result);
7030 /* get the msb and put it into the carry */
7031 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7038 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7040 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7041 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7048 pic16_freeAsmop(left,NULL,ic,TRUE);
7049 pic16_freeAsmop(result,NULL,ic,TRUE);
7053 /* gpasm can get the highest order bit with HIGH/UPPER
7054 * so the following probably is not needed -- VR */
7056 /*-----------------------------------------------------------------*/
7057 /* genGetHbit - generates code get highest order bit */
7058 /*-----------------------------------------------------------------*/
7059 static void genGetHbit (iCode *ic)
7061 operand *left, *result;
7063 result=IC_RESULT(ic);
7064 pic16_aopOp (left,ic,FALSE);
7065 pic16_aopOp (result,ic,FALSE);
7067 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7068 /* get the highest order byte into a */
7069 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7070 if(AOP_TYPE(result) == AOP_CRY){
7071 pic16_emitcode("rlc","a");
7072 pic16_outBitC(result);
7075 pic16_emitcode("rl","a");
7076 pic16_emitcode("anl","a,#0x01");
7077 pic16_outAcc(result);
7081 pic16_freeAsmop(left,NULL,ic,TRUE);
7082 pic16_freeAsmop(result,NULL,ic,TRUE);
7086 /*-----------------------------------------------------------------*/
7087 /* AccRol - rotate left accumulator by known count */
7088 /*-----------------------------------------------------------------*/
7089 static void AccRol (int shCount)
7091 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7092 shCount &= 0x0007; // shCount : 0..7
7097 pic16_emitcode("rl","a");
7100 pic16_emitcode("rl","a");
7101 pic16_emitcode("rl","a");
7104 pic16_emitcode("swap","a");
7105 pic16_emitcode("rr","a");
7108 pic16_emitcode("swap","a");
7111 pic16_emitcode("swap","a");
7112 pic16_emitcode("rl","a");
7115 pic16_emitcode("rr","a");
7116 pic16_emitcode("rr","a");
7119 pic16_emitcode("rr","a");
7125 /*-----------------------------------------------------------------*/
7126 /* AccLsh - left shift accumulator by known count */
7127 /*-----------------------------------------------------------------*/
7128 static void AccLsh (int shCount)
7130 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7136 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7139 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7140 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7143 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7144 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7147 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7150 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7151 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7154 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7155 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7158 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7162 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7165 /*-----------------------------------------------------------------*/
7166 /* AccRsh - right shift accumulator by known count */
7167 /*-----------------------------------------------------------------*/
7168 static void AccRsh (int shCount, int andmask)
7170 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7175 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7176 // andmask = 0; /* no need */
7179 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7180 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7181 // andmask = 0; /* no need */
7184 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7185 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7188 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7191 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7192 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7195 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7196 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7199 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7204 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
7206 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
7210 /*-----------------------------------------------------------------*/
7211 /* AccSRsh - signed right shift accumulator by known count */
7212 /*-----------------------------------------------------------------*/
7213 static void AccSRsh (int shCount)
7216 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7219 pic16_emitcode("mov","c,acc.7");
7220 pic16_emitcode("rrc","a");
7221 } else if(shCount == 2){
7222 pic16_emitcode("mov","c,acc.7");
7223 pic16_emitcode("rrc","a");
7224 pic16_emitcode("mov","c,acc.7");
7225 pic16_emitcode("rrc","a");
7227 tlbl = newiTempLabel(NULL);
7228 /* rotate right accumulator */
7229 AccRol(8 - shCount);
7230 /* and kill the higher order bits */
7231 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
7232 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
7233 pic16_emitcode("orl","a,#0x%02x",
7234 (unsigned char)~SRMask[shCount]);
7235 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7240 /*-----------------------------------------------------------------*/
7241 /* shiftR1Left2Result - shift right one byte from left to result */
7242 /*-----------------------------------------------------------------*/
7243 static void shiftR1Left2ResultSigned (operand *left, int offl,
7244 operand *result, int offr,
7249 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7251 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7255 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7257 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7259 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7260 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7266 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7268 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7270 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7271 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7273 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7274 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7280 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7282 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7283 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7286 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7287 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7288 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7290 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7291 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
7293 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7297 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7298 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7299 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7300 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
7301 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7305 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7307 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7308 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7310 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7311 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
7312 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7313 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
7314 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7319 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7320 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7321 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
7322 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7323 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
7324 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7326 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7327 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7328 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7329 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7330 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
7336 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7337 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7338 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7339 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7341 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7342 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7343 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7351 /*-----------------------------------------------------------------*/
7352 /* shiftR1Left2Result - shift right one byte from left to result */
7353 /*-----------------------------------------------------------------*/
7354 static void shiftR1Left2Result (operand *left, int offl,
7355 operand *result, int offr,
7356 int shCount, int sign)
7360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7362 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7364 /* Copy the msb into the carry if signed. */
7366 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
7376 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7378 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7379 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7385 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7387 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7388 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7391 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7396 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7398 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7399 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7402 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7403 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7404 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7405 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7409 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7410 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7415 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7416 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7417 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7419 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7424 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7425 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7427 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7428 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7433 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7434 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7435 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7444 /*-----------------------------------------------------------------*/
7445 /* shiftL1Left2Result - shift left one byte from left to result */
7446 /*-----------------------------------------------------------------*/
7447 static void shiftL1Left2Result (operand *left, int offl,
7448 operand *result, int offr, int shCount)
7453 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7455 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7456 DEBUGpic16_emitcode ("; ***","same = %d",same);
7457 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7459 /* shift left accumulator */
7460 //AccLsh(shCount); // don't comment out just yet...
7461 // pic16_aopPut(AOP(result),"a",offr);
7465 /* Shift left 1 bit position */
7466 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7468 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7470 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7471 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7475 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7476 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7477 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7478 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7481 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7482 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7483 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7484 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7485 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7488 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7489 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7490 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7493 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7494 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7495 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7496 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7499 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7500 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7501 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7502 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7503 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7506 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7507 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7508 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7512 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7517 /*-----------------------------------------------------------------*/
7518 /* movLeft2Result - move byte from left to result */
7519 /*-----------------------------------------------------------------*/
7520 static void movLeft2Result (operand *left, int offl,
7521 operand *result, int offr)
7524 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7525 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7526 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7528 if (*l == '@' && (IS_AOP_PREG(result))) {
7529 pic16_emitcode("mov","a,%s",l);
7530 pic16_aopPut(AOP(result),"a",offr);
7532 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7533 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7538 /*-----------------------------------------------------------------*/
7539 /* shiftL2Left2Result - shift left two bytes from left to result */
7540 /*-----------------------------------------------------------------*/
7541 static void shiftL2Left2Result (operand *left, int offl,
7542 operand *result, int offr, int shCount)
7544 int same = pic16_sameRegs(AOP(result), AOP(left));
7547 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7549 if (same && (offl != offr)) { // shift bytes
7552 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7553 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7555 } else { // just treat as different later on
7568 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7569 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7570 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7574 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7575 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7581 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7582 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7583 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7584 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7585 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7586 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7587 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7589 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7590 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7594 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7595 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7596 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7597 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7598 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7599 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7600 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7601 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7602 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7603 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7606 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7607 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7608 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7609 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7610 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7620 /* note, use a mov/add for the shift since the mov has a
7621 chance of getting optimized out */
7622 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7623 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7624 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7625 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7626 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7630 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7631 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7637 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7638 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7639 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7640 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7641 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7642 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7643 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7644 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7648 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7649 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7653 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7654 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7655 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7656 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7658 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7659 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7660 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7661 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7662 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7663 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7664 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7665 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7668 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7669 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7670 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7671 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7672 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7677 /*-----------------------------------------------------------------*/
7678 /* shiftR2Left2Result - shift right two bytes from left to result */
7679 /*-----------------------------------------------------------------*/
7680 static void shiftR2Left2Result (operand *left, int offl,
7681 operand *result, int offr,
7682 int shCount, int sign)
7684 int same = pic16_sameRegs(AOP(result), AOP(left));
7686 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7688 if (same && (offl != offr)) { // shift right bytes
7691 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7692 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7694 } else { // just treat as different later on
7706 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7711 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7712 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7714 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7715 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7716 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7717 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7722 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7725 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7726 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7733 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7734 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7735 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7737 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7738 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7739 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7740 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7742 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7743 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7744 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7746 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7747 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7748 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7749 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7750 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7754 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7755 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7759 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7760 pic16_emitpcode(POC_BTFSC,
7761 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7762 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7770 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7771 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7773 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7774 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7775 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7776 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7778 pic16_emitpcode(POC_BTFSC,
7779 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7780 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7782 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7783 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7784 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7785 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7787 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7788 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7789 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7790 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7791 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7792 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7793 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7794 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7796 pic16_emitpcode(POC_BTFSC,
7797 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7798 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7800 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7801 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7808 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7809 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7810 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7811 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7814 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7816 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7821 /*-----------------------------------------------------------------*/
7822 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7823 /*-----------------------------------------------------------------*/
7824 static void shiftLLeftOrResult (operand *left, int offl,
7825 operand *result, int offr, int shCount)
7827 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7829 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7830 /* shift left accumulator */
7832 /* or with result */
7833 /* back to result */
7834 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7837 /*-----------------------------------------------------------------*/
7838 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7839 /*-----------------------------------------------------------------*/
7840 static void shiftRLeftOrResult (operand *left, int offl,
7841 operand *result, int offr, int shCount)
7843 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7845 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7846 /* shift right accumulator */
7848 /* or with result */
7849 /* back to result */
7850 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7853 /*-----------------------------------------------------------------*/
7854 /* genlshOne - left shift a one byte quantity by known count */
7855 /*-----------------------------------------------------------------*/
7856 static void genlshOne (operand *result, operand *left, int shCount)
7858 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7859 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7862 /*-----------------------------------------------------------------*/
7863 /* genlshTwo - left shift two bytes by known amount != 0 */
7864 /*-----------------------------------------------------------------*/
7865 static void genlshTwo (operand *result,operand *left, int shCount)
7869 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7870 size = pic16_getDataSize(result);
7872 /* if shCount >= 8 */
7878 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7880 movLeft2Result(left, LSB, result, MSB16);
7882 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7885 /* 1 <= shCount <= 7 */
7888 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7890 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7894 /*-----------------------------------------------------------------*/
7895 /* shiftLLong - shift left one long from left to result */
7896 /* offr = LSB or MSB16 */
7897 /*-----------------------------------------------------------------*/
7898 static void shiftLLong (operand *left, operand *result, int offr )
7900 int size = AOP_SIZE(result);
7901 int same = pic16_sameRegs(AOP(left),AOP(result));
7904 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7906 if (same && (offr == MSB16)) { //shift one byte
7907 for(i=size-1;i>=MSB16;i--) {
7908 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7909 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7912 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7915 if (size >= LSB+offr ){
7917 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7919 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7920 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7924 if(size >= MSB16+offr){
7926 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7928 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7929 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7933 if(size >= MSB24+offr){
7935 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7937 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7938 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7942 if(size > MSB32+offr){
7944 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7946 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7947 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7951 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7955 /*-----------------------------------------------------------------*/
7956 /* genlshFour - shift four byte by a known amount != 0 */
7957 /*-----------------------------------------------------------------*/
7958 static void genlshFour (operand *result, operand *left, int shCount)
7962 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 size = AOP_SIZE(result);
7965 /* if shifting more that 3 bytes */
7966 if (shCount >= 24 ) {
7969 /* lowest order of left goes to the highest
7970 order of the destination */
7971 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7973 movLeft2Result(left, LSB, result, MSB32);
7975 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7976 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7977 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7982 /* more than two bytes */
7983 else if ( shCount >= 16 ) {
7984 /* lower order two bytes goes to higher order two bytes */
7986 /* if some more remaining */
7988 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7990 movLeft2Result(left, MSB16, result, MSB32);
7991 movLeft2Result(left, LSB, result, MSB24);
7993 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7994 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7998 /* if more than 1 byte */
7999 else if ( shCount >= 8 ) {
8000 /* lower order three bytes goes to higher order three bytes */
8004 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8006 movLeft2Result(left, LSB, result, MSB16);
8008 else{ /* size = 4 */
8010 movLeft2Result(left, MSB24, result, MSB32);
8011 movLeft2Result(left, MSB16, result, MSB24);
8012 movLeft2Result(left, LSB, result, MSB16);
8013 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8015 else if(shCount == 1)
8016 shiftLLong(left, result, MSB16);
8018 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8019 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8020 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8021 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8026 /* 1 <= shCount <= 7 */
8027 else if(shCount <= 3)
8029 shiftLLong(left, result, LSB);
8030 while(--shCount >= 1)
8031 shiftLLong(result, result, LSB);
8033 /* 3 <= shCount <= 7, optimize */
8035 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8036 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8037 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8041 /*-----------------------------------------------------------------*/
8042 /* genLeftShiftLiteral - left shifting by known count */
8043 /*-----------------------------------------------------------------*/
8044 static void genLeftShiftLiteral (operand *left,
8049 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8052 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8053 pic16_freeAsmop(right,NULL,ic,TRUE);
8055 pic16_aopOp(left,ic,FALSE);
8056 pic16_aopOp(result,ic,FALSE);
8058 size = getSize(operandType(result));
8061 pic16_emitcode("; shift left ","result %d, left %d",size,
8065 /* I suppose that the left size >= result size */
8068 movLeft2Result(left, size, result, size);
8072 else if(shCount >= (size * 8))
8074 pic16_aopPut(AOP(result),zero,size);
8078 genlshOne (result,left,shCount);
8083 genlshTwo (result,left,shCount);
8087 genlshFour (result,left,shCount);
8091 pic16_freeAsmop(left,NULL,ic,TRUE);
8092 pic16_freeAsmop(result,NULL,ic,TRUE);
8095 /*-----------------------------------------------------------------*
8096 * genMultiAsm - repeat assembly instruction for size of register.
8097 * if endian == 1, then the high byte (i.e base address + size of
8098 * register) is used first else the low byte is used first;
8099 *-----------------------------------------------------------------*/
8100 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8105 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8118 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8123 /*-----------------------------------------------------------------*/
8124 /* genLeftShift - generates code for left shifting */
8125 /*-----------------------------------------------------------------*/
8126 static void genLeftShift (iCode *ic)
8128 operand *left,*right, *result;
8131 symbol *tlbl , *tlbl1;
8134 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8136 right = IC_RIGHT(ic);
8138 result = IC_RESULT(ic);
8140 pic16_aopOp(right,ic,FALSE);
8142 /* if the shift count is known then do it
8143 as efficiently as possible */
8144 if (AOP_TYPE(right) == AOP_LIT) {
8145 genLeftShiftLiteral (left,right,result,ic);
8149 /* shift count is unknown then we have to form
8150 a loop get the loop count in B : Note: we take
8151 only the lower order byte since shifting
8152 more that 32 bits make no sense anyway, ( the
8153 largest size of an object can be only 32 bits ) */
8156 pic16_aopOp(left,ic,FALSE);
8157 pic16_aopOp(result,ic,FALSE);
8159 /* now move the left to the result if they are not the
8161 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8162 AOP_SIZE(result) > 1) {
8164 size = AOP_SIZE(result);
8167 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8168 if (*l == '@' && (IS_AOP_PREG(result))) {
8170 pic16_emitcode("mov","a,%s",l);
8171 pic16_aopPut(AOP(result),"a",offset);
8173 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8174 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8175 //pic16_aopPut(AOP(result),l,offset);
8181 size = AOP_SIZE(result);
8183 /* if it is only one byte then */
8185 if(optimized_for_speed) {
8186 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8187 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8188 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
8189 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8190 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8191 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
8192 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8193 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8194 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8195 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8196 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
8197 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8200 tlbl = newiTempLabel(NULL);
8201 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8202 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8203 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8206 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8207 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8208 pic16_emitpLabel(tlbl->key);
8209 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8210 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8212 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8217 if (pic16_sameRegs(AOP(left),AOP(result))) {
8219 tlbl = newiTempLabel(NULL);
8220 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8221 genMultiAsm(POC_RRCF, result, size,1);
8222 pic16_emitpLabel(tlbl->key);
8223 genMultiAsm(POC_RLCF, result, size,0);
8224 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8226 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8230 //tlbl = newiTempLabel(NULL);
8232 //tlbl1 = newiTempLabel(NULL);
8234 //reAdjustPreg(AOP(result));
8236 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8237 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8238 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8240 //pic16_emitcode("add","a,acc");
8241 //pic16_aopPut(AOP(result),"a",offset++);
8243 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8245 // pic16_emitcode("rlc","a");
8246 // pic16_aopPut(AOP(result),"a",offset++);
8248 //reAdjustPreg(AOP(result));
8250 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8251 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8254 tlbl = newiTempLabel(NULL);
8255 tlbl1= newiTempLabel(NULL);
8257 size = AOP_SIZE(result);
8260 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8262 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8264 /* offset should be 0, 1 or 3 */
8266 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8268 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8270 pic16_emitpcode(POC_MOVWF, pctemp);
8273 pic16_emitpLabel(tlbl->key);
8276 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8278 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8280 pic16_emitpcode(POC_DECFSZ, pctemp);
8281 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8282 pic16_emitpLabel(tlbl1->key);
8284 pic16_popReleaseTempReg(pctemp);
8288 pic16_freeAsmop (right,NULL,ic,TRUE);
8289 pic16_freeAsmop(left,NULL,ic,TRUE);
8290 pic16_freeAsmop(result,NULL,ic,TRUE);
8293 /*-----------------------------------------------------------------*/
8294 /* genrshOne - right shift a one byte quantity by known count */
8295 /*-----------------------------------------------------------------*/
8296 static void genrshOne (operand *result, operand *left,
8297 int shCount, int sign)
8299 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8300 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
8303 /*-----------------------------------------------------------------*/
8304 /* genrshTwo - right shift two bytes by known amount != 0 */
8305 /*-----------------------------------------------------------------*/
8306 static void genrshTwo (operand *result,operand *left,
8307 int shCount, int sign)
8309 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8310 /* if shCount >= 8 */
8314 shiftR1Left2Result(left, MSB16, result, LSB,
8317 movLeft2Result(left, MSB16, result, LSB);
8319 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8322 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
8323 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
8327 /* 1 <= shCount <= 7 */
8329 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
8332 /*-----------------------------------------------------------------*/
8333 /* shiftRLong - shift right one long from left to result */
8334 /* offl = LSB or MSB16 */
8335 /*-----------------------------------------------------------------*/
8336 static void shiftRLong (operand *left, int offl,
8337 operand *result, int sign)
8339 int size = AOP_SIZE(result);
8340 int same = pic16_sameRegs(AOP(left),AOP(result));
8342 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
8344 if (same && (offl == MSB16)) { //shift one byte right
8345 for(i=MSB16;i<size;i++) {
8346 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
8347 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
8352 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
8358 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
8360 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
8361 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
8365 /* add sign of "a" */
8366 pic16_addSign(result, MSB32, sign);
8370 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
8372 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
8373 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
8377 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
8379 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
8380 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
8384 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
8387 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
8388 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
8393 /*-----------------------------------------------------------------*/
8394 /* genrshFour - shift four byte by a known amount != 0 */
8395 /*-----------------------------------------------------------------*/
8396 static void genrshFour (operand *result, operand *left,
8397 int shCount, int sign)
8399 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8400 /* if shifting more that 3 bytes */
8401 if(shCount >= 24 ) {
8404 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8406 movLeft2Result(left, MSB32, result, LSB);
8408 pic16_addSign(result, MSB16, sign);
8410 else if(shCount >= 16){
8413 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8415 movLeft2Result(left, MSB24, result, LSB);
8416 movLeft2Result(left, MSB32, result, MSB16);
8418 pic16_addSign(result, MSB24, sign);
8420 else if(shCount >= 8){
8423 shiftRLong(left, MSB16, result, sign);
8424 else if(shCount == 0){
8425 movLeft2Result(left, MSB16, result, LSB);
8426 movLeft2Result(left, MSB24, result, MSB16);
8427 movLeft2Result(left, MSB32, result, MSB24);
8428 pic16_addSign(result, MSB32, sign);
8430 else{ //shcount >= 2
8431 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8432 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8433 /* the last shift is signed */
8434 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8435 pic16_addSign(result, MSB32, sign);
8438 else{ /* 1 <= shCount <= 7 */
8440 shiftRLong(left, LSB, result, sign);
8442 shiftRLong(result, LSB, result, sign);
8445 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8446 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8447 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8452 /*-----------------------------------------------------------------*/
8453 /* genRightShiftLiteral - right shifting by known count */
8454 /*-----------------------------------------------------------------*/
8455 static void genRightShiftLiteral (operand *left,
8461 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8464 pic16_freeAsmop(right,NULL,ic,TRUE);
8466 pic16_aopOp(left,ic,FALSE);
8467 pic16_aopOp(result,ic,FALSE);
8469 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8472 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8476 lsize = pic16_getDataSize(left);
8477 res_size = pic16_getDataSize(result);
8478 /* test the LEFT size !!! */
8480 /* I suppose that the left size >= result size */
8483 movLeft2Result(left, lsize, result, res_size);
8486 else if(shCount >= (lsize * 8)){
8489 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8491 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8492 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8497 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8498 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8499 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8501 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8506 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8513 genrshOne (result,left,shCount,sign);
8517 genrshTwo (result,left,shCount,sign);
8521 genrshFour (result,left,shCount,sign);
8529 pic16_freeAsmop(left,NULL,ic,TRUE);
8530 pic16_freeAsmop(result,NULL,ic,TRUE);
8533 /*-----------------------------------------------------------------*/
8534 /* genSignedRightShift - right shift of signed number */
8535 /*-----------------------------------------------------------------*/
8536 static void genSignedRightShift (iCode *ic)
8538 operand *right, *left, *result;
8541 symbol *tlbl, *tlbl1 ;
8544 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8546 /* we do it the hard way put the shift count in b
8547 and loop thru preserving the sign */
8548 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8550 right = IC_RIGHT(ic);
8552 result = IC_RESULT(ic);
8554 pic16_aopOp(right,ic,FALSE);
8555 pic16_aopOp(left,ic,FALSE);
8556 pic16_aopOp(result,ic,FALSE);
8559 if ( AOP_TYPE(right) == AOP_LIT) {
8560 genRightShiftLiteral (left,right,result,ic,1);
8563 /* shift count is unknown then we have to form
8564 a loop get the loop count in B : Note: we take
8565 only the lower order byte since shifting
8566 more that 32 bits make no sense anyway, ( the
8567 largest size of an object can be only 32 bits ) */
8569 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8570 //pic16_emitcode("inc","b");
8571 //pic16_freeAsmop (right,NULL,ic,TRUE);
8572 //pic16_aopOp(left,ic,FALSE);
8573 //pic16_aopOp(result,ic,FALSE);
8575 /* now move the left to the result if they are not the
8577 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8578 AOP_SIZE(result) > 1) {
8580 size = AOP_SIZE(result);
8584 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8585 if (*l == '@' && IS_AOP_PREG(result)) {
8587 pic16_emitcode("mov","a,%s",l);
8588 pic16_aopPut(AOP(result),"a",offset);
8590 pic16_aopPut(AOP(result),l,offset);
8592 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8593 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8599 /* mov the highest order bit to OVR */
8600 tlbl = newiTempLabel(NULL);
8601 tlbl1= newiTempLabel(NULL);
8603 size = AOP_SIZE(result);
8606 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8608 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8610 /* offset should be 0, 1 or 3 */
8611 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8613 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8615 pic16_emitpcode(POC_MOVWF, pctemp);
8618 pic16_emitpLabel(tlbl->key);
8620 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8621 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8624 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8627 pic16_emitpcode(POC_DECFSZ, pctemp);
8628 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8629 pic16_emitpLabel(tlbl1->key);
8631 pic16_popReleaseTempReg(pctemp);
8633 size = AOP_SIZE(result);
8635 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8636 pic16_emitcode("rlc","a");
8637 pic16_emitcode("mov","ov,c");
8638 /* if it is only one byte then */
8640 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8642 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8643 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8644 pic16_emitcode("mov","c,ov");
8645 pic16_emitcode("rrc","a");
8646 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8647 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8648 pic16_aopPut(AOP(result),"a",0);
8652 reAdjustPreg(AOP(result));
8653 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8654 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8655 pic16_emitcode("mov","c,ov");
8657 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8659 pic16_emitcode("rrc","a");
8660 pic16_aopPut(AOP(result),"a",offset--);
8662 reAdjustPreg(AOP(result));
8663 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8664 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8669 pic16_freeAsmop(left,NULL,ic,TRUE);
8670 pic16_freeAsmop(result,NULL,ic,TRUE);
8671 pic16_freeAsmop(right,NULL,ic,TRUE);
8674 /*-----------------------------------------------------------------*/
8675 /* genRightShift - generate code for right shifting */
8676 /*-----------------------------------------------------------------*/
8677 static void genRightShift (iCode *ic)
8679 operand *right, *left, *result;
8683 symbol *tlbl, *tlbl1 ;
8685 /* if signed then we do it the hard way preserve the
8686 sign bit moving it inwards */
8687 letype = getSpec(operandType(IC_LEFT(ic)));
8688 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8690 if (!SPEC_USIGN(letype)) {
8691 genSignedRightShift (ic);
8695 /* signed & unsigned types are treated the same : i.e. the
8696 signed is NOT propagated inwards : quoting from the
8697 ANSI - standard : "for E1 >> E2, is equivalent to division
8698 by 2**E2 if unsigned or if it has a non-negative value,
8699 otherwise the result is implementation defined ", MY definition
8700 is that the sign does not get propagated */
8702 right = IC_RIGHT(ic);
8704 result = IC_RESULT(ic);
8706 pic16_aopOp(right,ic,FALSE);
8708 /* if the shift count is known then do it
8709 as efficiently as possible */
8710 if (AOP_TYPE(right) == AOP_LIT) {
8711 genRightShiftLiteral (left,right,result,ic, 0);
8715 /* shift count is unknown then we have to form
8716 a loop get the loop count in B : Note: we take
8717 only the lower order byte since shifting
8718 more that 32 bits make no sense anyway, ( the
8719 largest size of an object can be only 32 bits ) */
8721 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8722 pic16_emitcode("inc","b");
8723 pic16_aopOp(left,ic,FALSE);
8724 pic16_aopOp(result,ic,FALSE);
8726 /* now move the left to the result if they are not the
8728 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8729 AOP_SIZE(result) > 1) {
8731 size = AOP_SIZE(result);
8734 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8735 if (*l == '@' && IS_AOP_PREG(result)) {
8737 pic16_emitcode("mov","a,%s",l);
8738 pic16_aopPut(AOP(result),"a",offset);
8740 pic16_aopPut(AOP(result),l,offset);
8745 tlbl = newiTempLabel(NULL);
8746 tlbl1= newiTempLabel(NULL);
8747 size = AOP_SIZE(result);
8750 /* if it is only one byte then */
8753 tlbl = newiTempLabel(NULL);
8754 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8755 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8756 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8759 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8760 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8761 pic16_emitpLabel(tlbl->key);
8762 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8763 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8765 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8770 reAdjustPreg(AOP(result));
8771 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8772 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8775 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8777 pic16_emitcode("rrc","a");
8778 pic16_aopPut(AOP(result),"a",offset--);
8780 reAdjustPreg(AOP(result));
8782 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8783 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8786 pic16_freeAsmop(left,NULL,ic,TRUE);
8787 pic16_freeAsmop (right,NULL,ic,TRUE);
8788 pic16_freeAsmop(result,NULL,ic,TRUE);
8791 /*-----------------------------------------------------------------*/
8792 /* genUnpackBits - generates code for unpacking bits */
8793 /*-----------------------------------------------------------------*/
8794 static void genUnpackBits (operand *result, char *rname, int ptype)
8801 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8802 etype = getSpec(operandType(result));
8804 /* read the first byte */
8811 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8814 pic16_emitcode("clr","a");
8815 pic16_emitcode("movc","a","@a+dptr");
8820 /* if we have bitdisplacement then it fits */
8821 /* into this byte completely or if length is */
8822 /* less than a byte */
8823 if ((shCnt = SPEC_BSTR(etype)) ||
8824 (SPEC_BLEN(etype) <= 8)) {
8826 /* shift right acc */
8829 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8830 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8832 /* VR -- normally I would use the following, but since we use the hack,
8833 * to avoid the masking from AccRsh, why not mask it right now? */
8836 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8839 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8845 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8846 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8849 /* bit field did not fit in a byte */
8850 rlen = SPEC_BLEN(etype) - 8;
8851 pic16_aopPut(AOP(result),"a",offset++);
8858 pic16_emitcode("inc","%s",rname);
8859 pic16_emitcode("mov","a,@%s",rname);
8863 pic16_emitcode("inc","%s",rname);
8864 pic16_emitcode("movx","a,@%s",rname);
8868 pic16_emitcode("inc","dptr");
8869 pic16_emitcode("movx","a,@dptr");
8873 pic16_emitcode("clr","a");
8874 pic16_emitcode("inc","dptr");
8875 pic16_emitcode("movc","a","@a+dptr");
8879 pic16_emitcode("inc","dptr");
8880 pic16_emitcode("lcall","__gptrget");
8885 /* if we are done */
8889 pic16_aopPut(AOP(result),"a",offset++);
8894 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8895 pic16_aopPut(AOP(result),"a",offset);
8902 static void genDataPointerGet(operand *left,
8906 int size, offset = 0, leoffset=0 ;
8908 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8909 pic16_aopOp(result, ic, FALSE);
8911 size = AOP_SIZE(result);
8912 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
8916 /* The following tests may save a redudant movff instruction when
8917 * accessing unions */
8919 /* if they are the same */
8920 if (operandsEqu (left, result)) {
8921 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
8927 /* if they are the same registers */
8928 if (pic16_sameRegs(AOP(left),AOP(result))) {
8929 DEBUGpic16_emitcode("; ***", "left and result registers are same");
8935 if ( AOP_TYPE(left) == AOP_PCODE) {
8936 fprintf(stderr,"genDataPointerGet %s, %d\n",
8937 AOP(left)->aopu.pcop->name,
8938 (AOP(left)->aopu.pcop->type == PO_DIR)?
8939 PCOR(AOP(left)->aopu.pcop)->instance:
8940 PCOI(AOP(left)->aopu.pcop)->offset);
8944 if(AOP(left)->aopu.pcop->type == PO_DIR)
8945 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
8947 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8950 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
8952 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
8953 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
8954 mov2w(AOP(left), offset); // patch 8
8955 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
8957 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
8958 pic16_popGet(AOP(left), offset), //patch 8
8959 pic16_popGet(AOP(result), offset)));
8967 pic16_freeAsmop(result,NULL,ic,TRUE);
8970 void pic16_loadFSR0(operand *op)
8972 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
8976 /*-----------------------------------------------------------------*/
8977 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8978 /*-----------------------------------------------------------------*/
8979 static void genNearPointerGet (operand *left,
8984 //regs *preg = NULL ;
8985 sym_link *rtype, *retype;
8986 sym_link *ltype = operandType(left);
8988 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8989 rtype = operandType(result);
8990 retype= getSpec(rtype);
8992 pic16_aopOp(left,ic,FALSE);
8994 pic16_DumpOp("(left)",left);
8995 pic16_DumpOp("(result)",result);
8997 /* if left is rematerialisable and
8998 * result is not bit variable type and
8999 * the left is pointer to data space i.e
9000 * lower 128 bytes of space */
9001 if (AOP_TYPE(left) == AOP_PCODE
9002 && !IS_BITFIELD(retype)
9003 && DCL_TYPE(ltype) == POINTER) {
9005 genDataPointerGet (left,result,ic);
9006 pic16_freeAsmop(left, NULL, ic, TRUE);
9010 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9012 /* if the value is already in a pointer register
9013 * then don't need anything more */
9014 if (!AOP_INPREG(AOP(left))) {
9015 /* otherwise get a free pointer register */
9016 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9018 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
9019 if( (AOP_TYPE(left) == AOP_PCODE)
9020 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9021 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
9023 pic16_loadFSR0( left ); // patch 10
9025 // set up FSR0 with address from left
9026 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9027 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9031 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9033 pic16_aopOp (result,ic,FALSE);
9035 /* if bitfield then unpack the bits */
9036 if (IS_BITFIELD(retype))
9037 genUnpackBits (result, NULL, POINTER);
9039 /* we have can just get the values */
9040 int size = AOP_SIZE(result);
9043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9046 /* fsr0 is loaded already -- VR */
9047 // pic16_loadFSR0( left );
9049 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
9050 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9054 pic16_emitpcode(POC_MOVFF,
9055 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
9056 pic16_popGet(AOP(result), offset++)));
9058 pic16_emitpcode(POC_MOVFF,
9059 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
9060 pic16_popGet(AOP(result), offset++)));
9064 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
9065 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
9067 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9071 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
9073 pic16_emitcode("mov","a,@%s",rname);
9074 pic16_aopPut(AOP(result),"a",offset);
9076 sprintf(buffer,"@%s",rname);
9077 pic16_aopPut(AOP(result),buffer,offset);
9081 pic16_emitcode("inc","%s",rname);
9086 /* now some housekeeping stuff */
9088 /* we had to allocate for this iCode */
9089 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9090 pic16_freeAsmop(NULL,aop,ic,TRUE);
9092 /* we did not allocate which means left
9093 already in a pointer register, then
9094 if size > 0 && this could be used again
9095 we have to point it back to where it
9097 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9098 if (AOP_SIZE(result) > 1 &&
9099 !OP_SYMBOL(left)->remat &&
9100 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9102 // int size = AOP_SIZE(result) - 1;
9104 // pic16_emitcode("dec","%s",rname);
9109 pic16_freeAsmop(left,NULL,ic,TRUE);
9110 pic16_freeAsmop(result,NULL,ic,TRUE);
9114 /*-----------------------------------------------------------------*/
9115 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
9116 /*-----------------------------------------------------------------*/
9117 static void genPagedPointerGet (operand *left,
9124 sym_link *rtype, *retype;
9126 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9128 rtype = operandType(result);
9129 retype= getSpec(rtype);
9131 pic16_aopOp(left,ic,FALSE);
9133 /* if the value is already in a pointer register
9134 then don't need anything more */
9135 if (!AOP_INPREG(AOP(left))) {
9136 /* otherwise get a free pointer register */
9138 preg = getFreePtr(ic,&aop,FALSE);
9139 pic16_emitcode("mov","%s,%s",
9141 pic16_aopGet(AOP(left),0,FALSE,TRUE));
9142 rname = preg->name ;
9144 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9146 pic16_freeAsmop(left,NULL,ic,TRUE);
9147 pic16_aopOp (result,ic,FALSE);
9149 /* if bitfield then unpack the bits */
9150 if (IS_BITFIELD(retype))
9151 genUnpackBits (result,rname,PPOINTER);
9153 /* we have can just get the values */
9154 int size = AOP_SIZE(result);
9159 pic16_emitcode("movx","a,@%s",rname);
9160 pic16_aopPut(AOP(result),"a",offset);
9165 pic16_emitcode("inc","%s",rname);
9169 /* now some housekeeping stuff */
9171 /* we had to allocate for this iCode */
9172 pic16_freeAsmop(NULL,aop,ic,TRUE);
9174 /* we did not allocate which means left
9175 already in a pointer register, then
9176 if size > 0 && this could be used again
9177 we have to point it back to where it
9179 if (AOP_SIZE(result) > 1 &&
9180 !OP_SYMBOL(left)->remat &&
9181 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9183 int size = AOP_SIZE(result) - 1;
9185 pic16_emitcode("dec","%s",rname);
9190 pic16_freeAsmop(result,NULL,ic,TRUE);
9195 /*-----------------------------------------------------------------*/
9196 /* genFarPointerGet - gget value from far space */
9197 /*-----------------------------------------------------------------*/
9198 static void genFarPointerGet (operand *left,
9199 operand *result, iCode *ic)
9202 sym_link *retype = getSpec(operandType(result));
9204 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9206 pic16_aopOp(left,ic,FALSE);
9208 /* if the operand is already in dptr
9209 then we do nothing else we move the value to dptr */
9210 if (AOP_TYPE(left) != AOP_STR) {
9211 /* if this is remateriazable */
9212 if (AOP_TYPE(left) == AOP_IMMD)
9213 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9214 else { /* we need to get it byte by byte */
9215 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9216 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9217 if (options.model == MODEL_FLAT24)
9219 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9223 /* so dptr know contains the address */
9224 pic16_freeAsmop(left,NULL,ic,TRUE);
9225 pic16_aopOp(result,ic,FALSE);
9227 /* if bit then unpack */
9228 if (IS_BITFIELD(retype))
9229 genUnpackBits(result,"dptr",FPOINTER);
9231 size = AOP_SIZE(result);
9235 pic16_emitcode("movx","a,@dptr");
9236 pic16_aopPut(AOP(result),"a",offset++);
9238 pic16_emitcode("inc","dptr");
9242 pic16_freeAsmop(result,NULL,ic,TRUE);
9245 /*-----------------------------------------------------------------*/
9246 /* genCodePointerGet - get value from code space */
9247 /*-----------------------------------------------------------------*/
9248 static void genCodePointerGet (operand *left,
9249 operand *result, iCode *ic)
9252 sym_link *retype = getSpec(operandType(result));
9254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9256 pic16_aopOp(left,ic,FALSE);
9258 /* if the operand is already in dptr
9259 then we do nothing else we move the value to dptr */
9260 if (AOP_TYPE(left) != AOP_STR) {
9261 /* if this is remateriazable */
9262 if (AOP_TYPE(left) == AOP_IMMD)
9263 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9264 else { /* we need to get it byte by byte */
9265 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9266 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9267 if (options.model == MODEL_FLAT24)
9269 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9273 /* so dptr know contains the address */
9274 pic16_freeAsmop(left,NULL,ic,TRUE);
9275 pic16_aopOp(result,ic,FALSE);
9277 /* if bit then unpack */
9278 if (IS_BITFIELD(retype))
9279 genUnpackBits(result,"dptr",CPOINTER);
9281 size = AOP_SIZE(result);
9285 pic16_emitcode("clr","a");
9286 pic16_emitcode("movc","a,@a+dptr");
9287 pic16_aopPut(AOP(result),"a",offset++);
9289 pic16_emitcode("inc","dptr");
9293 pic16_freeAsmop(result,NULL,ic,TRUE);
9296 /*-----------------------------------------------------------------*/
9297 /* genGenPointerGet - gget value from generic pointer space */
9298 /*-----------------------------------------------------------------*/
9299 static void genGenPointerGet (operand *left,
9300 operand *result, iCode *ic)
9302 int size, offset, lit;
9303 sym_link *retype = getSpec(operandType(result));
9305 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9306 pic16_aopOp(left,ic,FALSE);
9307 pic16_aopOp(result,ic,FALSE);
9308 size = AOP_SIZE(result);
9310 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9312 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
9314 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
9315 // load FSR0 from immediate
9316 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9318 // pic16_loadFSR0( left );
9323 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9325 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9332 else { /* we need to get it byte by byte */
9333 // set up FSR0 with address from left
9334 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9335 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9341 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9343 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9350 /* if bit then unpack */
9351 if (IS_BITFIELD(retype))
9352 genUnpackBits(result,"BAD",GPOINTER);
9355 pic16_freeAsmop(left,NULL,ic,TRUE);
9356 pic16_freeAsmop(result,NULL,ic,TRUE);
9360 /*-----------------------------------------------------------------*/
9361 /* genConstPointerGet - get value from const generic pointer space */
9362 /*-----------------------------------------------------------------*/
9363 static void genConstPointerGet (operand *left,
9364 operand *result, iCode *ic)
9366 //sym_link *retype = getSpec(operandType(result));
9367 // symbol *albl = newiTempLabel(NULL); // patch 15
9368 // symbol *blbl = newiTempLabel(NULL); //
9369 // PIC_OPCODE poc; // patch 15
9373 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9374 pic16_aopOp(left,ic,FALSE);
9375 pic16_aopOp(result,ic,TRUE);
9376 size = AOP_SIZE(result);
9378 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9380 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
9382 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
9383 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
9384 pic16_emitpLabel(albl->key);
9386 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
9388 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
9389 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
9390 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
9391 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
9392 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
9394 pic16_emitpLabel(blbl->key);
9396 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
9400 // set up table pointer
9401 if( (AOP_TYPE(left) == AOP_PCODE)
9402 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9403 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
9405 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
9406 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
9407 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
9408 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
9409 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
9410 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
9414 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
9415 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
9416 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
9422 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
9423 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
9427 pic16_freeAsmop(left,NULL,ic,TRUE);
9428 pic16_freeAsmop(result,NULL,ic,TRUE);
9431 /*-----------------------------------------------------------------*/
9432 /* genPointerGet - generate code for pointer get */
9433 /*-----------------------------------------------------------------*/
9434 static void genPointerGet (iCode *ic)
9436 operand *left, *result ;
9437 sym_link *type, *etype;
9440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9443 result = IC_RESULT(ic) ;
9445 /* depending on the type of pointer we need to
9446 move it to the correct pointer register */
9447 type = operandType(left);
9448 etype = getSpec(type);
9451 if (IS_PTR_CONST(type))
9453 if (IS_CODEPTR(type))
9455 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9457 /* if left is of type of pointer then it is simple */
9458 if (IS_PTR(type) && !IS_FUNC(type->next))
9459 p_type = DCL_TYPE(type);
9461 /* we have to go by the storage class */
9462 p_type = PTR_TYPE(SPEC_OCLS(etype));
9464 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9466 if (SPEC_OCLS(etype)->codesp ) {
9467 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9468 //p_type = CPOINTER ;
9471 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9472 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9473 /*p_type = FPOINTER ;*/
9475 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9476 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9477 /* p_type = PPOINTER; */
9479 if (SPEC_OCLS(etype) == idata )
9480 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9481 /* p_type = IPOINTER; */
9483 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9484 /* p_type = POINTER ; */
9487 /* now that we have the pointer type we assign
9488 the pointer values */
9493 genNearPointerGet (left,result,ic);
9497 genPagedPointerGet(left,result,ic);
9501 genFarPointerGet (left,result,ic);
9505 genConstPointerGet (left,result,ic);
9506 //pic16_emitcodePointerGet (left,result,ic);
9511 if (IS_PTR_CONST(type))
9512 genConstPointerGet (left,result,ic);
9515 genGenPointerGet (left,result,ic);
9521 /*-----------------------------------------------------------------*/
9522 /* genPackBits - generates code for packed bit storage */
9523 /*-----------------------------------------------------------------*/
9524 static void genPackBits (sym_link *etype ,
9526 char *rname, int p_type)
9534 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9535 blen = SPEC_BLEN(etype);
9536 bstr = SPEC_BSTR(etype);
9538 if(AOP_TYPE(right) == AOP_LIT) {
9539 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9542 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9544 /* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9547 /* if the bit lenth is less than or */
9548 /* it exactly fits a byte then */
9549 if((shCnt=SPEC_BSTR(etype))
9550 || SPEC_BLEN(etype) <= 8 ) {
9552 /* shift left acc */
9555 /* using PRODL as a temporary register here */
9556 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9562 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9563 // pic16_emitcode ("mov","b,a");
9564 // pic16_emitcode("mov","a,@%s",rname);
9568 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9569 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9570 (unsigned char)(0xff >> (8-bstr))) ));
9571 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9572 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9576 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9577 ((unsigned char)(0xFF << (blen+bstr)) |
9578 (unsigned char)(0xFF >> (8-bstr)) ) );
9579 pic16_emitcode ("orl","a,b");
9580 if (p_type == GPOINTER)
9581 pic16_emitcode("pop","b");
9586 pic16_emitcode("mov","@%s,a",rname);
9589 pic16_emitcode("movx","@dptr,a");
9592 DEBUGpic16_emitcode(";lcall","__gptrput");
9601 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9602 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9607 if ( SPEC_BLEN(etype) <= 8 )
9610 pic16_emitcode("inc","%s",rname);
9611 rLen = SPEC_BLEN(etype) ;
9615 /* now generate for lengths greater than one byte */
9618 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9628 pic16_emitcode("mov","@%s,a",rname);
9630 pic16_emitcode("mov","@%s,%s",rname,l);
9635 pic16_emitcode("movx","@dptr,a");
9640 DEBUGpic16_emitcode(";lcall","__gptrput");
9643 pic16_emitcode ("inc","%s",rname);
9648 /* last last was not complete */
9650 /* save the byte & read byte */
9653 pic16_emitcode ("mov","b,a");
9654 pic16_emitcode("mov","a,@%s",rname);
9658 pic16_emitcode ("mov","b,a");
9659 pic16_emitcode("movx","a,@dptr");
9663 pic16_emitcode ("push","b");
9664 pic16_emitcode ("push","acc");
9665 pic16_emitcode ("lcall","__gptrget");
9666 pic16_emitcode ("pop","b");
9670 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9671 pic16_emitcode ("orl","a,b");
9674 if (p_type == GPOINTER)
9675 pic16_emitcode("pop","b");
9680 pic16_emitcode("mov","@%s,a",rname);
9684 pic16_emitcode("movx","@dptr,a");
9688 DEBUGpic16_emitcode(";lcall","__gptrput");
9692 /*-----------------------------------------------------------------*/
9693 /* genDataPointerSet - remat pointer to data space */
9694 /*-----------------------------------------------------------------*/
9695 static void genDataPointerSet(operand *right,
9699 int size, offset = 0, resoffset=0 ;
9701 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9702 pic16_aopOp(right,ic,FALSE);
9704 size = AOP_SIZE(right);
9706 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9709 if ( AOP_TYPE(result) == AOP_PCODE) {
9710 fprintf(stderr,"genDataPointerSet %s, %d\n",
9711 AOP(result)->aopu.pcop->name,
9712 (AOP(result)->aopu.pcop->type == PO_DIR)?
9713 PCOR(AOP(result)->aopu.pcop)->instance:
9714 PCOI(AOP(result)->aopu.pcop)->offset);
9718 if(AOP(result)->aopu.pcop->type == PO_DIR)
9719 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9722 if (AOP_TYPE(right) == AOP_LIT) {
9723 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9725 lit = lit >> (8*offset);
9727 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9728 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
9730 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
9733 mov2w(AOP(right), offset);
9734 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
9740 pic16_freeAsmop(right,NULL,ic,TRUE);
9745 /*-----------------------------------------------------------------*/
9746 /* genNearPointerSet - pic16_emitcode for near pointer put */
9747 /*-----------------------------------------------------------------*/
9748 static void genNearPointerSet (operand *right,
9755 sym_link *ptype = operandType(result);
9758 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9759 retype= getSpec(operandType(right));
9760 resetype = getSpec(operandType(result));
9762 pic16_aopOp(result,ic,FALSE);
9764 /* if the result is rematerializable &
9765 * in data space & not a bit variable */
9767 /* and result is not a bit variable */
9768 if (AOP_TYPE(result) == AOP_PCODE
9769 // && AOP_TYPE(result) == AOP_IMMD
9770 && DCL_TYPE(ptype) == POINTER
9771 && !IS_BITFIELD(retype)
9772 && !IS_BITFIELD(resetype)) {
9774 genDataPointerSet (right,result,ic);
9775 pic16_freeAsmop(result,NULL,ic,TRUE);
9779 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9780 pic16_aopOp(right,ic,FALSE);
9781 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9783 /* if the value is already in a pointer register
9784 * then don't need anything more */
9785 if (!AOP_INPREG(AOP(result))) {
9786 /* otherwise get a free pointer register */
9787 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9789 if( (AOP_TYPE(result) == AOP_PCODE)
9790 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
9791 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
9793 pic16_loadFSR0( result ); // patch 10
9795 // set up FSR0 with address of result
9796 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9797 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9802 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9804 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9806 /* if bitfield then unpack the bits */
9807 if (IS_BITFIELD(resetype)) {
9808 genPackBits (resetype, right, NULL, POINTER);
9810 /* we have can just get the values */
9811 int size = AOP_SIZE(right);
9814 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9816 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9819 //pic16_emitcode("mov","@%s,a",rname);
9820 pic16_emitcode("movf","indf0,w ;1");
9823 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
9824 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
9826 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
9828 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
9830 } else { // no literal //
9832 pic16_emitpcode(POC_MOVFF, //
9833 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9834 pic16_popCopyReg(&pic16_pc_postinc0))); //
9836 pic16_emitpcode(POC_MOVFF, //
9837 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9838 pic16_popCopyReg(&pic16_pc_indf0))); //
9846 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9847 /* now some housekeeping stuff */
9849 /* we had to allocate for this iCode */
9850 pic16_freeAsmop(NULL,aop,ic,TRUE);
9852 /* we did not allocate which means left
9853 * already in a pointer register, then
9854 * if size > 0 && this could be used again
9855 * we have to point it back to where it
9857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9858 if (AOP_SIZE(right) > 1
9859 && !OP_SYMBOL(result)->remat
9860 && ( OP_SYMBOL(result)->liveTo > ic->seq
9863 int size = AOP_SIZE(right) - 1;
9866 pic16_emitcode("decf","fsr0,f");
9867 //pic16_emitcode("dec","%s",rname);
9871 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9874 pic16_freeAsmop(right,NULL,ic,TRUE);
9875 pic16_freeAsmop(result,NULL,ic,TRUE);
9878 /*-----------------------------------------------------------------*/
9879 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9880 /*-----------------------------------------------------------------*/
9881 static void genPagedPointerSet (operand *right,
9890 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9892 retype= getSpec(operandType(right));
9894 pic16_aopOp(result,ic,FALSE);
9896 /* if the value is already in a pointer register
9897 then don't need anything more */
9898 if (!AOP_INPREG(AOP(result))) {
9899 /* otherwise get a free pointer register */
9901 preg = getFreePtr(ic,&aop,FALSE);
9902 pic16_emitcode("mov","%s,%s",
9904 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9905 rname = preg->name ;
9907 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9909 pic16_freeAsmop(result,NULL,ic,TRUE);
9910 pic16_aopOp (right,ic,FALSE);
9912 /* if bitfield then unpack the bits */
9913 if (IS_BITFIELD(retype))
9914 genPackBits (retype,right,rname,PPOINTER);
9916 /* we have can just get the values */
9917 int size = AOP_SIZE(right);
9921 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9924 pic16_emitcode("movx","@%s,a",rname);
9927 pic16_emitcode("inc","%s",rname);
9933 /* now some housekeeping stuff */
9935 /* we had to allocate for this iCode */
9936 pic16_freeAsmop(NULL,aop,ic,TRUE);
9938 /* we did not allocate which means left
9939 already in a pointer register, then
9940 if size > 0 && this could be used again
9941 we have to point it back to where it
9943 if (AOP_SIZE(right) > 1 &&
9944 !OP_SYMBOL(result)->remat &&
9945 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9947 int size = AOP_SIZE(right) - 1;
9949 pic16_emitcode("dec","%s",rname);
9954 pic16_freeAsmop(right,NULL,ic,TRUE);
9959 /*-----------------------------------------------------------------*/
9960 /* genFarPointerSet - set value from far space */
9961 /*-----------------------------------------------------------------*/
9962 static void genFarPointerSet (operand *right,
9963 operand *result, iCode *ic)
9966 sym_link *retype = getSpec(operandType(right));
9968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9969 pic16_aopOp(result,ic,FALSE);
9971 /* if the operand is already in dptr
9972 then we do nothing else we move the value to dptr */
9973 if (AOP_TYPE(result) != AOP_STR) {
9974 /* if this is remateriazable */
9975 if (AOP_TYPE(result) == AOP_IMMD)
9976 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9977 else { /* we need to get it byte by byte */
9978 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9979 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9980 if (options.model == MODEL_FLAT24)
9982 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9986 /* so dptr know contains the address */
9987 pic16_freeAsmop(result,NULL,ic,TRUE);
9988 pic16_aopOp(right,ic,FALSE);
9990 /* if bit then unpack */
9991 if (IS_BITFIELD(retype))
9992 genPackBits(retype,right,"dptr",FPOINTER);
9994 size = AOP_SIZE(right);
9998 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10000 pic16_emitcode("movx","@dptr,a");
10002 pic16_emitcode("inc","dptr");
10006 pic16_freeAsmop(right,NULL,ic,TRUE);
10009 /*-----------------------------------------------------------------*/
10010 /* genGenPointerSet - set value from generic pointer space */
10011 /*-----------------------------------------------------------------*/
10012 static void genGenPointerSet (operand *right,
10013 operand *result, iCode *ic)
10015 int i, size, offset, lit;
10016 sym_link *retype = getSpec(operandType(right));
10018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10020 pic16_aopOp(result,ic,FALSE);
10021 pic16_aopOp(right,ic,FALSE);
10022 size = AOP_SIZE(right);
10025 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10027 /* if the operand is already in dptr
10028 then we do nothing else we move the value to dptr */
10029 if (AOP_TYPE(result) != AOP_STR) {
10030 /* if this is remateriazable */
10031 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10032 // WARNING: anythig until "else" is untested!
10033 if (AOP_TYPE(result) == AOP_IMMD) {
10034 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10035 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
10036 // load FSR0 from immediate
10037 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10041 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10043 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10049 else { /* we need to get it byte by byte */
10050 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10051 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10053 // set up FSR0 with address of result
10054 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10055 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10057 /* hack hack! see if this the FSR. If so don't load W */
10058 if(AOP_TYPE(right) != AOP_ACC) {
10060 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10062 if(AOP_TYPE(right) == AOP_LIT)
10065 // note: pic16_popGet handles sign extension
10066 for(i=0;i<size;i++) {
10067 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
10069 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
10071 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10076 for(i=0;i<size;i++) {
10078 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10079 pic16_popCopyReg(&pic16_pc_postinc0)));
10081 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10082 pic16_popCopyReg(&pic16_pc_indf0)));
10088 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10089 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10091 } // if (AOP_TYPE(result) != AOP_IMMD)
10093 } // if (AOP_TYPE(result) != AOP_STR)
10094 /* so dptr know contains the address */
10097 /* if bit then unpack */
10098 if (IS_BITFIELD(retype))
10099 genPackBits(retype,right,"dptr",GPOINTER);
10101 size = AOP_SIZE(right);
10104 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
10106 // set up FSR0 with address of result
10107 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10108 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10111 if (AOP_TYPE(right) == AOP_LIT) {
10112 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10114 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
10116 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10118 } else { // no literal
10120 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10122 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10130 pic16_freeAsmop(right,NULL,ic,TRUE);
10131 pic16_freeAsmop(result,NULL,ic,TRUE);
10134 /*-----------------------------------------------------------------*/
10135 /* genPointerSet - stores the value into a pointer location */
10136 /*-----------------------------------------------------------------*/
10137 static void genPointerSet (iCode *ic)
10139 operand *right, *result ;
10140 sym_link *type, *etype;
10143 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10145 right = IC_RIGHT(ic);
10146 result = IC_RESULT(ic) ;
10148 /* depending on the type of pointer we need to
10149 move it to the correct pointer register */
10150 type = operandType(result);
10151 etype = getSpec(type);
10152 /* if left is of type of pointer then it is simple */
10153 if (IS_PTR(type) && !IS_FUNC(type->next)) {
10154 p_type = DCL_TYPE(type);
10157 /* we have to go by the storage class */
10158 p_type = PTR_TYPE(SPEC_OCLS(etype));
10160 /* if (SPEC_OCLS(etype)->codesp ) { */
10161 /* p_type = CPOINTER ; */
10164 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10165 /* p_type = FPOINTER ; */
10167 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10168 /* p_type = PPOINTER ; */
10170 /* if (SPEC_OCLS(etype) == idata ) */
10171 /* p_type = IPOINTER ; */
10173 /* p_type = POINTER ; */
10176 /* now that we have the pointer type we assign
10177 the pointer values */
10182 genNearPointerSet (right,result,ic);
10186 genPagedPointerSet (right,result,ic);
10190 genFarPointerSet (right,result,ic);
10194 genGenPointerSet (right,result,ic);
10198 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10199 "genPointerSet: illegal pointer type");
10203 /*-----------------------------------------------------------------*/
10204 /* genIfx - generate code for Ifx statement */
10205 /*-----------------------------------------------------------------*/
10206 static void genIfx (iCode *ic, iCode *popIc)
10208 operand *cond = IC_COND(ic);
10211 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10213 pic16_aopOp(cond,ic,FALSE);
10215 /* get the value into acc */
10216 if (AOP_TYPE(cond) != AOP_CRY)
10217 pic16_toBoolean(cond);
10220 /* the result is now in the accumulator */
10221 pic16_freeAsmop(cond,NULL,ic,TRUE);
10223 /* if there was something to be popped then do it */
10227 /* if the condition is a bit variable */
10228 if (isbit && IS_ITEMP(cond) &&
10230 genIfxJump(ic,SPIL_LOC(cond)->rname);
10231 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
10234 if (isbit && !IS_ITEMP(cond))
10235 genIfxJump(ic,OP_SYMBOL(cond)->rname);
10237 genIfxJump(ic,"a");
10243 /*-----------------------------------------------------------------*/
10244 /* genAddrOf - generates code for address of */
10245 /*-----------------------------------------------------------------*/
10246 static void genAddrOf (iCode *ic)
10248 operand *result, *left;
10250 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
10251 pCodeOp *pcop0, *pcop1, *pcop2;
10253 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10255 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
10256 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
10258 sym = OP_SYMBOL( left );
10260 size = AOP_SIZE(IC_RESULT(ic));
10262 if(pic16_debug_verbose) {
10263 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
10264 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
10267 /* Assume that what we want the address of is in data space
10268 * since there is no stack on the PIC, yet! -- VR */
10270 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10273 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10276 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10280 pic16_emitpcode(POC_MOVLW, pcop0);
10281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10282 pic16_emitpcode(POC_MOVLW, pcop1);
10283 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10284 pic16_emitpcode(POC_MOVLW, pcop2);
10285 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10288 pic16_emitpcode(POC_MOVLW, pcop0);
10289 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10290 pic16_emitpcode(POC_MOVLW, pcop1);
10291 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10293 pic16_emitpcode(POC_MOVLW, pcop0);
10294 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10297 pic16_freeAsmop(result,NULL,ic,TRUE);
10298 pic16_freeAsmop(left, NULL, ic, FALSE);
10303 /*-----------------------------------------------------------------*/
10304 /* genFarFarAssign - assignment when both are in far space */
10305 /*-----------------------------------------------------------------*/
10306 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
10308 int size = AOP_SIZE(right);
10311 /* first push the right side on to the stack */
10313 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10315 pic16_emitcode ("push","acc");
10318 pic16_freeAsmop(right,NULL,ic,FALSE);
10319 /* now assign DPTR to result */
10320 pic16_aopOp(result,ic,FALSE);
10321 size = AOP_SIZE(result);
10323 pic16_emitcode ("pop","acc");
10324 pic16_aopPut(AOP(result),"a",--offset);
10326 pic16_freeAsmop(result,NULL,ic,FALSE);
10331 /*-----------------------------------------------------------------*/
10332 /* genAssign - generate code for assignment */
10333 /*-----------------------------------------------------------------*/
10334 static void genAssign (iCode *ic)
10336 operand *result, *right;
10337 int size, offset,know_W;
10338 unsigned long lit = 0L;
10340 result = IC_RESULT(ic);
10341 right = IC_RIGHT(ic) ;
10343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10345 /* if they are the same */
10346 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
10349 pic16_aopOp(right,ic,FALSE);
10350 pic16_aopOp(result,ic,TRUE);
10352 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10354 /* if they are the same registers */
10355 if (pic16_sameRegs(AOP(right),AOP(result)))
10358 /* if the result is a bit */
10359 if (AOP_TYPE(result) == AOP_CRY) {
10360 /* if the right size is a literal then
10361 we know what the value is */
10362 if (AOP_TYPE(right) == AOP_LIT) {
10364 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10365 pic16_popGet(AOP(result),0));
10367 if (((int) operandLitValue(right)))
10368 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10369 AOP(result)->aopu.aop_dir,
10370 AOP(result)->aopu.aop_dir);
10372 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10373 AOP(result)->aopu.aop_dir,
10374 AOP(result)->aopu.aop_dir);
10378 /* the right is also a bit variable */
10379 if (AOP_TYPE(right) == AOP_CRY) {
10380 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10381 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10382 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10384 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10385 AOP(result)->aopu.aop_dir,
10386 AOP(result)->aopu.aop_dir);
10387 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
10388 AOP(right)->aopu.aop_dir,
10389 AOP(right)->aopu.aop_dir);
10390 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10391 AOP(result)->aopu.aop_dir,
10392 AOP(result)->aopu.aop_dir);
10396 /* we need to or */
10397 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10398 pic16_toBoolean(right);
10400 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10401 //pic16_aopPut(AOP(result),"a",0);
10405 /* bit variables done */
10407 size = AOP_SIZE(result);
10409 if(AOP_TYPE(right) == AOP_LIT)
10410 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10412 /* VR - What is this?! */
10413 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
10414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10415 if(aopIdx(AOP(result),0) == 4) {
10416 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10417 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10418 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10421 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
10426 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10427 if(AOP_TYPE(right) == AOP_LIT) {
10429 if(know_W != (lit&0xff))
10430 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
10432 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10434 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10438 } else if (AOP_TYPE(right) == AOP_CRY) {
10439 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10441 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
10442 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10444 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
10445 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10446 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10451 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
10452 normally should work, but mind that the W register live range
10453 is not checked, so if the code generator assumes that the W
10454 is already loaded after such a pair, wrong code will be generated.
10456 Checking the live range is the next step.
10457 This is experimental code yet and has not been fully tested yet.
10458 USE WITH CARE. Revert to old code by setting 0 to the condition above.
10459 Vangelis Rokas 030603 (vrokas@otenet.gr) */
10461 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
10463 /* This is the old code, which is assumed(?!) that works fine(!?) */
10465 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10466 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10475 pic16_freeAsmop (right,NULL,ic,FALSE);
10476 pic16_freeAsmop (result,NULL,ic,TRUE);
10479 /*-----------------------------------------------------------------*/
10480 /* genJumpTab - generates code for jump table */
10481 /*-----------------------------------------------------------------*/
10482 static void genJumpTab (iCode *ic)
10487 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10489 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10490 /* get the condition into accumulator */
10491 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10493 /* multiply by three */
10494 pic16_emitcode("add","a,acc");
10495 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10497 jtab = newiTempLabel(NULL);
10498 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10499 pic16_emitcode("jmp","@a+dptr");
10500 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10502 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10503 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10505 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10506 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10507 pic16_emitpLabel(jtab->key);
10509 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10511 /* now generate the jump labels */
10512 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10513 jtab = setNextItem(IC_JTLABELS(ic))) {
10514 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10515 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10521 /*-----------------------------------------------------------------*/
10522 /* genMixedOperation - gen code for operators between mixed types */
10523 /*-----------------------------------------------------------------*/
10525 TSD - Written for the PIC port - but this unfortunately is buggy.
10526 This routine is good in that it is able to efficiently promote
10527 types to different (larger) sizes. Unfortunately, the temporary
10528 variables that are optimized out by this routine are sometimes
10529 used in other places. So until I know how to really parse the
10530 iCode tree, I'm going to not be using this routine :(.
10532 static int genMixedOperation (iCode *ic)
10535 operand *result = IC_RESULT(ic);
10536 sym_link *ctype = operandType(IC_LEFT(ic));
10537 operand *right = IC_RIGHT(ic);
10543 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10545 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10551 nextright = IC_RIGHT(nextic);
10552 nextleft = IC_LEFT(nextic);
10553 nextresult = IC_RESULT(nextic);
10555 pic16_aopOp(right,ic,FALSE);
10556 pic16_aopOp(result,ic,FALSE);
10557 pic16_aopOp(nextright, nextic, FALSE);
10558 pic16_aopOp(nextleft, nextic, FALSE);
10559 pic16_aopOp(nextresult, nextic, FALSE);
10561 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10563 operand *t = right;
10567 pic16_emitcode(";remove right +","");
10569 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10571 operand *t = right;
10575 pic16_emitcode(";remove left +","");
10579 big = AOP_SIZE(nextleft);
10580 small = AOP_SIZE(nextright);
10582 switch(nextic->op) {
10585 pic16_emitcode(";optimize a +","");
10586 /* if unsigned or not an integral type */
10587 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10588 pic16_emitcode(";add a bit to something","");
10591 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10593 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10594 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10595 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10597 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10605 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10606 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10607 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10610 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10612 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10613 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10614 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10615 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10616 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10619 pic16_emitcode("rlf","known_zero,w");
10626 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10627 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10628 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10630 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10640 pic16_freeAsmop(right,NULL,ic,TRUE);
10641 pic16_freeAsmop(result,NULL,ic,TRUE);
10642 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10643 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10645 nextic->generated = 1;
10652 /*-----------------------------------------------------------------*/
10653 /* genCast - gen code for casting */
10654 /*-----------------------------------------------------------------*/
10655 static void genCast (iCode *ic)
10657 operand *result = IC_RESULT(ic);
10658 sym_link *ctype = operandType(IC_LEFT(ic));
10659 sym_link *rtype = operandType(IC_RIGHT(ic));
10660 operand *right = IC_RIGHT(ic);
10663 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10664 /* if they are equivalent then do nothing */
10665 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10668 pic16_aopOp(right,ic,FALSE) ;
10669 pic16_aopOp(result,ic,FALSE);
10671 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10673 /* if the result is a bit */
10674 if (AOP_TYPE(result) == AOP_CRY) {
10676 /* if the right size is a literal then
10677 * we know what the value is */
10678 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10680 if (AOP_TYPE(right) == AOP_LIT) {
10681 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10682 pic16_popGet(AOP(result),0));
10684 if (((int) operandLitValue(right)))
10685 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10686 AOP(result)->aopu.aop_dir,
10687 AOP(result)->aopu.aop_dir);
10689 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10690 AOP(result)->aopu.aop_dir,
10691 AOP(result)->aopu.aop_dir);
10695 /* the right is also a bit variable */
10696 if (AOP_TYPE(right) == AOP_CRY) {
10698 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10700 pic16_emitcode("clrc","");
10701 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10702 AOP(right)->aopu.aop_dir,
10703 AOP(right)->aopu.aop_dir);
10704 pic16_aopPut(AOP(result),"c",0);
10708 /* we need to or */
10709 if (AOP_TYPE(right) == AOP_REG) {
10710 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10711 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10712 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10714 pic16_toBoolean(right);
10715 pic16_aopPut(AOP(result),"a",0);
10719 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10722 size = AOP_SIZE(result);
10724 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10726 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10727 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10728 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10731 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10736 /* if they are the same size : or less */
10737 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10739 /* if they are in the same place */
10740 if (pic16_sameRegs(AOP(right),AOP(result)))
10743 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10745 if (IS_PTR_CONST(rtype))
10747 if (IS_CODEPTR(rtype))
10749 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10752 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10754 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10756 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10759 if(AOP_TYPE(right) == AOP_IMMD) {
10760 pCodeOp *pcop0, *pcop1, *pcop2;
10761 symbol *sym = OP_SYMBOL( right );
10763 size = AOP_SIZE(result);
10765 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10767 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10769 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10772 pic16_emitpcode(POC_MOVLW, pcop0);
10773 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10774 pic16_emitpcode(POC_MOVLW, pcop1);
10775 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10776 pic16_emitpcode(POC_MOVLW, pcop2);
10777 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10780 pic16_emitpcode(POC_MOVLW, pcop0);
10781 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10782 pic16_emitpcode(POC_MOVLW, pcop1);
10783 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10785 pic16_emitpcode(POC_MOVLW, pcop0);
10786 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10790 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10791 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10792 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10793 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10794 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10795 if(AOP_SIZE(result) <2)
10796 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10798 /* if they in different places then copy */
10799 size = AOP_SIZE(result);
10802 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10803 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10810 /* if the result is of type pointer */
10811 if (IS_PTR(ctype)) {
10813 sym_link *type = operandType(right);
10814 sym_link *etype = getSpec(type);
10816 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10818 /* pointer to generic pointer */
10819 if (IS_GENPTR(ctype)) {
10823 p_type = DCL_TYPE(type);
10825 /* we have to go by the storage class */
10826 p_type = PTR_TYPE(SPEC_OCLS(etype));
10828 /* if (SPEC_OCLS(etype)->codesp ) */
10829 /* p_type = CPOINTER ; */
10831 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10832 /* p_type = FPOINTER ; */
10834 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10835 /* p_type = PPOINTER; */
10837 /* if (SPEC_OCLS(etype) == idata ) */
10838 /* p_type = IPOINTER ; */
10840 /* p_type = POINTER ; */
10843 /* the first two bytes are known */
10844 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10845 size = GPTRSIZE - 1;
10848 if(offset < AOP_SIZE(right)) {
10849 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10850 if ((AOP_TYPE(right) == AOP_PCODE) &&
10851 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10852 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10855 pic16_aopPut(AOP(result),
10856 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10860 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10863 /* the last byte depending on type */
10867 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10870 pic16_emitcode(";BUG!? ","%d",__LINE__);
10874 pic16_emitcode(";BUG!? ","%d",__LINE__);
10878 pic16_emitcode(";BUG!? ","%d",__LINE__);
10883 /* this should never happen */
10884 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10885 "got unknown pointer type");
10888 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10892 /* just copy the pointers */
10893 size = AOP_SIZE(result);
10896 pic16_aopPut(AOP(result),
10897 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10906 /* so we now know that the size of destination is greater
10907 than the size of the source.
10908 Now, if the next iCode is an operator then we might be
10909 able to optimize the operation without performing a cast.
10911 if(genMixedOperation(ic))
10914 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10916 /* we move to result for the size of source */
10917 size = AOP_SIZE(right);
10920 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10921 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10925 /* now depending on the sign of the destination */
10926 size = AOP_SIZE(result) - AOP_SIZE(right);
10927 /* if unsigned or not an integral type */
10928 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
10930 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10932 /* we need to extend the sign :( */
10935 /* Save one instruction of casting char to int */
10936 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10937 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10938 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10940 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10943 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10945 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10947 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10950 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10955 pic16_freeAsmop(right,NULL,ic,TRUE);
10956 pic16_freeAsmop(result,NULL,ic,TRUE);
10960 /*-----------------------------------------------------------------*/
10961 /* genDjnz - generate decrement & jump if not zero instrucion */
10962 /*-----------------------------------------------------------------*/
10963 static int genDjnz (iCode *ic, iCode *ifx)
10965 symbol *lbl, *lbl1;
10966 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10971 /* if the if condition has a false label
10972 then we cannot save */
10976 /* if the minus is not of the form
10978 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10979 !IS_OP_LITERAL(IC_RIGHT(ic)))
10982 if (operandLitValue(IC_RIGHT(ic)) != 1)
10985 /* if the size of this greater than one then no
10987 if (getSize(operandType(IC_RESULT(ic))) > 1)
10990 /* otherwise we can save BIG */
10991 lbl = newiTempLabel(NULL);
10992 lbl1= newiTempLabel(NULL);
10994 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10996 if (IS_AOP_PREG(IC_RESULT(ic))) {
10997 pic16_emitcode("dec","%s",
10998 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10999 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11000 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
11004 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
11005 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
11007 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11008 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
11011 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
11012 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
11013 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
11014 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
11017 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11018 ifx->generated = 1;
11022 /*-----------------------------------------------------------------*/
11023 /* genReceive - generate code for a receive iCode */
11024 /*-----------------------------------------------------------------*/
11025 static void genReceive (iCode *ic)
11027 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11029 if (isOperandInFarSpace(IC_RESULT(ic)) &&
11030 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
11031 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
11033 int size = getSize(operandType(IC_RESULT(ic)));
11034 int offset = pic16_fReturnSizePic - size;
11037 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
11038 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
11042 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
11044 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11045 size = AOP_SIZE(IC_RESULT(ic));
11048 pic16_emitcode ("pop","acc");
11049 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
11052 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
11055 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11057 assignResultValue(IC_RESULT(ic), 0);
11060 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11063 /*-----------------------------------------------------------------*/
11064 /* genDummyRead - generate code for dummy read of volatiles */
11065 /*-----------------------------------------------------------------*/
11067 genDummyRead (iCode * ic)
11069 pic16_emitcode ("; genDummyRead","");
11070 pic16_emitcode ("; not implemented","");
11075 /*-----------------------------------------------------------------*/
11076 /* genpic16Code - generate code for pic16 based controllers */
11077 /*-----------------------------------------------------------------*/
11079 * At this point, ralloc.c has gone through the iCode and attempted
11080 * to optimize in a way suitable for a PIC. Now we've got to generate
11081 * PIC instructions that correspond to the iCode.
11083 * Once the instructions are generated, we'll pass through both the
11084 * peep hole optimizer and the pCode optimizer.
11085 *-----------------------------------------------------------------*/
11087 void genpic16Code (iCode *lic)
11092 lineHead = lineCurr = NULL;
11094 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
11095 pic16_addpBlock(pb);
11098 /* if debug information required */
11099 if (options.debug && currFunc) {
11101 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
11103 if (IS_STATIC(currFunc->etype)) {
11104 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
11105 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
11107 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
11108 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
11115 for (ic = lic ; ic ; ic = ic->next ) {
11117 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
11118 if ( cln != ic->lineno ) {
11119 if ( options.debug ) {
11121 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
11122 FileBaseName(ic->filename),ic->lineno,
11123 ic->level,ic->block);
11127 if(!options.noCcodeInAsm) {
11128 pic16_addpCode2pBlock(pb,
11129 pic16_newpCodeCSource(ic->lineno, ic->filename,
11130 printCLine(ic->filename, ic->lineno)));
11136 if(options.iCodeInAsm) {
11137 /* insert here code to print iCode as comment */
11138 pic16_emitpcomment("ic:%d: %s", ic->seq, printILine(ic));
11141 /* if the result is marked as
11142 spilt and rematerializable or code for
11143 this has already been generated then
11145 if (resultRemat(ic) || ic->generated )
11148 /* depending on the operation */
11167 /* IPOP happens only when trying to restore a
11168 spilt live range, if there is an ifx statement
11169 following this pop then the if statement might
11170 be using some of the registers being popped which
11171 would destroy the contents of the register so
11172 we need to check for this condition and handle it */
11174 ic->next->op == IFX &&
11175 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
11176 genIfx (ic->next,ic);
11194 genEndFunction (ic);
11210 pic16_genPlus (ic) ;
11214 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
11215 pic16_genMinus (ic);
11231 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
11235 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
11242 /* note these two are xlated by algebraic equivalence
11243 during parsing SDCC.y */
11244 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11245 "got '>=' or '<=' shouldn't have come here");
11249 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
11261 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
11265 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
11269 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
11293 genRightShift (ic);
11296 case GET_VALUE_AT_ADDRESS:
11301 if (POINTER_SET(ic))
11328 addSet(&_G.sendSet,ic);
11331 case DUMMY_READ_VOLATILE:
11341 /* now we are ready to call the
11342 peep hole optimizer */
11343 if (!options.nopeep) {
11344 peepHole (&lineHead);
11346 /* now do the actual printing */
11347 printLine (lineHead,codeOutFile);
11350 DFPRINTF((stderr,"printing pBlock\n\n"));
11351 pic16_printpBlock(stdout,pb);