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)
9 - Vangelis Rokas vrokas@otenet.gr (2003,2004)
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 In other words, you are welcome to use, share and improve this program.
26 You are forbidden to forbid anyone else to use, share and improve
27 what you give them. Help stamp out software-hoarding!
30 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
31 Made everything static
32 -------------------------------------------------------------------------*/
38 #include "SDCCglobl.h"
42 #include "SDCCpeeph.h"
50 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
51 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
52 void pic16_genMult8X8_8 (operand *, operand *,operand *);
53 void pic16_genMult16X16_16(operand *, operand *, operand *);
54 void pic16_genMult32X32_32(operand *, operand *, operand *);
55 pCode *pic16_AssembleLine(char *line, int peeps);
56 extern void pic16_printpBlock(FILE *of, pBlock *pb);
57 static asmop *newAsmop (short type);
58 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op);
59 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
60 static void mov2w (asmop *aop, int offset);
61 static void mov2f(asmop *dst, asmop *src, int offset);
62 static void mov2fp(pCodeOp *dst, asmop *src, int offset);
63 static pCodeOp *pic16_popRegFromIdx(int rIdx);
65 //static int aopIdx (asmop *aop, int offset);
67 int pic16_labelOffset=0;
68 extern int pic16_debug_verbose;
69 static int optimized_for_speed = 0;
75 /* max_key keeps track of the largest label number used in
76 a function. This is then used to adjust the label offset
77 for the next function.
80 static int GpsuedoStkPtr=0;
82 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
84 unsigned int pic16aopLiteral (value *val, int offset);
85 const char *pic16_AopType(short type);
86 static iCode *ifxForOp ( operand *op, iCode *ic );
88 void pic16_pushpCodeOp(pCodeOp *pcop);
89 void pic16_poppCodeOp(pCodeOp *pcop);
91 static bool is_LitOp(operand *op);
92 static bool is_LitAOp(asmop *aop);
95 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
97 /* set the following macro to 1 to enable passing the
98 * first byte of functions parameters via WREG */
99 #define USE_WREG_IN_FUNC_PARAMS 0
102 /* this is the down and dirty file with all kinds of
103 kludgy & hacky stuff. This is what it is all about
104 CODE GENERATION for a specific MCU . some of the
105 routines may be reusable, will have to see */
107 static char *zero = "#0x00";
108 static char *one = "#0x01";
109 //static char *spname = "sp";
113 * Function return value policy (MSB-->LSB):
115 * 16 bits -> PRODL:WREG
116 * 24 bits -> PRODH:PRODL:WREG
117 * 32 bits -> FSR0L:PRODH:PRODL:WREG
118 * >32 bits -> on stack, and FSR0 points to the beginning
123 char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
124 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
125 static char **fReturn = fReturnpic16;
127 static char *accUse[] = {"WREG"};
129 //static short rbank = -1;
145 int stack_lat; /* stack offset latency */
147 int useWreg; /* flag when WREG is used to pass function parameter */
150 /* Resolved ifx structure. This structure stores information
151 about an iCode ifx that makes it easier to generate code.
153 typedef struct resolvedIfx {
154 symbol *lbl; /* pointer to a label */
155 int condition; /* true or false ifx */
156 int generated; /* set true when the code associated with the ifx
160 extern int pic16_ptrRegReq ;
161 extern int pic16_nRegs;
162 extern FILE *codeOutFile;
163 //static void saverbank (int, iCode *,bool);
165 static lineNode *lineHead = NULL;
166 static lineNode *lineCurr = NULL;
168 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
169 0xE0, 0xC0, 0x80, 0x00};
170 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
171 0x07, 0x03, 0x01, 0x00};
175 /*-----------------------------------------------------------------*/
176 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
177 /* exponent of 2 is returned, otherwise -1 is */
179 /* note that this is similar to the function `powof2' in SDCCsymt */
183 /*-----------------------------------------------------------------*/
184 static int my_powof2 (unsigned long num)
187 if( (num & (num-1)) == 0) {
200 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
202 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
204 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
205 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
206 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
207 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
208 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
209 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
210 ((result) ? AOP_SIZE(result) : 0));
213 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
216 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
218 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
219 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
220 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
221 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
222 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
223 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
227 void pic16_emitpcomment (char *fmt, ...)
230 char lb[INITIAL_INLINEASM];
236 vsprintf(lb+1,fmt,ap);
238 while (isspace(*lbp)) lbp++;
241 lineCurr = (lineCurr ?
242 connectLine(lineCurr,newLineNode(lb)) :
243 (lineHead = newLineNode(lb)));
244 lineCurr->isInline = _G.inLine;
245 lineCurr->isDebug = _G.debugLine;
247 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
250 // fprintf(stderr, "%s\n", lb);
253 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
256 char lb[INITIAL_INLINEASM];
259 if(!pic16_debug_verbose)
266 sprintf(lb,"%s\t",inst);
268 sprintf(lb,"%s",inst);
269 vsprintf(lb+(strlen(lb)),fmt,ap);
273 while (isspace(*lbp)) lbp++;
276 lineCurr = (lineCurr ?
277 connectLine(lineCurr,newLineNode(lb)) :
278 (lineHead = newLineNode(lb)));
279 lineCurr->isInline = _G.inLine;
280 lineCurr->isDebug = _G.debugLine;
282 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
285 // fprintf(stderr, "%s\n", lb);
288 void pic16_emitpLabel(int key)
290 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset));
293 void pic16_emitpLabelFORCE(int key)
295 pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
298 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
302 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
304 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
307 void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop)
310 pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop));
312 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
315 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
318 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
324 #define pic16_emitcode DEBUGpic16_emitcode
326 /*-----------------------------------------------------------------*/
327 /* pic16_emitcode - writes the code into a file : for now it is simple */
328 /*-----------------------------------------------------------------*/
329 void pic16_emitcode (char *inst,char *fmt, ...)
332 char lb[INITIAL_INLINEASM];
339 sprintf(lb,"%s\t",inst);
341 sprintf(lb,"%s",inst);
342 vsprintf(lb+(strlen(lb)),fmt,ap);
346 while (isspace(*lbp)) lbp++;
349 lineCurr = (lineCurr ?
350 connectLine(lineCurr,newLineNode(lb)) :
351 (lineHead = newLineNode(lb)));
352 lineCurr->isInline = _G.inLine;
353 lineCurr->isDebug = _G.debugLine;
355 // VR fprintf(stderr, "lb = <%s>\n", lbp);
357 // if(pic16_debug_verbose)
358 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
365 /*-----------------------------------------------------------------*/
366 /* pic16_emitDebuggerSymbol - associate the current code location */
367 /* with a debugger symbol */
368 /*-----------------------------------------------------------------*/
370 pic16_emitDebuggerSymbol (char * debugSym)
373 pic16_emitcode (";", "%s ==.", debugSym);
378 /*-----------------------------------------------------------------*/
379 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
380 /*-----------------------------------------------------------------*/
381 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
383 // bool r0iu = FALSE , r1iu = FALSE;
384 // bool r0ou = FALSE , r1ou = FALSE;
385 bool fsr0iu = FALSE, fsr0ou;
386 bool fsr2iu = FALSE, fsr2ou;
388 fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
391 fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
392 fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
394 fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
395 fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
397 if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
398 fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
399 DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
402 if(!fsr0iu && !fsr0ou) {
403 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
404 (*aopp)->type = AOP_FSR0;
406 fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
408 return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
412 /* no usage of FSR2 */
413 if(!fsr2iu && !fsr2ou) {
414 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
415 (*aopp)->type = AOP_FSR2;
417 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
421 /* now we know they both have usage */
422 /* if fsr0 not used in this instruction */
424 if (!_G.fsr0Pushed) {
425 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
426 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
430 ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
431 (*aopp)->type = AOP_FSR0;
433 // fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__);
435 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
439 fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
444 /* the logic: if r0 & r1 used in the instruction
445 then we are in trouble otherwise */
447 /* first check if r0 & r1 are used by this
448 instruction, in which case we are in trouble */
449 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
450 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
455 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
456 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
458 /* if no usage of r0 then return it */
459 if (!r0iu && !r0ou) {
460 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
461 (*aopp)->type = AOP_R0;
463 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
466 /* if no usage of r1 then return it */
467 if (!r1iu && !r1ou) {
468 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
469 (*aopp)->type = AOP_R1;
471 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
474 /* now we know they both have usage */
475 /* if r0 not used in this instruction */
477 /* push it if not already pushed */
479 //pic16_emitcode ("push","%s",
480 // pic16_regWithIdx(R0_IDX)->dname);
484 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
485 (*aopp)->type = AOP_R0;
487 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
490 /* if r1 not used then */
493 /* push it if not already pushed */
495 //pic16_emitcode ("push","%s",
496 // pic16_regWithIdx(R1_IDX)->dname);
500 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
501 (*aopp)->type = AOP_R1;
502 return pic16_regWithIdx(R1_IDX);
506 /* I said end of world but not quite end of world yet */
507 /* if this is a result then we can push it on the stack*/
509 (*aopp)->type = AOP_STK;
513 /* other wise this is true end of the world */
514 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
515 "getFreePtr should never reach here");
520 /*-----------------------------------------------------------------*/
521 /* newAsmop - creates a new asmOp */
522 /*-----------------------------------------------------------------*/
523 static asmop *newAsmop (short type)
527 aop = Safe_calloc(1,sizeof(asmop));
532 static void genSetDPTR(int n)
536 pic16_emitcode(";", "Select standard DPTR");
537 pic16_emitcode("mov", "dps, #0x00");
541 pic16_emitcode(";", "Select alternate DPTR");
542 pic16_emitcode("mov", "dps, #0x01");
546 /*-----------------------------------------------------------------*/
547 /* resolveIfx - converts an iCode ifx into a form more useful for */
548 /* generating code */
549 /*-----------------------------------------------------------------*/
550 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
553 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
559 resIfx->condition = 1; /* assume that the ifx is true */
560 resIfx->generated = 0; /* indicate that the ifx has not been used */
563 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
566 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
567 __FUNCTION__,__LINE__,resIfx->lbl->key);
572 resIfx->lbl = IC_TRUE(ifx);
574 resIfx->lbl = IC_FALSE(ifx);
575 resIfx->condition = 0;
580 DEBUGpic16_emitcode("; ***","ifx true is non-null");
582 DEBUGpic16_emitcode("; ***","ifx false is non-null");
586 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset);
590 /*-----------------------------------------------------------------*/
591 /* pointerCode - returns the code for a pointer type */
592 /*-----------------------------------------------------------------*/
593 static int pointerCode (sym_link *etype)
596 return PTR_TYPE(SPEC_OCLS(etype));
601 /*-----------------------------------------------------------------*/
602 /* aopForSym - for a true symbol */
603 /*-----------------------------------------------------------------*/
604 static asmop *aopForSym (iCode *ic, operand *op, bool result)
606 symbol *sym=OP_SYMBOL(op);
608 memmap *space= SPEC_OCLS(sym->etype);
610 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
612 _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
614 // sym = OP_SYMBOL(op);
616 /* if already has one */
618 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
623 /* if symbol was initially placed onStack then we must re-place it
624 * to direct memory, since pic16 does not have a specific stack */
626 fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
631 /* assign depending on the storage class */
632 /* if it is on the stack or indirectly addressable */
633 /* space we need to assign either r0 or r1 to it */
634 if (sym->onStack || sym->iaccess) {
638 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
639 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
641 /* acquire a temporary register -- it is saved in function */
643 sym->aop = aop = newAsmop(AOP_STA);
644 aop->aopu.stk.stk = sym->stack;
645 aop->size = getSize(sym->type);
648 DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
649 pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
650 if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
651 && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
653 for(i=0;i<aop->size;i++)
654 aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
655 _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
657 for(i=0;i<aop->size;i++) {
658 aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
659 _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
663 // fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
666 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
669 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
672 for(i=0;i<aop->size;i++) {
674 /* initialise for stack access via frame pointer */
675 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack + i + _G.stack_lat));
677 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
678 pic16_popCopyReg(&pic16_pc_plusw2), pcop[i]));
682 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
689 /* now assign the address of the variable to
690 the pointer register */
691 if (aop->type != AOP_STK) {
695 pic16_emitcode("push","acc");
697 pic16_emitcode("mov","a,_bp");
698 pic16_emitcode("add","a,#0x%02x",
700 ((char)(sym->stack - _G.nRegsSaved )) :
701 ((char)sym->stack)) & 0xff);
702 pic16_emitcode("mov","%s,a",
703 aop->aopu.aop_ptr->name);
706 pic16_emitcode("pop","acc");
708 pic16_emitcode("mov","%s,#%s",
709 aop->aopu.aop_ptr->name,
711 aop->paged = space->paged;
713 aop->aopu.aop_stk = sym->stack;
721 if (sym->onStack && options.stack10bit)
723 /* It's on the 10 bit stack, which is located in
727 //DEBUGpic16_emitcode(";","%d",__LINE__);
730 pic16_emitcode("push","acc");
732 pic16_emitcode("mov","a,_bp");
733 pic16_emitcode("add","a,#0x%02x",
735 ((char)(sym->stack - _G.nRegsSaved )) :
736 ((char)sym->stack)) & 0xff);
739 pic16_emitcode ("mov","dpx1,#0x40");
740 pic16_emitcode ("mov","dph1,#0x00");
741 pic16_emitcode ("mov","dpl1, a");
745 pic16_emitcode("pop","acc");
747 sym->aop = aop = newAsmop(AOP_DPTR2);
748 aop->size = getSize(sym->type);
754 /* special case for a function */
755 if (IS_FUNC(sym->type)) {
756 sym->aop = aop = newAsmop(AOP_PCODE);
757 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
758 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
759 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
760 PCOI(aop->aopu.pcop)->index = 0;
761 aop->size = FPTRSIZE;
762 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
769 //DEBUGpic16_emitcode(";","%d",__LINE__);
770 /* if in bit space */
771 if (IN_BITSPACE(space)) {
772 sym->aop = aop = newAsmop (AOP_CRY);
773 aop->aopu.aop_dir = sym->rname ;
774 aop->size = getSize(sym->type);
775 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
778 /* if it is in direct space */
779 if (IN_DIRSPACE(space)) {
780 sym->aop = aop = newAsmop (AOP_DIR);
781 aop->aopu.aop_dir = sym->rname ;
782 aop->size = getSize(sym->type);
783 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
784 pic16_allocDirReg( IC_LEFT(ic) );
789 if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
790 sym->aop = aop = newAsmop (AOP_DIR);
791 aop->aopu.aop_dir = sym->rname ;
792 aop->size = getSize(sym->type);
793 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
794 pic16_allocDirReg( IC_LEFT(ic) );
799 /* only remaining is far space */
800 sym->aop = aop = newAsmop(AOP_PCODE);
802 /* change the next if to 1 to revert to good old immediate code */
803 if(IN_CODESPACE(space)) {
804 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
805 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
806 PCOI(aop->aopu.pcop)->index = 0;
808 /* try to allocate via direct register */
809 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
810 // aop->size = getSize( sym->type );
813 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
814 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
817 if(!pic16_allocDirReg (IC_LEFT(ic)))
821 if(IN_DIRSPACE( space ))
823 else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
824 aop->size = FPTRSIZE;
825 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
826 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
827 else if(sym->onStack) {
833 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
835 /* if it is in code space */
836 if (IN_CODESPACE(space))
842 /*-----------------------------------------------------------------*/
843 /* aopForRemat - rematerialzes an object */
844 /*-----------------------------------------------------------------*/
845 static asmop *aopForRemat (operand *op) // x symbol *sym)
847 symbol *sym = OP_SYMBOL(op);
849 iCode *ic = NULL, *oldic;
850 asmop *aop = newAsmop(AOP_PCODE);
856 ic = sym->rematiCode;
858 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
860 if(IS_OP_POINTER(op)) {
861 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
867 // pic16_emitpcomment("ic: %s\n", printILine(ic));
870 val += (int) operandLitValue(IC_RIGHT(ic));
871 } else if (ic->op == '-') {
872 val -= (int) operandLitValue(IC_RIGHT(ic));
876 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
879 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
882 if(!op->isaddr)viaimmd++; else viaimmd=0;
884 /* set the following if to 1 to revert to good old immediate code */
885 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
888 DEBUGpic16_emitcode(";", "%s:%d immediate", __FILE__, __LINE__);
890 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
893 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
895 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
898 PCOI(aop->aopu.pcop)->index = val;
900 DEBUGpic16_emitcode(";", "%s:%d dir", __FILE__, __LINE__);
902 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
903 getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
904 // aop->size = AOP_SIZE( IC_LEFT(ic) );
908 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
909 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
911 val, IS_PTR_CONST(operandType(op)));
913 val, IS_CODEPTR(operandType(op)));
916 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
918 pic16_allocDirReg (IC_LEFT(ic));
920 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
927 static int aopIdx (asmop *aop, int offset)
932 if(aop->type != AOP_REG)
935 return aop->aopu.aop_reg[offset]->rIdx;
940 /*-----------------------------------------------------------------*/
941 /* regsInCommon - two operands have some registers in common */
942 /*-----------------------------------------------------------------*/
943 static bool regsInCommon (operand *op1, operand *op2)
948 /* if they have registers in common */
949 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
952 sym1 = OP_SYMBOL(op1);
953 sym2 = OP_SYMBOL(op2);
955 if (sym1->nRegs == 0 || sym2->nRegs == 0)
958 for (i = 0 ; i < sym1->nRegs ; i++) {
963 for (j = 0 ; j < sym2->nRegs ;j++ ) {
967 if (sym2->regs[j] == sym1->regs[i])
975 /*-----------------------------------------------------------------*/
976 /* operandsEqu - equivalent */
977 /*-----------------------------------------------------------------*/
978 static bool operandsEqu ( operand *op1, operand *op2)
982 /* if they not symbols */
983 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
986 sym1 = OP_SYMBOL(op1);
987 sym2 = OP_SYMBOL(op2);
989 /* if both are itemps & one is spilt
990 and the other is not then false */
991 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
992 sym1->isspilt != sym2->isspilt )
995 /* if they are the same */
999 if (sym1->rname[0] && sym2->rname[0]
1000 && strcmp (sym1->rname, sym2->rname) == 0)
1004 /* if left is a tmp & right is not */
1005 if (IS_ITEMP(op1) &&
1008 (sym1->usl.spillLoc == sym2))
1011 if (IS_ITEMP(op2) &&
1015 (sym2->usl.spillLoc == sym1))
1021 /*-----------------------------------------------------------------*/
1022 /* pic16_sameRegs - two asmops have the same registers */
1023 /*-----------------------------------------------------------------*/
1024 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
1031 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
1032 pic16_AopType(aop1->type), pic16_AopType(aop2->type));
1034 if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
1036 if (aop1->type != AOP_REG ||
1037 aop2->type != AOP_REG )
1040 if (aop1->size != aop2->size )
1043 for (i = 0 ; i < aop1->size ; i++ ) {
1044 // if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE;
1046 // if(aop1->aopu.aop_reg[i]->type == AOP_REG)
1047 if (strcmp(aop1->aopu.aop_reg[i]->name, aop2->aopu.aop_reg[i]->name ))
1054 bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
1056 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
1057 pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
1059 if(aop1 == aop2)return TRUE;
1060 if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
1062 if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
1068 /*-----------------------------------------------------------------*/
1069 /* pic16_aopOp - allocates an asmop for an operand : */
1070 /*-----------------------------------------------------------------*/
1071 void pic16_aopOp (operand *op, iCode *ic, bool result)
1080 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
1082 /* if this a literal */
1083 if (IS_OP_LITERAL(op)) {
1084 op->aop = aop = newAsmop(AOP_LIT);
1085 aop->aopu.aop_lit = op->operand.valOperand;
1086 aop->size = getSize(operandType(op));
1091 sym_link *type = operandType(op);
1093 if(IS_PTR_CONST(type))
1095 if(IS_CODEPTR(type))
1097 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1100 /* if already has a asmop then continue */
1104 /* if the underlying symbol has a aop */
1105 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
1106 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
1107 op->aop = OP_SYMBOL(op)->aop;
1111 /* if this is a true symbol */
1112 if (IS_TRUE_SYMOP(op)) {
1113 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
1114 op->aop = aopForSym(ic, op, result);
1118 /* this is a temporary : this has
1124 e) can be a return use only */
1126 sym = OP_SYMBOL(op);
1128 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
1129 /* if the type is a conditional */
1130 if (sym->regType == REG_CND) {
1131 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
1136 /* if it is spilt then two situations
1138 b) has a spill location */
1139 if (sym->isspilt || sym->nRegs == 0) {
1141 DEBUGpic16_emitcode(";","%d",__LINE__);
1142 /* rematerialize it NOW */
1145 sym->aop = op->aop = aop = aopForRemat (op);
1146 aop->size = getSize(sym->type);
1147 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
1154 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
1155 aop->size = getSize(sym->type);
1156 for ( i = 0 ; i < 1 ; i++ ) {
1157 aop->aopu.aop_str[i] = accUse[i];
1158 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
1160 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
1161 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
1169 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1170 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1171 //pic16_allocDirReg (IC_LEFT(ic));
1172 aop->size = getSize(sym->type);
1177 aop = op->aop = sym->aop = newAsmop(AOP_STR);
1178 aop->size = getSize(sym->type);
1179 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
1180 aop->aopu.aop_str[i] = fReturn[i];
1182 DEBUGpic16_emitcode(";","%d",__LINE__);
1186 /* else spill location */
1187 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
1188 /* force a new aop if sizes differ */
1189 sym->usl.spillLoc->aop = NULL;
1193 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1194 __FUNCTION__,__LINE__,
1195 sym->usl.spillLoc->rname,
1196 sym->rname, sym->usl.spillLoc->offset);
1199 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1200 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1201 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1203 sym->usl.spillLoc->offset, op);
1204 aop->size = getSize(sym->type);
1210 sym_link *type = operandType(op);
1212 if(IS_PTR_CONST(type))
1214 if(IS_CODEPTR(type))
1216 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1219 /* must be in a register */
1220 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1221 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1222 aop->size = sym->nRegs;
1223 for ( i = 0 ; i < sym->nRegs ;i++)
1224 aop->aopu.aop_reg[i] = sym->regs[i];
1227 /*-----------------------------------------------------------------*/
1228 /* pic16_freeAsmop - free up the asmop given to an operand */
1229 /*----------------------------------------------------------------*/
1230 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1247 /* depending on the asmop type only three cases need work AOP_RO
1248 , AOP_R1 && AOP_STK */
1250 switch (aop->type) {
1252 if (_G.fsr0Pushed ) {
1254 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
1255 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
1256 // pic16_emitcode ("pop","ar0");
1260 bitVectUnSetBit(ic->rUsed,IDX_FSR0);
1264 bitVectUnSetBit(ic->rUsed,IDX_FSR2);
1270 pic16_emitcode ("pop","ar0");
1274 bitVectUnSetBit(ic->rUsed,R0_IDX);
1280 pic16_emitcode ("pop","ar1");
1284 bitVectUnSetBit(ic->rUsed,R1_IDX);
1291 /* we must store the result on stack */
1292 if((op == IC_RESULT(ic)) && RESULTONSTA(ic)) {
1293 if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1294 for(i=0;i<aop->size;i++) {
1295 /* initialise for stack access via frame pointer */
1296 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(OP_SYMBOL(IC_RESULT(ic))->stack + i + _G.stack_lat));
1298 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1299 aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2)));
1302 if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1306 for(i=0;i<aop->size;i++)
1307 PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
1316 int stk = aop->aopu.aop_stk + aop->size;
1317 bitVectUnSetBit(ic->rUsed,R0_IDX);
1318 bitVectUnSetBit(ic->rUsed,R1_IDX);
1320 getFreePtr(ic,&aop,FALSE);
1322 if (options.stack10bit)
1324 /* I'm not sure what to do here yet... */
1327 "*** Warning: probably generating bad code for "
1328 "10 bit stack mode.\n");
1332 pic16_emitcode ("mov","a,_bp");
1333 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1334 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1336 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1340 pic16_emitcode("pop","acc");
1341 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1343 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1346 pic16_freeAsmop(op,NULL,ic,TRUE);
1348 pic16_emitcode("pop","ar0");
1353 pic16_emitcode("pop","ar1");
1363 /* all other cases just dealloc */
1367 OP_SYMBOL(op)->aop = NULL;
1368 /* if the symbol has a spill */
1370 SPIL_LOC(op)->aop = NULL;
1375 /*-----------------------------------------------------------------*/
1376 /* pic16_aopGet - for fetching value of the aop */
1377 /*-----------------------------------------------------------------*/
1378 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1383 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1385 /* offset is greater than size then zero */
1386 if (offset > (aop->size - 1) &&
1387 aop->type != AOP_LIT)
1390 /* depending on type */
1391 switch (aop->type) {
1395 sprintf(s, "%s", aop->aopu.aop_ptr->name);
1396 rs = Safe_calloc(1, strlen(s)+1);
1401 /* if we need to increment it */
1402 while (offset > aop->coff)
1404 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1408 while (offset < aop->coff)
1410 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1416 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
1417 return (dname ? "acc" : "a");
1419 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
1420 rs = Safe_calloc (1, strlen (s) + 1);
1428 sprintf (s,"%s",aop->aopu.aop_immd);
1431 sprintf(s,"(%s >> %d)",
1436 aop->aopu.aop_immd);
1437 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1438 rs = Safe_calloc(1,strlen(s)+1);
1444 sprintf(s,"(%s + %d)",
1447 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1449 sprintf(s,"%s",aop->aopu.aop_dir);
1450 rs = Safe_calloc(1,strlen(s)+1);
1456 // return aop->aopu.aop_reg[offset]->dname;
1458 return aop->aopu.aop_reg[offset]->name;
1461 //pic16_emitcode(";","%d",__LINE__);
1462 return aop->aopu.aop_dir;
1465 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
1466 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1468 // return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1469 rs = Safe_strdup("WREG");
1473 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1474 rs = Safe_calloc(1,strlen(s)+1);
1479 aop->coff = offset ;
1480 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1483 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1485 return aop->aopu.aop_str[offset];
1489 pCodeOp *pcop = aop->aopu.pcop;
1490 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1492 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1493 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1494 sprintf(s,"%s", pcop->name);
1496 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1499 rs = Safe_calloc(1,strlen(s)+1);
1504 rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
1508 // pCodeOp *pcop = aop->aop
1513 fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type));
1514 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1515 "aopget got unsupported aop->type");
1521 /* lock has the following meaning: When allocating temporary registers
1522 * for stack variables storage, the value of the temporary register is
1523 * saved on stack. Its value is restored at the end. This procedure is
1524 * done via calls to pic16_aopOp and pic16_freeAsmop functions. There is
1525 * a possibility that before a call to pic16_aopOp, a temporary register
1526 * is allocated for a while and it is freed after some time, this will
1527 * mess the stack and values will not be restored properly. So use lock=1
1528 * to allocate temporary registers used internally by the programmer, and
1529 * lock=0 to allocate registers for stack use. lock=1 will emit a warning
1530 * to inform the compiler developer about a possible bug. This is an internal
1531 * feature for developing the compiler -- VR */
1533 int _TempReg_lock = 0;
1534 /*-----------------------------------------------------------------*/
1535 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1536 /*-----------------------------------------------------------------*/
1537 pCodeOp *pic16_popGetTempReg(int lock)
1542 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1544 werror(W_POSSBUG2, __FILE__, __LINE__);
1547 _TempReg_lock += lock;
1552 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1553 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1554 PCOR(pcop)->r->wasUsed=1;
1555 PCOR(pcop)->r->isFree=0;
1557 /* push value on stack */
1558 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1566 /*-----------------------------------------------------------------*/
1567 /* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */
1568 /* don't save if inside v */
1569 /*-----------------------------------------------------------------*/
1570 pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
1575 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1578 werror(W_POSSBUG2, __FILE__, __LINE__);
1581 _TempReg_lock += lock;
1586 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1587 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1588 PCOR(pcop)->r->wasUsed=1;
1589 PCOR(pcop)->r->isFree=0;
1591 if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
1592 /* push value on stack */
1593 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1603 /*-----------------------------------------------------------------*/
1604 /* pic16_popReleaseTempReg - create a new temporary pCodeOp */
1605 /*-----------------------------------------------------------------*/
1606 void pic16_popReleaseTempReg(pCodeOp *pcop, int lock)
1608 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1610 _TempReg_lock -= lock;
1612 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1613 PCOR(pcop)->r->isFree = 1;
1614 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1617 /*-----------------------------------------------------------------*/
1618 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1619 /*-----------------------------------------------------------------*/
1620 pCodeOp *pic16_popGetLabel(unsigned int key)
1623 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
1628 return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset);
1631 /*-----------------------------------------------------------------*/
1632 /* pic16_popCopyReg - copy a pcode operator */
1633 /*-----------------------------------------------------------------*/
1634 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1638 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1639 pcor->pcop.type = pc->pcop.type;
1641 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1642 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1644 pcor->pcop.name = NULL;
1647 pcor->rIdx = pc->rIdx;
1650 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1655 /*-----------------------------------------------------------------*/
1656 /* pic16_popGetLit - asm operator to pcode operator conversion */
1657 /*-----------------------------------------------------------------*/
1658 pCodeOp *pic16_popGetLit(int lit)
1660 return pic16_newpCodeOpLit(lit);
1663 /*-----------------------------------------------------------------*/
1664 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1665 /*-----------------------------------------------------------------*/
1666 pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2)
1668 return pic16_newpCodeOpLit2(lit, arg2);
1672 /*-----------------------------------------------------------------*/
1673 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1674 /*-----------------------------------------------------------------*/
1675 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1677 return pic16_newpCodeOpImmd(name, offset,index, 0);
1681 /*-----------------------------------------------------------------*/
1682 /* pic16_popGet - asm operator to pcode operator conversion */
1683 /*-----------------------------------------------------------------*/
1684 pCodeOp *pic16_popGetWithString(char *str)
1690 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1694 pcop = pic16_newpCodeOp(str,PO_STR);
1699 /*-----------------------------------------------------------------*/
1700 /* pic16_popRegFromString - */
1701 /*-----------------------------------------------------------------*/
1702 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op)
1705 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1706 pcop->type = PO_DIR;
1708 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1709 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1714 pcop->name = Safe_calloc(1,strlen(str)+1);
1715 strcpy(pcop->name,str);
1717 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1719 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1721 /* make sure that register doesn't exist,
1722 * and operand isn't NULL
1723 * and symbol isn't in codespace (codespace symbols are handled elsewhere) */
1724 if((PCOR(pcop)->r == NULL)
1726 && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
1727 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1728 // __FUNCTION__, __LINE__, str, size, offset);
1730 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
1731 fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
1734 PCOR(pcop)->instance = offset;
1739 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1743 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1745 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1746 PCOR(pcop)->rIdx = rIdx;
1747 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1749 PCOR(pcop)->r->isFree = 0;
1750 PCOR(pcop)->r->wasUsed = 1;
1752 pcop->type = PCOR(pcop)->r->pc_type;
1757 /*---------------------------------------------------------------------------------*/
1758 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1760 /*---------------------------------------------------------------------------------*/
1761 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1766 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1768 /* comment the following check, so errors to throw up */
1769 // if(!pcop2)return NULL;
1771 temp = pic16_popGet(aop_dst, offset);
1772 pcop2->pcop2 = temp;
1779 /*--------------------------------------------------------------------------------.-*/
1780 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1781 /* VR 030601 , adapted by Hans Dorn */
1782 /*--------------------------------------------------------------------------------.-*/
1783 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1787 pcop2 = (pCodeOpReg2 *)src;
1795 /*---------------------------------------------------------------------------------*/
1796 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1797 /* movff instruction */
1798 /*---------------------------------------------------------------------------------*/
1799 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1804 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1805 pcop2->pcop2 = pic16_popCopyReg(dst);
1807 /* the pCodeOp may be already allocated */
1808 pcop2 = (pCodeOpReg2 *)(src);
1809 pcop2->pcop2 = (pCodeOp *)(dst);
1816 /*-----------------------------------------------------------------*/
1817 /* pic16_popGet - asm operator to pcode operator conversion */
1818 /*-----------------------------------------------------------------*/
1819 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1821 //char *s = buffer ;
1825 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1826 /* offset is greater than
1829 // if (offset > (aop->size - 1) &&
1830 // aop->type != AOP_LIT)
1831 // return NULL; //zero;
1833 /* depending on type */
1834 switch (aop->type) {
1840 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1841 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1848 pcop = Safe_calloc(1, sizeof(pCodeOpReg));
1849 PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
1850 PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
1851 PCOR(pcop)->r->wasUsed = 1;
1852 PCOR(pcop)->r->isFree = 0;
1854 PCOR(pcop)->instance = offset;
1855 pcop->type = PCOR(pcop)->r->pc_type;
1859 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1860 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1863 /* pCodeOp is already allocated from aopForSym */
1864 DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
1865 pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
1871 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1873 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1875 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1877 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1878 PCOR(pcop)->rIdx = rIdx;
1879 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1880 PCOR(pcop)->r->wasUsed=1;
1881 PCOR(pcop)->r->isFree=0;
1883 PCOR(pcop)->instance = offset;
1884 pcop->type = PCOR(pcop)->r->pc_type;
1885 // rs = aop->aopu.aop_reg[offset]->name;
1886 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1890 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1891 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1897 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1898 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
1902 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1904 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1906 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1907 // pcop->type = PO_GPR_REGISTER;
1908 PCOR(pcop)->rIdx = rIdx;
1909 PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
1910 PCOR(pcop)->r->wasUsed=1;
1911 PCOR(pcop)->r->isFree=0;
1913 PCOR(pcop)->instance = offset;
1914 pcop->type = PCOR(pcop)->r->pc_type;
1915 rs = aop->aopu.aop_reg[offset]->name;
1916 DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs);
1921 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1923 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
1924 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1925 //if(PCOR(pcop)->r == NULL)
1926 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1930 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1931 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1934 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1935 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1938 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1939 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1940 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1941 pcop->type = PCOR(pcop)->r->pc_type;
1942 pcop->name = PCOR(pcop)->r->name;
1948 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1950 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1951 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1953 switch( aop->aopu.pcop->type ) {
1954 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1955 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1957 assert( 0 ); /* should never reach here */;
1960 PCOI(pcop)->offset = offset;
1965 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1966 "pic16_popGet got unsupported aop->type");
1969 /*-----------------------------------------------------------------*/
1970 /* pic16_aopPut - puts a string for a aop */
1971 /*-----------------------------------------------------------------*/
1972 void pic16_aopPut (asmop *aop, char *s, int offset)
1979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1981 if (aop->size && offset > ( aop->size - 1)) {
1982 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1983 "pic16_aopPut got offset > aop->size");
1987 /* will assign value to value */
1988 /* depending on where it is ofcourse */
1989 switch (aop->type) {
1992 sprintf(d,"(%s + %d)",
1993 aop->aopu.aop_dir,offset);
1994 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1997 sprintf(d,"%s",aop->aopu.aop_dir);
2000 DEBUGpic16_emitcode(";","%d",__LINE__);
2002 pic16_emitcode("movf","%s,w",s);
2003 pic16_emitcode("movwf","%s",d);
2006 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
2007 if(offset >= aop->size) {
2008 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2011 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
2014 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2021 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
2022 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
2025 strcmp(s,"r0") == 0 ||
2026 strcmp(s,"r1") == 0 ||
2027 strcmp(s,"r2") == 0 ||
2028 strcmp(s,"r3") == 0 ||
2029 strcmp(s,"r4") == 0 ||
2030 strcmp(s,"r5") == 0 ||
2031 strcmp(s,"r6") == 0 ||
2032 strcmp(s,"r7") == 0 )
2033 pic16_emitcode("mov","%s,%s ; %d",
2034 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
2038 if(strcmp(s,"W")==0 )
2039 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
2041 pic16_emitcode("movwf","%s",
2042 aop->aopu.aop_reg[offset]->name);
2044 if(strcmp(s,zero)==0) {
2045 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2047 } else if(strcmp(s,"W")==0) {
2048 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
2049 pcop->type = PO_GPR_REGISTER;
2051 PCOR(pcop)->rIdx = -1;
2052 PCOR(pcop)->r = NULL;
2054 DEBUGpic16_emitcode(";","%d",__LINE__);
2055 pcop->name = Safe_strdup(s);
2056 pic16_emitpcode(POC_MOVFW,pcop);
2057 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2058 } else if(strcmp(s,one)==0) {
2059 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2060 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
2062 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2070 if (aop->type == AOP_DPTR2)
2076 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2077 "pic16_aopPut writting to code space");
2081 while (offset > aop->coff) {
2083 pic16_emitcode ("inc","dptr");
2086 while (offset < aop->coff) {
2088 pic16_emitcode("lcall","__decdptr");
2093 /* if not in accumulater */
2096 pic16_emitcode ("movx","@dptr,a");
2098 if (aop->type == AOP_DPTR2)
2106 while (offset > aop->coff) {
2108 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
2110 while (offset < aop->coff) {
2112 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
2118 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
2123 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
2125 if (strcmp(s,"r0") == 0 ||
2126 strcmp(s,"r1") == 0 ||
2127 strcmp(s,"r2") == 0 ||
2128 strcmp(s,"r3") == 0 ||
2129 strcmp(s,"r4") == 0 ||
2130 strcmp(s,"r5") == 0 ||
2131 strcmp(s,"r6") == 0 ||
2132 strcmp(s,"r7") == 0 ) {
2134 sprintf(buffer,"a%s",s);
2135 pic16_emitcode("mov","@%s,%s",
2136 aop->aopu.aop_ptr->name,buffer);
2138 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
2143 if (strcmp(s,"a") == 0)
2144 pic16_emitcode("push","acc");
2146 pic16_emitcode("push","%s",s);
2151 /* if bit variable */
2152 if (!aop->aopu.aop_dir) {
2153 pic16_emitcode("clr","a");
2154 pic16_emitcode("rlc","a");
2157 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
2160 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
2163 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2165 lbl = newiTempLabel(NULL);
2167 if (strcmp(s,"a")) {
2170 pic16_emitcode("clr","c");
2171 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
2172 pic16_emitcode("cpl","c");
2173 pic16_emitcode("","%05d_DS_:",lbl->key+100);
2174 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2181 if (strcmp(aop->aopu.aop_str[offset],s))
2182 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
2187 if (!offset && (strcmp(s,"acc") == 0))
2190 if (strcmp(aop->aopu.aop_str[offset],s))
2191 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
2195 fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type);
2196 // werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2197 // "pic16_aopPut got unsupported aop->type");
2203 /*-----------------------------------------------------------------*/
2204 /* mov2w - generate either a MOVLW or MOVFW based operand type */
2205 /*-----------------------------------------------------------------*/
2206 static void mov2w (asmop *aop, int offset)
2208 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
2211 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
2213 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
2216 static void mov2f(asmop *dst, asmop *src, int offset)
2218 if(is_LitAOp(src)) {
2219 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2220 pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
2222 if(pic16_sameRegsOfs(src, dst, offset))return;
2223 pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset),
2224 pic16_popGet(dst, offset)));
2228 static void mov2fp(pCodeOp *dst, asmop *src, int offset)
2230 if(is_LitAOp(src)) {
2231 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2232 pic16_emitpcode(POC_MOVWF, dst);
2234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(src, offset), dst));
2239 /* push pcop into stack */
2240 void pic16_pushpCodeOp(pCodeOp *pcop)
2242 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2243 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
2246 /* pop pcop from stack */
2247 void pic16_poppCodeOp(pCodeOp *pcop)
2249 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
2253 /*-----------------------------------------------------------------*/
2254 /* pushw - pushes wreg to stack */
2255 /*-----------------------------------------------------------------*/
2258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2259 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2263 /*-----------------------------------------------------------------*/
2264 /* pushaop - pushes aop to stack */
2265 /*-----------------------------------------------------------------*/
2266 void pushaop(asmop *aop, int offset)
2268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2269 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
2272 /*-----------------------------------------------------------------*/
2273 /* popaop - pops aop from stack */
2274 /*-----------------------------------------------------------------*/
2275 void popaop(asmop *aop, int offset)
2277 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
2278 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
2281 void popaopidx(asmop *aop, int offset, int index)
2285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2287 if(STACK_MODEL_LARGE)ofs++;
2289 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
2290 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
2293 /*-----------------------------------------------------------------*/
2294 /* reAdjustPreg - points a register back to where it should */
2295 /*-----------------------------------------------------------------*/
2296 static void reAdjustPreg (asmop *aop)
2300 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2302 if ((size = aop->size) <= 1)
2305 switch (aop->type) {
2309 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
2313 if (aop->type == AOP_DPTR2)
2319 pic16_emitcode("lcall","__decdptr");
2322 if (aop->type == AOP_DPTR2)
2334 /*-----------------------------------------------------------------*/
2335 /* opIsGptr: returns non-zero if the passed operand is */
2336 /* a generic pointer type. */
2337 /*-----------------------------------------------------------------*/
2338 static int opIsGptr(operand *op)
2340 sym_link *type = operandType(op);
2342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2343 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2351 /*-----------------------------------------------------------------*/
2352 /* pic16_getDataSize - get the operand data size */
2353 /*-----------------------------------------------------------------*/
2354 int pic16_getDataSize(operand *op)
2356 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2359 return AOP_SIZE(op);
2361 // tsd- in the pic port, the genptr size is 1, so this code here
2362 // fails. ( in the 8051 port, the size was 4).
2365 size = AOP_SIZE(op);
2366 if (size == GPTRSIZE)
2368 sym_link *type = operandType(op);
2369 if (IS_GENPTR(type))
2371 /* generic pointer; arithmetic operations
2372 * should ignore the high byte (pointer type).
2375 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2382 /*-----------------------------------------------------------------*/
2383 /* pic16_outAcc - output Acc */
2384 /*-----------------------------------------------------------------*/
2385 void pic16_outAcc(operand *result)
2388 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2389 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2392 size = pic16_getDataSize(result);
2394 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2397 /* unsigned or positive */
2399 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2404 /*-----------------------------------------------------------------*/
2405 /* pic16_outBitC - output a bit C */
2406 /* Move to result the value of Carry flag -- VR */
2407 /*-----------------------------------------------------------------*/
2408 void pic16_outBitC(operand *result)
2412 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2413 /* if the result is bit */
2414 if (AOP_TYPE(result) == AOP_CRY) {
2415 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2416 pic16_aopPut(AOP(result),"c",0);
2419 i = AOP_SIZE(result);
2421 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2423 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2426 pic16_emitcode("clr","a ; %d", __LINE__);
2427 pic16_emitcode("rlc","a");
2428 pic16_outAcc(result);
2433 /*-----------------------------------------------------------------*/
2434 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2435 /*-----------------------------------------------------------------*/
2436 void pic16_toBoolean(operand *oper)
2438 int size = AOP_SIZE(oper) - 1;
2441 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2443 if ( AOP_TYPE(oper) != AOP_ACC) {
2444 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2447 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2452 #if !defined(GEN_Not)
2453 /*-----------------------------------------------------------------*/
2454 /* genNot - generate code for ! operation */
2455 /*-----------------------------------------------------------------*/
2456 static void pic16_genNot (iCode *ic)
2461 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2462 /* assign asmOps to operand & result */
2463 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2464 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2466 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2467 /* if in bit space then a special case */
2468 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2469 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2470 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2471 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2473 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2474 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2475 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2480 size = AOP_SIZE(IC_LEFT(ic));
2482 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2483 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2484 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2487 pic16_toBoolean(IC_LEFT(ic));
2489 tlbl = newiTempLabel(NULL);
2490 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2491 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2492 pic16_outBitC(IC_RESULT(ic));
2495 /* release the aops */
2496 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2497 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2502 #if !defined(GEN_Cpl)
2503 /*-----------------------------------------------------------------*/
2504 /* genCpl - generate code for complement */
2505 /*-----------------------------------------------------------------*/
2506 static void pic16_genCpl (iCode *ic)
2512 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2513 /* assign asmOps to operand & result */
2514 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2515 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2517 /* if both are in bit space then
2519 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2520 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2522 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2523 pic16_emitcode("cpl","c");
2524 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2528 size = AOP_SIZE(IC_RESULT(ic));
2531 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2533 pic16_emitcode("cpl","a");
2534 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2536 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2537 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2539 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2540 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2548 /* release the aops */
2549 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2550 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2554 /*-----------------------------------------------------------------*/
2555 /* genUminusFloat - unary minus for floating points */
2556 /*-----------------------------------------------------------------*/
2557 static void genUminusFloat(operand *op,operand *result)
2559 int size ,offset =0 ;
2562 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2563 /* for this we just need to flip the
2564 first it then copy the rest in place */
2565 size = AOP_SIZE(op) - 1;
2566 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2570 pic16_emitcode("cpl","acc.7");
2571 pic16_aopPut(AOP(result),"a",3);
2574 pic16_aopPut(AOP(result),
2575 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2581 /*-----------------------------------------------------------------*/
2582 /* genUminus - unary minus code generation */
2583 /*-----------------------------------------------------------------*/
2584 static void genUminus (iCode *ic)
2587 sym_link *optype, *rtype;
2589 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2592 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2593 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2595 /* if both in bit space then special case */
2596 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
2597 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2599 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2600 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2601 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2606 optype = operandType(IC_LEFT(ic));
2607 rtype = operandType(IC_RESULT(ic));
2609 /* if float then do float stuff */
2610 if (IS_FLOAT(optype)) {
2611 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2615 /* otherwise subtract from zero by taking the 2's complement */
2616 size = AOP_SIZE(IC_LEFT(ic));
2618 for(i=0; i<size; i++) {
2619 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2620 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2622 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2623 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2627 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2628 for(i=1; i<size; i++) {
2630 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2634 /* release the aops */
2635 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2636 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2640 /*-----------------------------------------------------------------*/
2641 /* saveRegisters - will look for a call and save the registers */
2642 /*-----------------------------------------------------------------*/
2643 static void saveRegisters(iCode *lic)
2650 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2652 for (ic = lic ; ic ; ic = ic->next)
2653 if (ic->op == CALL || ic->op == PCALL)
2657 fprintf(stderr,"found parameter push with no function call\n");
2661 /* if the registers have been saved already then
2663 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2666 /* find the registers in use at this time
2667 and push them away to safety */
2668 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2672 if (options.useXstack) {
2673 if (bitVectBitValue(rsave,R0_IDX))
2674 pic16_emitcode("mov","b,r0");
2675 pic16_emitcode("mov","r0,%s",spname);
2676 for (i = 0 ; i < pic16_nRegs ; i++) {
2677 if (bitVectBitValue(rsave,i)) {
2679 pic16_emitcode("mov","a,b");
2681 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2682 pic16_emitcode("movx","@r0,a");
2683 pic16_emitcode("inc","r0");
2686 pic16_emitcode("mov","%s,r0",spname);
2687 if (bitVectBitValue(rsave,R0_IDX))
2688 pic16_emitcode("mov","r0,b");
2690 //for (i = 0 ; i < pic16_nRegs ; i++) {
2691 // if (bitVectBitValue(rsave,i))
2692 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2695 dtype = operandType(IC_LEFT(ic));
2696 if (currFunc && dtype &&
2697 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2698 IFFUNC_ISISR(currFunc->type) &&
2701 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2704 /*-----------------------------------------------------------------*/
2705 /* unsaveRegisters - pop the pushed registers */
2706 /*-----------------------------------------------------------------*/
2707 static void unsaveRegisters (iCode *ic)
2712 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2713 /* find the registers in use at this time
2714 and push them away to safety */
2715 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2718 if (options.useXstack) {
2719 pic16_emitcode("mov","r0,%s",spname);
2720 for (i = pic16_nRegs ; i >= 0 ; i--) {
2721 if (bitVectBitValue(rsave,i)) {
2722 pic16_emitcode("dec","r0");
2723 pic16_emitcode("movx","a,@r0");
2725 pic16_emitcode("mov","b,a");
2727 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2731 pic16_emitcode("mov","%s,r0",spname);
2732 if (bitVectBitValue(rsave,R0_IDX))
2733 pic16_emitcode("mov","r0,b");
2735 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2736 // if (bitVectBitValue(rsave,i))
2737 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2744 /*-----------------------------------------------------------------*/
2746 /*-----------------------------------------------------------------*/
2747 static void pushSide(operand * oper, int size)
2750 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2752 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2753 if (AOP_TYPE(oper) != AOP_REG &&
2754 AOP_TYPE(oper) != AOP_DIR &&
2756 pic16_emitcode("mov","a,%s",l);
2757 pic16_emitcode("push","acc");
2759 pic16_emitcode("push","%s",l);
2764 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2766 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2767 pic16_emitpcode(POC_MOVFW, src);
2768 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2770 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2771 src, pic16_popGet(AOP(op), offset)));
2776 /*-----------------------------------------------------------------*/
2777 /* assignResultValue - assign results to oper, rescall==1 is */
2778 /* called from genCall() or genPcall() */
2779 /*-----------------------------------------------------------------*/
2780 static void assignResultValue(operand * oper, int rescall)
2782 int size = AOP_SIZE(oper);
2785 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2786 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2789 /* assign result from a call/pcall function() */
2791 /* function results are stored in a special order,
2792 * see top of file with Function return policy, or manual */
2795 /* 8-bits, result in WREG */
2796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2799 /* 16-bits, result in PRODL:WREG */
2800 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2804 /* 24-bits, result in PRODH:PRODL:WREG */
2805 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2809 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2810 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2814 /* >32-bits, result on stack, and FSR0 points to beginning.
2815 * Fix stack when done */
2818 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2819 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2821 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2826 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2827 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2828 if(STACK_MODEL_LARGE) {
2830 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2834 int areg = 0; /* matching argument register */
2836 debugf("_G.useWreg = %d\n", _G.useWreg);
2837 areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
2840 /* its called from genReceive (probably) -- VR */
2841 if(!GpsuedoStkPtr && _G.useWreg) {
2842 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2844 /* The last byte in the assignment is in W */
2845 if(areg <= GpsuedoStkPtr) {
2847 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
2852 _G.stack_lat = AOP_SIZE(oper)-1;
2857 popaopidx(AOP(oper), offset, GpsuedoStkPtr);
2864 /*-----------------------------------------------------------------*/
2865 /* genIpush - generate code for pushing this gets a little complex */
2866 /*-----------------------------------------------------------------*/
2867 static void genIpush (iCode *ic)
2869 // int size, offset=0;
2871 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2875 pic16_aopOp(IC_LEFT(ic), ic, FALSE );
2877 /* send to stack as normal */
2878 addSet(&_G.sendSet,ic);
2879 // addSetHead(&_G.sendSet,ic);
2880 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2885 int size, offset = 0 ;
2889 /* if this is not a parm push : ie. it is spill push
2890 and spill push is always done on the local stack */
2891 if (!ic->parmPush) {
2893 /* and the item is spilt then do nothing */
2894 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2897 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2898 size = AOP_SIZE(IC_LEFT(ic));
2899 /* push it on the stack */
2901 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2906 pic16_emitcode("push","%s",l);
2911 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2915 /*-----------------------------------------------------------------*/
2916 /* genIpop - recover the registers: can happen only for spilling */
2917 /*-----------------------------------------------------------------*/
2918 static void genIpop (iCode *ic)
2920 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2925 /* if the temp was not pushed then */
2926 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2929 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2930 size = AOP_SIZE(IC_LEFT(ic));
2933 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2936 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2941 /*-----------------------------------------------------------------*/
2942 /* unsaverbank - restores the resgister bank from stack */
2943 /*-----------------------------------------------------------------*/
2944 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2946 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2954 if (options.useXstack) {
2956 r = getFreePtr(ic,&aop,FALSE);
2959 pic16_emitcode("mov","%s,_spx",r->name);
2960 pic16_emitcode("movx","a,@%s",r->name);
2961 pic16_emitcode("mov","psw,a");
2962 pic16_emitcode("dec","%s",r->name);
2965 pic16_emitcode ("pop","psw");
2968 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2969 if (options.useXstack) {
2970 pic16_emitcode("movx","a,@%s",r->name);
2971 //pic16_emitcode("mov","(%s+%d),a",
2972 // regspic16[i].base,8*bank+regspic16[i].offset);
2973 pic16_emitcode("dec","%s",r->name);
2976 pic16_emitcode("pop",""); //"(%s+%d)",
2977 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2980 if (options.useXstack) {
2982 pic16_emitcode("mov","_spx,%s",r->name);
2983 pic16_freeAsmop(NULL,aop,ic,TRUE);
2989 /*-----------------------------------------------------------------*/
2990 /* saverbank - saves an entire register bank on the stack */
2991 /*-----------------------------------------------------------------*/
2992 static void saverbank (int bank, iCode *ic, bool pushPsw)
2994 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3000 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3001 if (options.useXstack) {
3004 r = getFreePtr(ic,&aop,FALSE);
3005 pic16_emitcode("mov","%s,_spx",r->name);
3009 for (i = 0 ; i < pic16_nRegs ;i++) {
3010 if (options.useXstack) {
3011 pic16_emitcode("inc","%s",r->name);
3012 //pic16_emitcode("mov","a,(%s+%d)",
3013 // regspic16[i].base,8*bank+regspic16[i].offset);
3014 pic16_emitcode("movx","@%s,a",r->name);
3016 pic16_emitcode("push","");// "(%s+%d)",
3017 //regspic16[i].base,8*bank+regspic16[i].offset);
3021 if (options.useXstack) {
3022 pic16_emitcode("mov","a,psw");
3023 pic16_emitcode("movx","@%s,a",r->name);
3024 pic16_emitcode("inc","%s",r->name);
3025 pic16_emitcode("mov","_spx,%s",r->name);
3026 pic16_freeAsmop (NULL,aop,ic,TRUE);
3029 pic16_emitcode("push","psw");
3031 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
3039 /*-----------------------------------------------------------------*/
3040 /* genCall - generates a call statement */
3041 /*-----------------------------------------------------------------*/
3042 static void genCall (iCode *ic)
3049 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3051 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3052 /* if caller saves & we have not saved then */
3053 // if (!ic->regsSaved)
3054 // saveRegisters(ic);
3056 /* initialise stackParms for IPUSH pushes */
3057 // stackParms = psuedoStkPtr;
3058 // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
3059 fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
3062 gpsimDebug_StackDump(__FILE__, __LINE__, fname );
3065 /* if send set is not empty the assign */
3068 int psuedoStkPtr=-1;
3069 #if USE_WREG_IN_FUNC_PARAMS
3070 int firstTimeThruLoop = 1;
3074 /* reverse sendSet if function is not reentrant */
3075 if(!IFFUNC_ISREENT(ftype))
3076 _G.sendSet = reverseSet(_G.sendSet);
3079 /* First figure how many parameters are getting passed */
3081 /* do we really need to know this ? -- VR
3082 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3083 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3084 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
3085 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
3090 // stackParms = psuedoStkPtr;
3094 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3096 #if USE_WREG_IN_FUNC_PARAMS
3099 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3100 size = AOP_SIZE(IC_LEFT(sic));
3104 /* set the following to 1 to enable passing arguments via WREG */
3105 #if USE_WREG_IN_FUNC_PARAMS
3107 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3108 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3109 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3111 if(!firstTimeThruLoop) {
3112 /* If this is not the first time we've been through the loop
3113 * then we need to save the parameter in a temporary
3114 * register. The last byte of the last parameter is
3118 // --psuedoStkPtr; // sanity check
3122 firstTimeThruLoop=0;
3124 mov2w (AOP(IC_LEFT(sic)), size);
3129 /* all arguments are passed via stack */
3131 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3132 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3133 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3135 mov2w (AOP(IC_LEFT(sic)), size);
3140 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3143 #if USE_WREG_IN_FUNC_PARAMS
3144 /* save last parameter to stack if functions has varargs */
3145 if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
3146 else use_wreg = 1; /* last parameter in WREG */
3149 _G.stackRegSet = _G.sendSet;
3154 pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
3157 /* if we need to assign a result value */
3158 if ((IS_ITEMP(IC_RESULT(ic))
3159 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3160 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3161 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3164 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3167 assignResultValue(IC_RESULT(ic), 1);
3169 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3170 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3172 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3175 if(!stackParms && ic->parmBytes) {
3176 stackParms = ic->parmBytes;
3179 stackParms -= use_wreg;
3182 if(stackParms == 1) {
3183 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
3185 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3186 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3188 if(STACK_MODEL_LARGE) {
3190 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3195 gpsimDebug_StackDump(__FILE__, __LINE__, fname);
3198 /* adjust the stack for parameters if required */
3199 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3202 /* if register bank was saved then pop them */
3204 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3206 /* if we hade saved some registers then unsave them */
3207 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3208 unsaveRegisters (ic);
3214 /*-----------------------------------------------------------------*/
3215 /* genPcall - generates a call by pointer statement */
3216 /* new version, created from genCall - HJD */
3217 /*-----------------------------------------------------------------*/
3218 static void genPcall (iCode *ic)
3223 symbol *retlbl = newiTempLabel(NULL);
3224 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
3226 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3228 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3230 /* if send set is not empty the assign */
3233 int psuedoStkPtr=-1;
3234 #if USE_WREG_IN_FUNC_PARAMS
3235 int firstTimeThruLoop = 1;
3238 /* For the Pic port, there is no data stack.
3239 * So parameters passed to functions are stored
3240 * in registers. (The pCode optimizer will get
3241 * rid of most of these :). */
3245 /* reverse sendSet if function is not reentrant */
3246 if(!IFFUNC_ISREENT(ftype))
3247 _G.sendSet = reverseSet(_G.sendSet);
3250 /* First figure how many parameters are getting passed */
3252 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3253 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3254 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
3255 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
3259 // stackParms = psuedoStkPtr;
3262 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3264 #if USE_WREG_IN_FUNC_PARAMS
3268 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3269 size = AOP_SIZE(IC_LEFT(sic));
3272 #if USE_WREG_IN_FUNC_PARAMS
3274 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3275 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3276 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3278 if(!firstTimeThruLoop) {
3279 /* If this is not the first time we've been through the loop
3280 * then we need to save the parameter in a temporary
3281 * register. The last byte of the last parameter is
3285 --psuedoStkPtr; // sanity check
3288 firstTimeThruLoop=0;
3290 mov2w (AOP(IC_LEFT(sic)), size);
3297 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3298 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3299 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3301 mov2w (AOP(IC_LEFT(sic)), size);
3306 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3309 #if USE_WREG_IN_FUNC_PARAMS
3310 if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
3311 else use_wreg = 1; /* last parameter in WREG */
3314 _G.stackRegSet = _G.sendSet;
3318 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3320 // push return address
3321 // push $ on return stack, then replace with retlbl
3323 pic16_emitpcodeNULLop(POC_PUSH);
3325 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
3326 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
3327 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
3328 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
3329 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
3330 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
3332 /* make the call by writing the pointer into pc */
3333 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
3334 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
3336 // note: MOVFF to PCL not allowed
3337 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
3338 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
3341 /* return address is here: (X) */
3342 pic16_emitpLabelFORCE(retlbl->key);
3344 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3347 /* if we need assign a result value */
3348 if ((IS_ITEMP(IC_RESULT(ic))
3349 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3350 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3351 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3354 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3357 assignResultValue(IC_RESULT(ic), 1);
3359 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3360 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3362 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3365 stackParms -= use_wreg;
3368 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3369 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3370 if(STACK_MODEL_LARGE) {
3371 /* this implies that stackParms < 256 !!! -- VR */
3373 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3378 /*-----------------------------------------------------------------*/
3379 /* resultRemat - result is rematerializable */
3380 /*-----------------------------------------------------------------*/
3381 static int resultRemat (iCode *ic)
3383 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3384 if (SKIP_IC(ic) || ic->op == IFX)
3387 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3388 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3389 if (sym->remat && !POINTER_SET(ic))
3396 #if defined(__BORLANDC__) || defined(_MSC_VER)
3397 #define STRCASECMP stricmp
3399 #define STRCASECMP strcasecmp
3403 /*-----------------------------------------------------------------*/
3404 /* inExcludeList - return 1 if the string is in exclude Reg list */
3405 /*-----------------------------------------------------------------*/
3406 static bool inExcludeList(char *s)
3408 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3411 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3412 if (options.excludeRegs[i] &&
3413 STRCASECMP(options.excludeRegs[i],"none") == 0)
3416 for ( i = 0 ; options.excludeRegs[i]; i++) {
3417 if (options.excludeRegs[i] &&
3418 STRCASECMP(s,options.excludeRegs[i]) == 0)
3425 /*-----------------------------------------------------------------*/
3426 /* genFunction - generated code for function entry */
3427 /*-----------------------------------------------------------------*/
3428 static void genFunction (iCode *ic)
3433 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
3435 pic16_labelOffset += (max_key+4);
3440 ftype = operandType(IC_LEFT(ic));
3441 sym = OP_SYMBOL(IC_LEFT(ic));
3443 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3444 /* create an absolute section at the interrupt vector:
3445 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3453 sym = OP_SYMBOL( IC_LEFT(ic));
3455 if(interrupts[i]->name
3456 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3463 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3464 __FILE__, __LINE__, sym->name);
3467 _G.interruptvector = found;
3470 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3471 asym = newSymbol(asymname, 0);
3473 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3474 pic16_addpBlock( apb );
3476 pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
3477 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3478 pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3480 /* mark the end of this tiny function */
3481 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3486 abSym = Safe_calloc(1, sizeof(absSym));
3487 strcpy(abSym->name, asymname);
3489 switch( _G.interruptvector ) {
3490 case 0: abSym->address = 0x000000; break;
3491 case 1: abSym->address = 0x000008; break;
3492 case 2: abSym->address = 0x000018; break;
3495 /* relocate interrupt vectors if needed */
3496 abSym->address += pic16_options.ivt_loc;
3498 addSet(&absSymSet, abSym);
3502 /* create the function header */
3503 pic16_emitcode(";","-----------------------------------------");
3504 pic16_emitcode(";"," function %s",sym->name);
3505 pic16_emitcode(";","-----------------------------------------");
3507 pic16_emitcode("","%s:",sym->rname);
3508 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3514 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) {
3515 if(!strcmp(ab->name, sym->rname)) {
3516 pic16_pBlockConvert2Absolute(pb);
3523 if(IFFUNC_ISNAKED(ftype)) {
3524 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3528 /* if critical function then turn interrupts off */
3529 if (IFFUNC_ISCRITICAL(ftype)) {
3530 //pic16_emitcode("clr","ea");
3533 _G.fregsUsed = sym->regsUsed;
3535 /* if this is an interrupt service routine then
3536 * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
3537 if (IFFUNC_ISISR(sym->type)) {
3538 _G.usefastretfie = 1; /* use shadow registers by default */
3540 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3541 if(!(_G.interruptvector == 1)) {
3542 /* do not save WREG,STATUS,BSR for high priority interrupts
3543 * because they are stored in the hardware shadow registers already */
3544 _G.usefastretfie = 0;
3545 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3546 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3547 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3550 /* these should really be optimized somehow, because not all
3551 * interrupt handlers modify them */
3552 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3553 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3554 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3555 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3557 // pic16_pBlockConvert2ISR(pb);
3561 /* emit code to setup stack frame if user enabled,
3562 * and function is not main() */
3564 //fprintf(stderr, "function name: %s\n", sym->name);
3565 if(strcmp(sym->name, "main")) {
3566 if(1 /*!options.ommitFramePtr || sym->regsUsed*/) {
3567 /* setup the stack frame */
3568 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3569 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3570 if(STACK_MODEL_LARGE)
3571 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3575 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3578 if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
3580 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3581 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3583 pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
3586 #if USE_WREG_IN_FUNC_PARAMS
3587 if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
3589 else _G.useWreg = 1;
3594 /* if callee-save to be used for this function
3595 * then save the registers being used in this function */
3596 // if (IFFUNC_CALLEESAVES(sym->type))
3600 /* if any registers used */
3601 if (sym->regsUsed) {
3602 /* save the registers used */
3603 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3604 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
3605 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3606 if (bitVectBitValue(sym->regsUsed,i)) {
3607 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3610 if(!pic16_regWithIdx(i)->wasUsed) {
3611 fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
3612 __FILE__, __LINE__, pic16_regWithIdx(i)->name);
3613 pic16_regWithIdx(i)->wasUsed = 1;
3617 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
3621 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3622 // fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
3625 /*-----------------------------------------------------------------*/
3626 /* genEndFunction - generates epilogue for functions */
3627 /*-----------------------------------------------------------------*/
3628 static void genEndFunction (iCode *ic)
3630 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3632 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3634 if(IFFUNC_ISNAKED(sym->type)) {
3635 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3641 /* add code for ISCRITICAL */
3642 if(IFFUNC_ISCRITICAL(sym->type)) {
3643 /* if critical function, turn on interrupts */
3645 /* TODO: add code here -- VR */
3648 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3650 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3651 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3653 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
3656 /* now we need to restore the registers */
3657 /* if any registers used */
3658 if (sym->regsUsed) {
3661 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
3662 /* restore registers used */
3663 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3664 for ( i = sym->regsUsed->size; i >= 0; i--) {
3665 if (bitVectBitValue(sym->regsUsed,i)) {
3666 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3670 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
3674 if(strcmp(sym->name, "main")) {
3675 if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
3676 /* restore stack frame */
3677 if(STACK_MODEL_LARGE)
3678 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3679 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3685 if (IFFUNC_ISISR(sym->type)) {
3686 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3687 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3688 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3689 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3691 if(!(_G.interruptvector == 1)) {
3692 /* do not restore interrupt vector for WREG,STATUS,BSR
3693 * for high priority interrupt, see genFunction */
3694 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3695 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3696 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3698 _G.interruptvector = 0; /* sanity check */
3701 /* if debug then send end of function */
3702 /* if (options.debug && currFunc) */
3704 debugFile->writeEndFunction (currFunc, ic, 1);
3707 if(_G.usefastretfie)
3708 pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
3710 pic16_emitpcodeNULLop(POC_RETFIE);
3712 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3714 _G.usefastretfie = 0;
3718 if (IFFUNC_ISCRITICAL(sym->type)) {
3719 pic16_emitcode("setb","ea");
3722 /* if debug then send end of function */
3724 debugFile->writeEndFunction (currFunc, ic, 1);
3727 /* insert code to restore stack frame, if user enabled it
3728 * and function is not main() */
3731 pic16_emitpcodeNULLop(POC_RETURN);
3733 /* Mark the end of a function */
3734 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3738 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3741 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
3742 if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
3744 if(dest->type == PO_WREG && (offset == 0)) {
3745 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3748 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
3752 /*-----------------------------------------------------------------*/
3753 /* genRet - generate code for return statement */
3754 /*-----------------------------------------------------------------*/
3755 static void genRet (iCode *ic)
3760 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3761 /* if we have no return value then
3762 * just generate the "ret" */
3767 /* we have something to return then
3768 * move the return value into place */
3769 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3770 size = AOP_SIZE(IC_LEFT(ic));
3774 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3775 // pic16_emitpcode(POC_MOVFF,
3776 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3779 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3780 // pic16_emitpcode(POC_MOVFF,
3781 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3784 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3785 // pic16_emitpcode(POC_MOVFF,
3786 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3789 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3791 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3792 // pic16_emitpcode(POC_MOVFF,
3793 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3796 /* >32-bits, setup stack and FSR0 */
3798 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3799 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3801 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3803 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3808 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3809 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3811 if(STACK_MODEL_LARGE) {
3812 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3813 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3815 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3820 /* old code, left here for reference -- VR */
3824 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3826 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3827 pic16_emitpcomment("push %s",l);
3830 DEBUGpic16_emitcode(";", "%d", __LINE__);
3831 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3832 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3834 if (strcmp(fReturn[offset],l)) {
3835 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3836 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3837 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3839 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3843 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3853 if (strcmp(fReturn[pushed],"a"))
3854 pic16_emitcode("pop",fReturn[pushed]);
3856 pic16_emitcode("pop","acc");
3862 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3865 /* generate a jump to the return label
3866 * if the next is not the return statement */
3867 if (!(ic->next && ic->next->op == LABEL
3868 && IC_LABEL(ic->next) == returnLabel)) {
3870 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3871 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
3875 /*-----------------------------------------------------------------*/
3876 /* genLabel - generates a label */
3877 /*-----------------------------------------------------------------*/
3878 static void genLabel (iCode *ic)
3882 /* special case never generate */
3883 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3884 if (IC_LABEL(ic) == entryLabel)
3887 pic16_emitpLabel(IC_LABEL(ic)->key);
3888 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset));
3891 /*-----------------------------------------------------------------*/
3892 /* genGoto - generates a goto */
3893 /*-----------------------------------------------------------------*/
3895 static void genGoto (iCode *ic)
3897 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3898 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset);
3902 /*-----------------------------------------------------------------*/
3903 /* genMultbits :- multiplication of bits */
3904 /*-----------------------------------------------------------------*/
3905 static void genMultbits (operand *left,
3909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3911 if(!pic16_sameRegs(AOP(result),AOP(right)))
3912 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3914 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3915 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3916 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3921 /*-----------------------------------------------------------------*/
3922 /* genMultOneByte : 8 bit multiplication & division */
3923 /*-----------------------------------------------------------------*/
3924 static void genMultOneByte (operand *left,
3929 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3930 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3931 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3933 /* (if two literals, the value is computed before) */
3934 /* if one literal, literal on the right */
3935 if (AOP_TYPE(left) == AOP_LIT){
3941 /* size is already checked in genMult == 1 */
3942 // size = AOP_SIZE(result);
3944 if (AOP_TYPE(right) == AOP_LIT){
3945 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3946 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3947 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3948 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3950 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3951 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3952 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3953 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3956 pic16_genMult8X8_8 (left, right,result);
3959 /*-----------------------------------------------------------------*/
3960 /* genMultOneWord : 16 bit multiplication */
3961 /*-----------------------------------------------------------------*/
3962 static void genMultOneWord (operand *left,
3967 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3968 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3969 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3971 /* (if two literals, the value is computed before)
3972 * if one literal, literal on the right */
3973 if (AOP_TYPE(left) == AOP_LIT){
3979 /* size is checked already == 2 */
3980 // size = AOP_SIZE(result);
3982 if (AOP_TYPE(right) == AOP_LIT) {
3983 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3984 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3985 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3986 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3988 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3989 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3990 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3991 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3994 pic16_genMult16X16_16(left, right,result);
3997 /*-----------------------------------------------------------------*/
3998 /* genMultOneLong : 32 bit multiplication */
3999 /*-----------------------------------------------------------------*/
4000 static void genMultOneLong (operand *left,
4005 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4006 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4007 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4009 /* (if two literals, the value is computed before)
4010 * if one literal, literal on the right */
4011 if (AOP_TYPE(left) == AOP_LIT){
4017 /* size is checked already == 4 */
4018 // size = AOP_SIZE(result);
4020 if (AOP_TYPE(right) == AOP_LIT) {
4021 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4022 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4023 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4024 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4026 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4027 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4028 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4029 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4032 pic16_genMult32X32_32(left, right,result);
4037 /*-----------------------------------------------------------------*/
4038 /* genMult - generates code for multiplication */
4039 /*-----------------------------------------------------------------*/
4040 static void genMult (iCode *ic)
4042 operand *left = IC_LEFT(ic);
4043 operand *right = IC_RIGHT(ic);
4044 operand *result= IC_RESULT(ic);
4046 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4047 /* assign the amsops */
4048 pic16_aopOp (left,ic,FALSE);
4049 pic16_aopOp (right,ic,FALSE);
4050 pic16_aopOp (result,ic,TRUE);
4052 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4054 /* special cases first *
4056 if (AOP_TYPE(left) == AOP_CRY
4057 && AOP_TYPE(right)== AOP_CRY) {
4058 genMultbits(left,right,result);
4062 /* if both are of size == 1 */
4063 if(AOP_SIZE(left) == 1
4064 && AOP_SIZE(right) == 1) {
4065 genMultOneByte(left,right,result);
4069 /* if both are of size == 2 */
4070 if(AOP_SIZE(left) == 2
4071 && AOP_SIZE(right) == 2) {
4072 genMultOneWord(left, right, result);
4076 /* if both are of size == 4 */
4077 if(AOP_SIZE(left) == 4
4078 && AOP_SIZE(right) == 4) {
4079 genMultOneLong(left, right, result);
4083 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
4086 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
4087 /* should have been converted to function call */
4091 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4092 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4093 pic16_freeAsmop(result,NULL,ic,TRUE);
4096 /*-----------------------------------------------------------------*/
4097 /* genDivbits :- division of bits */
4098 /*-----------------------------------------------------------------*/
4099 static void genDivbits (operand *left,
4106 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4107 /* the result must be bit */
4108 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4109 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4113 pic16_emitcode("div","ab");
4114 pic16_emitcode("rrc","a");
4115 pic16_aopPut(AOP(result),"c",0);
4118 /*-----------------------------------------------------------------*/
4119 /* genDivOneByte : 8 bit division */
4120 /*-----------------------------------------------------------------*/
4121 static void genDivOneByte (operand *left,
4125 sym_link *opetype = operandType(result);
4130 /* result = divident / divisor
4131 * - divident may be a register or a literal,
4132 * - divisor may be a register or a literal,
4133 * so there are 3 cases (literal / literal is optimized
4134 * by the front-end) to handle.
4135 * In addition we must handle signed and unsigned, which
4136 * result in 6 final different cases -- VR */
4138 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4139 size = AOP_SIZE(result) - 1;
4141 /* signed or unsigned */
4142 if (SPEC_USIGN(opetype)) {
4143 pCodeOp *pct1, /* count */
4146 symbol *label1, *label2, *label3;;
4149 /* unsigned is easy */
4151 pct1 = pic16_popGetTempReg(1);
4152 pct2 = pic16_popGetTempReg(1);
4153 pct3 = pic16_popGetTempReg(1);
4155 label1 = newiTempLabel(NULL);
4156 label2 = newiTempLabel(NULL);
4157 label3 = newiTempLabel(NULL);
4159 /* the following algorithm is extracted from divuint.c */
4161 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
4162 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
4164 pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
4166 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
4168 pic16_emitpLabel(label1->key);
4171 pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
4175 pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
4179 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
4181 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
4182 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
4184 pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
4185 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
4186 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
4188 pic16_emitpLabel( label3->key );
4189 pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
4190 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
4194 pic16_emitpLabel(label2->key);
4195 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
4196 pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
4197 pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
4199 /* result is in wreg */
4200 if(AOP_TYPE(result) != AOP_ACC)
4201 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
4203 pic16_popReleaseTempReg( pct3, 1);
4204 pic16_popReleaseTempReg( pct2, 1);
4205 pic16_popReleaseTempReg( pct1, 1);
4210 /* signed is a little bit more difficult */
4212 /* save the signs of the operands */
4213 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4215 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4216 pic16_emitcode("push","acc"); /* save it on the stack */
4218 /* now sign adjust for both left & right */
4219 l = pic16_aopGet(AOP(right),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));
4226 pic16_emitcode("mov","b,a");
4228 /* sign adjust left side */
4229 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4232 lbl = newiTempLabel(NULL);
4233 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4234 pic16_emitcode("cpl","a");
4235 pic16_emitcode("inc","a");
4236 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4238 /* now the division */
4239 pic16_emitcode("div","ab");
4240 /* we are interested in the lower order
4242 pic16_emitcode("mov","b,a");
4243 lbl = newiTempLabel(NULL);
4244 pic16_emitcode("pop","acc");
4245 /* if there was an over flow we don't
4246 adjust the sign of the result */
4247 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4248 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4250 pic16_emitcode("clr","a");
4251 pic16_emitcode("subb","a,b");
4252 pic16_emitcode("mov","b,a");
4253 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4255 /* now we are done */
4256 pic16_aopPut(AOP(result),"b",0);
4258 pic16_emitcode("mov","c,b.7");
4259 pic16_emitcode("subb","a,acc");
4262 pic16_aopPut(AOP(result),"a",offset++);
4266 /*-----------------------------------------------------------------*/
4267 /* genDiv - generates code for division */
4268 /*-----------------------------------------------------------------*/
4269 static void genDiv (iCode *ic)
4271 operand *left = IC_LEFT(ic);
4272 operand *right = IC_RIGHT(ic);
4273 operand *result= IC_RESULT(ic);
4276 /* Division is a very lengthy algorithm, so it is better
4277 * to call support routines than inlining algorithm.
4278 * Division functions written here just in case someone
4279 * wants to inline and not use the support libraries -- VR */
4281 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4282 /* assign the amsops */
4283 pic16_aopOp (left,ic,FALSE);
4284 pic16_aopOp (right,ic,FALSE);
4285 pic16_aopOp (result,ic,TRUE);
4287 /* special cases first */
4289 if (AOP_TYPE(left) == AOP_CRY &&
4290 AOP_TYPE(right)== AOP_CRY) {
4291 genDivbits(left,right,result);
4295 /* if both are of size == 1 */
4296 if (AOP_SIZE(left) == 1 &&
4297 AOP_SIZE(right) == 1 ) {
4298 genDivOneByte(left,right,result);
4302 /* should have been converted to function call */
4305 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4306 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4307 pic16_freeAsmop(result,NULL,ic,TRUE);
4310 /*-----------------------------------------------------------------*/
4311 /* genModbits :- modulus of bits */
4312 /*-----------------------------------------------------------------*/
4313 static void genModbits (operand *left,
4320 /* the result must be bit */
4321 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4322 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4326 pic16_emitcode("div","ab");
4327 pic16_emitcode("mov","a,b");
4328 pic16_emitcode("rrc","a");
4329 pic16_aopPut(AOP(result),"c",0);
4332 /*-----------------------------------------------------------------*/
4333 /* genModOneByte : 8 bit modulus */
4334 /*-----------------------------------------------------------------*/
4335 static void genModOneByte (operand *left,
4339 sym_link *opetype = operandType(result);
4343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4344 /* signed or unsigned */
4345 if (SPEC_USIGN(opetype)) {
4346 /* unsigned is easy */
4347 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4348 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4350 pic16_emitcode("div","ab");
4351 pic16_aopPut(AOP(result),"b",0);
4355 /* signed is a little bit more difficult */
4357 /* save the signs of the operands */
4358 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4361 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4362 pic16_emitcode("push","acc"); /* save it on the stack */
4364 /* now sign adjust for both left & right */
4365 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4368 lbl = newiTempLabel(NULL);
4369 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4370 pic16_emitcode("cpl","a");
4371 pic16_emitcode("inc","a");
4372 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4373 pic16_emitcode("mov","b,a");
4375 /* sign adjust left side */
4376 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4379 lbl = newiTempLabel(NULL);
4380 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4381 pic16_emitcode("cpl","a");
4382 pic16_emitcode("inc","a");
4383 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4385 /* now the multiplication */
4386 pic16_emitcode("div","ab");
4387 /* we are interested in the lower order
4389 lbl = newiTempLabel(NULL);
4390 pic16_emitcode("pop","acc");
4391 /* if there was an over flow we don't
4392 adjust the sign of the result */
4393 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4394 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4396 pic16_emitcode("clr","a");
4397 pic16_emitcode("subb","a,b");
4398 pic16_emitcode("mov","b,a");
4399 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4401 /* now we are done */
4402 pic16_aopPut(AOP(result),"b",0);
4406 /*-----------------------------------------------------------------*/
4407 /* genMod - generates code for division */
4408 /*-----------------------------------------------------------------*/
4409 static void genMod (iCode *ic)
4411 operand *left = IC_LEFT(ic);
4412 operand *right = IC_RIGHT(ic);
4413 operand *result= IC_RESULT(ic);
4415 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4416 /* assign the amsops */
4417 pic16_aopOp (left,ic,FALSE);
4418 pic16_aopOp (right,ic,FALSE);
4419 pic16_aopOp (result,ic,TRUE);
4421 /* special cases first */
4423 if (AOP_TYPE(left) == AOP_CRY &&
4424 AOP_TYPE(right)== AOP_CRY) {
4425 genModbits(left,right,result);
4429 /* if both are of size == 1 */
4430 if (AOP_SIZE(left) == 1 &&
4431 AOP_SIZE(right) == 1 ) {
4432 genModOneByte(left,right,result);
4436 /* should have been converted to function call */
4440 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442 pic16_freeAsmop(result,NULL,ic,TRUE);
4445 /*-----------------------------------------------------------------*/
4446 /* genIfxJump :- will create a jump depending on the ifx */
4447 /*-----------------------------------------------------------------*/
4449 note: May need to add parameter to indicate when a variable is in bit space.
4451 static void genIfxJump (iCode *ic, char *jval)
4454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4455 /* if true label then we jump if condition
4457 if ( IC_TRUE(ic) ) {
4459 if(strcmp(jval,"a") == 0)
4461 else if (strcmp(jval,"c") == 0)
4464 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4465 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4468 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4469 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
4473 /* false label is present */
4474 if(strcmp(jval,"a") == 0)
4476 else if (strcmp(jval,"c") == 0)
4479 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4480 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4483 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4484 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
4489 /* mark the icode as generated */
4496 /*-----------------------------------------------------------------*/
4498 /*-----------------------------------------------------------------*/
4499 static void genSkip(iCode *ifx,int status_bit)
4501 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4505 if ( IC_TRUE(ifx) ) {
4506 switch(status_bit) {
4521 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4522 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4526 switch(status_bit) {
4540 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4541 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4548 /*-----------------------------------------------------------------*/
4550 /*-----------------------------------------------------------------*/
4551 static void genSkipc(resolvedIfx *rifx)
4553 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4563 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4564 rifx->generated = 1;
4567 /*-----------------------------------------------------------------*/
4569 /*-----------------------------------------------------------------*/
4570 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4572 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4577 if( (rifx->condition ^ invert_condition) & 1)
4582 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4583 rifx->generated = 1;
4587 /*-----------------------------------------------------------------*/
4589 /*-----------------------------------------------------------------*/
4590 static void genSkipz(iCode *ifx, int condition)
4601 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4603 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4606 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4608 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4613 /*-----------------------------------------------------------------*/
4615 /*-----------------------------------------------------------------*/
4616 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4622 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4624 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4627 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4628 rifx->generated = 1;
4632 /*-----------------------------------------------------------------*/
4633 /* genChkZeroes :- greater or less than comparison */
4634 /* For each byte in a literal that is zero, inclusive or the */
4635 /* the corresponding byte in the operand with W */
4636 /* returns true if any of the bytes are zero */
4637 /*-----------------------------------------------------------------*/
4638 static int genChkZeroes(operand *op, int lit, int size)
4645 i = (lit >> (size*8)) & 0xff;
4649 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4651 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4660 /*-----------------------------------------------------------------*/
4661 /* genCmp :- greater or less than comparison */
4662 /*-----------------------------------------------------------------*/
4664 static void genCmp (operand *left,operand *right,
4665 operand *result, iCode *ifx, int sign)
4667 int size; //, offset = 0 ;
4668 unsigned long lit = 0L,i = 0;
4669 resolvedIfx rFalseIfx;
4670 // resolvedIfx rTrueIfx;
4672 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4675 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4676 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4680 resolveIfx(&rFalseIfx,ifx);
4681 truelbl = newiTempLabel(NULL);
4682 size = max(AOP_SIZE(left),AOP_SIZE(right));
4684 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4688 /* if literal is on the right then swap with left */
4689 if ((AOP_TYPE(right) == AOP_LIT)) {
4690 operand *tmp = right ;
4691 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4692 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4695 lit = (lit - 1) & mask;
4698 rFalseIfx.condition ^= 1;
4701 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4702 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4706 //if(IC_TRUE(ifx) == NULL)
4707 /* if left & right are bit variables */
4708 if (AOP_TYPE(left) == AOP_CRY &&
4709 AOP_TYPE(right) == AOP_CRY ) {
4710 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4711 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4713 /* subtract right from left if at the
4714 end the carry flag is set then we know that
4715 left is greater than right */
4717 symbol *lbl = newiTempLabel(NULL);
4720 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4721 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
4725 if(AOP_TYPE(right) == AOP_LIT) {
4727 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4729 DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
4736 genSkipCond(&rFalseIfx,left,size-1,7);
4738 /* no need to compare to 0...*/
4739 /* NOTE: this is a de-generate compare that most certainly
4740 * creates some dead code. */
4741 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4743 if(ifx) ifx->generated = 1;
4750 //i = (lit >> (size*8)) & 0xff;
4751 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4753 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4755 i = ((0-lit) & 0xff);
4758 /* lit is 0x7f, all signed chars are less than
4759 * this except for 0x7f itself */
4760 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4761 genSkipz2(&rFalseIfx,0);
4763 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4764 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4765 genSkipc(&rFalseIfx);
4770 genSkipz2(&rFalseIfx,1);
4772 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4773 genSkipc(&rFalseIfx);
4777 if(ifx) ifx->generated = 1;
4781 /* chars are out of the way. now do ints and longs */
4784 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4791 genSkipCond(&rFalseIfx,left,size,7);
4792 if(ifx) ifx->generated = 1;
4797 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4799 //rFalseIfx.condition ^= 1;
4800 //genSkipCond(&rFalseIfx,left,size,7);
4801 //rFalseIfx.condition ^= 1;
4803 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4804 if(rFalseIfx.condition)
4805 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4807 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4809 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4810 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4811 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4814 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4816 if(rFalseIfx.condition) {
4818 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4824 genSkipc(&rFalseIfx);
4825 pic16_emitpLabel(truelbl->key);
4826 if(ifx) ifx->generated = 1;
4833 if( (lit & 0xff) == 0) {
4834 /* lower byte is zero */
4835 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4836 i = ((lit >> 8) & 0xff) ^0x80;
4837 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4838 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4839 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4840 genSkipc(&rFalseIfx);
4843 if(ifx) ifx->generated = 1;
4848 /* Special cases for signed longs */
4849 if( (lit & 0xffffff) == 0) {
4850 /* lower byte is zero */
4851 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4852 i = ((lit >> 8*3) & 0xff) ^0x80;
4853 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4854 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4855 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4856 genSkipc(&rFalseIfx);
4859 if(ifx) ifx->generated = 1;
4867 if(lit & (0x80 << (size*8))) {
4868 /* lit is negative */
4869 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4871 //genSkipCond(&rFalseIfx,left,size,7);
4873 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4875 if(rFalseIfx.condition)
4876 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4878 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4882 /* lit is positive */
4883 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4884 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4885 if(rFalseIfx.condition)
4886 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4888 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4893 This works, but is only good for ints.
4894 It also requires a "known zero" register.
4895 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4896 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4897 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4898 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4899 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4900 genSkipc(&rFalseIfx);
4902 pic16_emitpLabel(truelbl->key);
4903 if(ifx) ifx->generated = 1;
4907 /* There are no more special cases, so perform a general compare */
4909 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4910 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4914 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4916 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4918 //rFalseIfx.condition ^= 1;
4919 genSkipc(&rFalseIfx);
4921 pic16_emitpLabel(truelbl->key);
4923 if(ifx) ifx->generated = 1;
4930 /* sign is out of the way. So now do an unsigned compare */
4931 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4934 /* General case - compare to an unsigned literal on the right.*/
4936 i = (lit >> (size*8)) & 0xff;
4937 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4938 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4940 i = (lit >> (size*8)) & 0xff;
4943 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4945 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4947 /* this byte of the lit is zero,
4948 *if it's not the last then OR in the variable */
4950 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4955 pic16_emitpLabel(lbl->key);
4956 // pic16_emitpLabel(truelbl->key);
4957 //if(emitFinalCheck)
4958 genSkipc(&rFalseIfx);
4960 pic16_emitpLabel(truelbl->key);
4962 if(ifx) ifx->generated = 1;
4969 if(AOP_TYPE(left) == AOP_LIT) {
4970 //symbol *lbl = newiTempLabel(NULL);
4972 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4975 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4978 if((lit == 0) && (sign == 0)){
4981 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4983 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4985 genSkipz2(&rFalseIfx,0);
4986 if(ifx) ifx->generated = 1;
4993 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4994 /* degenerate compare can never be true */
4995 if(rFalseIfx.condition == 0)
4996 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4998 if(ifx) ifx->generated = 1;
5003 /* signed comparisons to a literal byte */
5005 int lp1 = (lit+1) & 0xff;
5007 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
5010 rFalseIfx.condition ^= 1;
5011 genSkipCond(&rFalseIfx,right,0,7);
5014 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5015 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5016 genSkipz2(&rFalseIfx,1);
5019 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5020 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5021 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5022 rFalseIfx.condition ^= 1;
5023 genSkipc(&rFalseIfx);
5027 /* unsigned comparisons to a literal byte */
5029 switch(lit & 0xff ) {
5031 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5032 genSkipz2(&rFalseIfx,0);
5035 rFalseIfx.condition ^= 1;
5036 genSkipCond(&rFalseIfx,right,0,7);
5040 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5041 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5042 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5043 rFalseIfx.condition ^= 1;
5044 if (AOP_TYPE(result) == AOP_CRY)
5045 genSkipc(&rFalseIfx);
5047 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5048 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5054 if(ifx) ifx->generated = 1;
5055 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5061 /* Size is greater than 1 */
5069 /* this means lit = 0xffffffff, or -1 */
5072 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5073 rFalseIfx.condition ^= 1;
5074 genSkipCond(&rFalseIfx,right,size,7);
5075 if(ifx) ifx->generated = 1;
5077 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5086 if(rFalseIfx.condition) {
5087 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5088 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5091 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5093 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5097 if(rFalseIfx.condition) {
5098 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5099 pic16_emitpLabel(truelbl->key);
5101 rFalseIfx.condition ^= 1;
5102 genSkipCond(&rFalseIfx,right,s,7);
5105 if(ifx) ifx->generated = 1;
5107 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5113 if((size == 1) && (0 == (lp1&0xff))) {
5114 /* lower byte of signed word is zero */
5115 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5116 i = ((lp1 >> 8) & 0xff) ^0x80;
5117 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5118 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5119 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5120 rFalseIfx.condition ^= 1;
5121 genSkipc(&rFalseIfx);
5124 if(ifx) ifx->generated = 1;
5126 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5132 if(lit & (0x80 << (size*8))) {
5133 /* Lit is less than zero */
5134 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5135 //rFalseIfx.condition ^= 1;
5136 //genSkipCond(&rFalseIfx,left,size,7);
5137 //rFalseIfx.condition ^= 1;
5138 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5139 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5141 if(rFalseIfx.condition)
5142 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5144 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5148 /* Lit is greater than or equal to zero */
5149 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5150 //rFalseIfx.condition ^= 1;
5151 //genSkipCond(&rFalseIfx,right,size,7);
5152 //rFalseIfx.condition ^= 1;
5154 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5155 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5157 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5158 if(rFalseIfx.condition)
5159 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5161 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5166 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5167 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5171 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5173 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5175 rFalseIfx.condition ^= 1;
5176 //rFalseIfx.condition = 1;
5177 genSkipc(&rFalseIfx);
5179 pic16_emitpLabel(truelbl->key);
5181 if(ifx) ifx->generated = 1;
5184 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5191 /* compare word or long to an unsigned literal on the right.*/
5196 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5199 break; /* handled above */
5202 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5204 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5205 genSkipz2(&rFalseIfx,0);
5209 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5211 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5214 if(rFalseIfx.condition)
5215 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5217 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5220 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5221 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5223 rFalseIfx.condition ^= 1;
5224 genSkipc(&rFalseIfx);
5227 pic16_emitpLabel(truelbl->key);
5229 if(ifx) ifx->generated = 1;
5231 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5239 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5240 i = (lit >> (size*8)) & 0xff;
5242 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5243 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5246 i = (lit >> (size*8)) & 0xff;
5249 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5251 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5253 /* this byte of the lit is zero,
5254 * if it's not the last then OR in the variable */
5256 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5261 pic16_emitpLabel(lbl->key);
5263 rFalseIfx.condition ^= 1;
5265 genSkipc(&rFalseIfx);
5269 pic16_emitpLabel(truelbl->key);
5270 if(ifx) ifx->generated = 1;
5272 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5278 /* Compare two variables */
5280 DEBUGpic16_emitcode(";sign","%d",sign);
5284 /* Sigh. thus sucks... */
5288 pctemp = pic16_popGetTempReg(1);
5289 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5290 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5291 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5292 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5293 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5294 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5295 pic16_popReleaseTempReg(pctemp, 1);
5297 /* Signed char comparison */
5298 /* Special thanks to Nikolai Golovchenko for this snippet */
5299 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5300 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5301 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5302 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5303 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5304 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5306 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5307 genSkipc(&rFalseIfx);
5309 if(ifx) ifx->generated = 1;
5311 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5319 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5320 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5324 /* The rest of the bytes of a multi-byte compare */
5328 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5331 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5332 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5337 pic16_emitpLabel(lbl->key);
5339 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5340 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5341 (AOP_TYPE(result) == AOP_REG)) {
5342 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5343 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5345 genSkipc(&rFalseIfx);
5347 //genSkipc(&rFalseIfx);
5348 if(ifx) ifx->generated = 1;
5351 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5359 if ((AOP_TYPE(result) != AOP_CRY)
5360 && AOP_SIZE(result)) {
5361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5363 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5365 pic16_outBitC(result);
5367 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5368 /* if the result is used in the next
5369 ifx conditional branch then generate
5370 code a little differently */
5372 genIfxJump (ifx,"c");
5374 pic16_outBitC(result);
5375 /* leave the result in acc */
5380 #else /* old version of genCmp() */
5382 /* new version of genCmp -- VR 20041012 */
5383 static void genCmp (operand *left,operand *right,
5384 operand *result, iCode *ifx, int sign)
5386 int size; //, offset = 0 ;
5387 unsigned long lit = 0L,i = 0;
5388 resolvedIfx rFalseIfx;
5389 int willCheckCarry=0;
5390 // resolvedIfx rTrueIfx;
5392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5396 * subtract right from left if at the end the carry flag is set then we
5397 * know that left is greater than right */
5399 resolveIfx(&rFalseIfx,ifx);
5400 truelbl = newiTempLabel(NULL);
5401 size = max(AOP_SIZE(left),AOP_SIZE(right));
5403 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5405 /* POC_CPFSGT compare f, wreg, skip if f greater than wreg
5406 * POC_CPFSLT compare f, wreg, skip if f less then wreg */
5409 /* if literal is on the right then swap with left */
5410 if ((AOP_TYPE(right) == AOP_LIT)) {
5411 operand *tmp = right ;
5412 unsigned long mask = (0x100 << (8*(size-1))) - 1;
5414 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5416 // lit = (lit - 1) & mask;
5419 rFalseIfx.condition ^= 1;
5421 if ((AOP_TYPE(left) == AOP_LIT)) {
5422 /* float compares are handled by support functions */
5423 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
5427 //if(IC_TRUE(ifx) == NULL)
5428 /* if left & right are bit variables */
5429 if (AOP_TYPE(left) == AOP_CRY &&
5430 AOP_TYPE(right) == AOP_CRY ) {
5431 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5432 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
5435 symbol *lbl = newiTempLabel(NULL);
5437 if(AOP_TYPE(left) == AOP_LIT) {
5438 DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
5440 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5442 else willCheckCarry = 0;
5445 if((lit == 0) && (sign == 0)){
5448 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5450 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
5452 genSkipz2(&rFalseIfx,0);
5453 if(ifx) ifx->generated = 1;
5460 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
5461 /* degenerate compare can never be true */
5462 if(rFalseIfx.condition == 0)
5463 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
5465 if(ifx) ifx->generated = 1;
5470 /* signed comparisons to a literal byte */
5472 int lp1 = (lit+1) & 0xff;
5474 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d",__LINE__,lit, rFalseIfx.condition);
5477 rFalseIfx.condition ^= 1;
5478 genSkipCond(&rFalseIfx,right,0,7);
5481 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5482 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5483 genSkipz2(&rFalseIfx,1);
5486 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
5488 if(rFalseIfx.condition)
5489 pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
5491 pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
5493 if(willCheckCarry) {
5494 if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
5495 else { emitSETC; emitCLRC; }
5498 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5501 /* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5502 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5503 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5504 rFalseIfx.condition ^= 1;
5505 genSkipc(&rFalseIfx);
5510 /* unsigned comparisons to a literal byte */
5512 switch(lit & 0xff ) {
5514 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5515 genSkipz2(&rFalseIfx,0);
5518 rFalseIfx.condition ^= 1;
5519 genSkipCond(&rFalseIfx,right,0,7);
5523 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5524 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5525 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5526 rFalseIfx.condition ^= 1;
5527 if (AOP_TYPE(result) == AOP_CRY)
5528 genSkipc(&rFalseIfx);
5530 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5531 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5537 if(ifx) ifx->generated = 1;
5538 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5544 /* Size is greater than 1 */
5552 /* this means lit = 0xffffffff, or -1 */
5555 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5556 rFalseIfx.condition ^= 1;
5557 genSkipCond(&rFalseIfx,right,size,7);
5558 if(ifx) ifx->generated = 1;
5565 if(rFalseIfx.condition) {
5566 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5567 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5570 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5572 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5576 if(rFalseIfx.condition) {
5577 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5578 pic16_emitpLabel(truelbl->key);
5580 rFalseIfx.condition ^= 1;
5581 genSkipCond(&rFalseIfx,right,s,7);
5584 if(ifx) ifx->generated = 1;
5588 if((size == 1) && (0 == (lp1&0xff))) {
5589 /* lower byte of signed word is zero */
5590 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5591 i = ((lp1 >> 8) & 0xff) ^0x80;
5592 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5593 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5594 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5595 rFalseIfx.condition ^= 1;
5596 genSkipc(&rFalseIfx);
5599 if(ifx) ifx->generated = 1;
5603 if(lit & (0x80 << (size*8))) {
5604 /* Lit is less than zero */
5605 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5606 //rFalseIfx.condition ^= 1;
5607 //genSkipCond(&rFalseIfx,left,size,7);
5608 //rFalseIfx.condition ^= 1;
5609 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5610 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5612 if(rFalseIfx.condition)
5613 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5615 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5619 /* Lit is greater than or equal to zero */
5620 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5621 //rFalseIfx.condition ^= 1;
5622 //genSkipCond(&rFalseIfx,right,size,7);
5623 //rFalseIfx.condition ^= 1;
5625 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5626 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5628 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5629 if(rFalseIfx.condition)
5630 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5632 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5637 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5638 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5642 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5644 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5646 rFalseIfx.condition ^= 1;
5647 //rFalseIfx.condition = 1;
5648 genSkipc(&rFalseIfx);
5650 pic16_emitpLabel(truelbl->key);
5652 if(ifx) ifx->generated = 1;
5657 /* compare word or long to an unsigned literal on the right.*/
5662 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5665 break; /* handled above */
5668 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5670 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5671 genSkipz2(&rFalseIfx,0);
5675 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5677 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5680 if(rFalseIfx.condition)
5681 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5683 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5686 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5687 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5689 rFalseIfx.condition ^= 1;
5690 genSkipc(&rFalseIfx);
5693 pic16_emitpLabel(truelbl->key);
5695 if(ifx) ifx->generated = 1;
5701 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5702 i = (lit >> (size*8)) & 0xff;
5704 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5705 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5708 i = (lit >> (size*8)) & 0xff;
5711 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5713 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5715 /* this byte of the lit is zero,
5716 * if it's not the last then OR in the variable */
5718 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5723 pic16_emitpLabel(lbl->key);
5725 rFalseIfx.condition ^= 1;
5727 genSkipc(&rFalseIfx);
5731 pic16_emitpLabel(truelbl->key);
5732 if(ifx) ifx->generated = 1;
5736 /* Compare two variables */
5738 DEBUGpic16_emitcode(";sign","%d",sign);
5742 /* Sigh. thus sucks... */
5746 pctemp = pic16_popGetTempReg(1);
5747 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5748 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5749 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5750 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5751 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5752 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5753 pic16_popReleaseTempReg(pctemp, 1);
5755 /* Signed char comparison */
5756 /* Special thanks to Nikolai Golovchenko for this snippet */
5757 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5758 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5759 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5760 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5761 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5762 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5764 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5765 genSkipc(&rFalseIfx);
5767 if(ifx) ifx->generated = 1;
5773 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5774 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5778 /* The rest of the bytes of a multi-byte compare */
5782 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5785 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5786 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5791 pic16_emitpLabel(lbl->key);
5793 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5794 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5795 (AOP_TYPE(result) == AOP_REG)) {
5796 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5797 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5799 genSkipc(&rFalseIfx);
5801 //genSkipc(&rFalseIfx);
5802 if(ifx) ifx->generated = 1;
5809 if ((AOP_TYPE(result) != AOP_CRY)
5810 && AOP_SIZE(result)) {
5811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5813 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5815 pic16_outBitC(result);
5817 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5818 /* if the result is used in the next
5819 ifx conditional branch then generate
5820 code a little differently */
5822 genIfxJump (ifx,"c");
5824 pic16_outBitC(result);
5825 /* leave the result in acc */
5833 /*-----------------------------------------------------------------*/
5834 /* genCmpGt :- greater than comparison */
5835 /*-----------------------------------------------------------------*/
5836 static void genCmpGt (iCode *ic, iCode *ifx)
5838 operand *left, *right, *result;
5839 sym_link *letype , *retype;
5842 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5844 right= IC_RIGHT(ic);
5845 result = IC_RESULT(ic);
5847 letype = getSpec(operandType(left));
5848 retype =getSpec(operandType(right));
5849 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5850 /* assign the amsops */
5851 pic16_aopOp (left,ic,FALSE);
5852 pic16_aopOp (right,ic,FALSE);
5853 pic16_aopOp (result,ic,TRUE);
5855 genCmp(right, left, result, ifx, sign);
5857 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5858 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5859 pic16_freeAsmop(result,NULL,ic,TRUE);
5862 /*-----------------------------------------------------------------*/
5863 /* genCmpLt - less than comparisons */
5864 /*-----------------------------------------------------------------*/
5865 static void genCmpLt (iCode *ic, iCode *ifx)
5867 operand *left, *right, *result;
5868 sym_link *letype , *retype;
5871 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5873 right= IC_RIGHT(ic);
5874 result = IC_RESULT(ic);
5876 letype = getSpec(operandType(left));
5877 retype =getSpec(operandType(right));
5878 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5880 /* assign the amsops */
5881 pic16_aopOp (left,ic,FALSE);
5882 pic16_aopOp (right,ic,FALSE);
5883 pic16_aopOp (result,ic,TRUE);
5885 genCmp(left, right, result, ifx, sign);
5887 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5888 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5889 pic16_freeAsmop(result,NULL,ic,TRUE);
5894 // FIXME reenable literal optimisation when the pic16 port is stable
5896 /*-----------------------------------------------------------------*/
5897 /* genc16bit2lit - compare a 16 bit value to a literal */
5898 /*-----------------------------------------------------------------*/
5899 static void genc16bit2lit(operand *op, int lit, int offset)
5903 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5904 if( (lit&0xff) == 0)
5909 switch( BYTEofLONG(lit,i)) {
5911 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5914 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5917 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5920 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5921 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5926 switch( BYTEofLONG(lit,i)) {
5928 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5932 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5936 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5939 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5941 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5950 /*-----------------------------------------------------------------*/
5951 /* gencjneshort - compare and jump if not equal */
5952 /*-----------------------------------------------------------------*/
5953 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5955 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5957 int res_offset = 0; /* the result may be a different size then left or right */
5958 int res_size = AOP_SIZE(result);
5960 symbol *lbl, *lbl_done;
5962 unsigned long lit = 0L;
5963 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5966 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5968 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5969 resolveIfx(&rIfx,ifx);
5970 lbl = newiTempLabel(NULL);
5971 lbl_done = newiTempLabel(NULL);
5974 /* if the left side is a literal or
5975 if the right is in a pointer register and left
5977 if ((AOP_TYPE(left) == AOP_LIT) ||
5978 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5983 if(AOP_TYPE(right) == AOP_LIT)
5984 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5986 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5987 preserve_result = 1;
5989 if(result && !preserve_result)
5992 for(i = 0; i < AOP_SIZE(result); i++)
5993 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5997 /* if the right side is a literal then anything goes */
5998 if (AOP_TYPE(right) == AOP_LIT &&
5999 AOP_TYPE(left) != AOP_DIR ) {
6002 genc16bit2lit(left, lit, 0);
6004 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6007 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6010 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6011 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6013 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6017 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6019 if(res_offset < res_size-1)
6027 /* if the right side is in a register or in direct space or
6028 if the left is a pointer register & right is not */
6029 else if (AOP_TYPE(right) == AOP_REG ||
6030 AOP_TYPE(right) == AOP_DIR ||
6031 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
6032 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
6033 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
6034 int lbl_key = lbl->key;
6037 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
6038 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6040 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6041 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
6042 __FUNCTION__,__LINE__);
6046 /* switch(size) { */
6048 /* genc16bit2lit(left, lit, 0); */
6050 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
6055 if((AOP_TYPE(left) == AOP_DIR) &&
6056 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
6058 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6059 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6061 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
6063 switch (lit & 0xff) {
6065 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6068 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6069 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6070 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6074 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6075 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6076 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6077 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6081 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6082 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6087 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6090 if(AOP_TYPE(result) == AOP_CRY) {
6091 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6096 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6098 /* fix me. probably need to check result size too */
6099 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
6104 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6105 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6112 if(res_offset < res_size-1)
6117 } else if(AOP_TYPE(right) == AOP_REG &&
6118 AOP_TYPE(left) != AOP_DIR){
6121 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6122 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6123 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6128 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6130 if(res_offset < res_size-1)
6135 /* right is a pointer reg need both a & b */
6137 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
6139 pic16_emitcode("mov","b,%s",l);
6140 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6141 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
6146 if(result && preserve_result)
6149 for(i = 0; i < AOP_SIZE(result); i++)
6150 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6153 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
6155 if(result && preserve_result)
6156 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
6159 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6161 pic16_emitpLabel(lbl->key);
6163 if(result && preserve_result)
6166 for(i = 0; i < AOP_SIZE(result); i++)
6167 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6169 pic16_emitpLabel(lbl_done->key);
6172 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6180 /*-----------------------------------------------------------------*/
6181 /* gencjne - compare and jump if not equal */
6182 /*-----------------------------------------------------------------*/
6183 static void gencjne(operand *left, operand *right, iCode *ifx)
6185 symbol *tlbl = newiTempLabel(NULL);
6187 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6188 gencjneshort(left, right, lbl);
6190 pic16_emitcode("mov","a,%s",one);
6191 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
6192 pic16_emitcode("","%05d_DS_:",lbl->key+100);
6193 pic16_emitcode("clr","a");
6194 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6196 pic16_emitpLabel(lbl->key);
6197 pic16_emitpLabel(tlbl->key);
6203 /*-----------------------------------------------------------------*/
6204 /* is_LitOp - check if operand has to be treated as literal */
6205 /*-----------------------------------------------------------------*/
6206 static bool is_LitOp(operand *op)
6208 return (AOP_TYPE(op) == AOP_LIT)
6209 || ( (AOP_TYPE(op) == AOP_PCODE)
6210 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
6211 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
6214 /*-----------------------------------------------------------------*/
6215 /* is_LitAOp - check if operand has to be treated as literal */
6216 /*-----------------------------------------------------------------*/
6217 static bool is_LitAOp(asmop *aop)
6219 return (aop->type == AOP_LIT)
6220 || ( (aop->type == AOP_PCODE)
6221 && ( (aop->aopu.pcop->type == PO_LITERAL)
6222 || (aop->aopu.pcop->type == PO_IMMEDIATE) ));
6227 /*-----------------------------------------------------------------*/
6228 /* genCmpEq - generates code for equal to */
6229 /*-----------------------------------------------------------------*/
6230 static void genCmpEq (iCode *ic, iCode *ifx)
6232 operand *left, *right, *result;
6233 symbol *falselbl = newiTempLabel(NULL);
6234 symbol *donelbl = newiTempLabel(NULL);
6236 int preserve_result = 0;
6237 int generate_result = 0;
6240 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6241 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6242 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6245 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6247 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
6249 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6250 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
6254 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
6256 operand *tmp = right ;
6261 if ( regsInCommon(left, result) || regsInCommon(right, result) )
6262 preserve_result = 1;
6264 if(result && AOP_SIZE(result))
6265 generate_result = 1;
6267 if(generate_result && !preserve_result)
6269 for(i = 0; i < AOP_SIZE(result); i++)
6270 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6273 for(i=0; i < AOP_SIZE(left); i++)
6275 if(AOP_TYPE(left) != AOP_ACC)
6278 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
6280 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
6283 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
6285 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
6287 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
6292 if(generate_result && preserve_result)
6294 for(i = 0; i < AOP_SIZE(result); i++)
6295 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6299 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
6301 if(generate_result && preserve_result)
6302 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6304 if(ifx && IC_TRUE(ifx))
6305 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6307 if(ifx && IC_FALSE(ifx))
6308 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6310 pic16_emitpLabel(falselbl->key);
6314 if(ifx && IC_FALSE(ifx))
6315 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6317 if(generate_result && preserve_result)
6319 for(i = 0; i < AOP_SIZE(result); i++)
6320 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6323 pic16_emitpLabel(donelbl->key);
6329 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6330 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6331 pic16_freeAsmop(result,NULL,ic,TRUE);
6337 // old version kept for reference
6339 /*-----------------------------------------------------------------*/
6340 /* genCmpEq - generates code for equal to */
6341 /*-----------------------------------------------------------------*/
6342 static void genCmpEq (iCode *ic, iCode *ifx)
6344 operand *left, *right, *result;
6345 unsigned long lit = 0L;
6347 symbol *falselbl = newiTempLabel(NULL);
6350 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6353 DEBUGpic16_emitcode ("; ifx is non-null","");
6355 DEBUGpic16_emitcode ("; ifx is null","");
6357 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6358 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6359 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6361 size = max(AOP_SIZE(left),AOP_SIZE(right));
6363 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6365 /* if literal, literal on the right or
6366 if the right is in a pointer register and left
6368 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
6369 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
6370 operand *tmp = right ;
6376 if(ifx && !AOP_SIZE(result)){
6378 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
6379 /* if they are both bit variables */
6380 if (AOP_TYPE(left) == AOP_CRY &&
6381 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6382 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
6383 if(AOP_TYPE(right) == AOP_LIT){
6384 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6386 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6387 pic16_emitcode("cpl","c");
6388 } else if(lit == 1L) {
6389 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6391 pic16_emitcode("clr","c");
6393 /* AOP_TYPE(right) == AOP_CRY */
6395 symbol *lbl = newiTempLabel(NULL);
6396 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6397 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6398 pic16_emitcode("cpl","c");
6399 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6401 /* if true label then we jump if condition
6403 tlbl = newiTempLabel(NULL);
6404 if ( IC_TRUE(ifx) ) {
6405 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
6406 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
6408 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
6409 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
6411 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6414 /* left and right are both bit variables, result is carry */
6417 resolveIfx(&rIfx,ifx);
6419 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
6420 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
6421 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
6422 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
6427 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
6429 /* They're not both bit variables. Is the right a literal? */
6430 if(AOP_TYPE(right) == AOP_LIT) {
6431 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6436 switch(lit & 0xff) {
6438 if ( IC_TRUE(ifx) ) {
6439 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
6441 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6443 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6444 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6448 if ( IC_TRUE(ifx) ) {
6449 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
6451 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6453 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6454 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6458 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6460 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6465 /* end of size == 1 */
6469 genc16bit2lit(left,lit,offset);
6472 /* end of size == 2 */
6477 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6478 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
6479 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6480 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6483 /* search for patterns that can be optimized */
6485 genc16bit2lit(left,lit,0);
6489 emitSKPZ; // if hi word unequal
6491 emitSKPNZ; // if hi word equal
6493 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
6494 genc16bit2lit(left,lit,2);
6497 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6498 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6502 pic16_emitpLabel(falselbl->key);
6511 } else if(AOP_TYPE(right) == AOP_CRY ) {
6512 /* we know the left is not a bit, but that the right is */
6513 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6514 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
6515 pic16_popGet(AOP(right),offset));
6516 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
6518 /* if the two are equal, then W will be 0 and the Z bit is set
6519 * we could test Z now, or go ahead and check the high order bytes if
6520 * the variable we're comparing is larger than a byte. */
6523 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
6525 if ( IC_TRUE(ifx) ) {
6527 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6528 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6531 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6532 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6536 /* They're both variables that are larger than bits */
6539 tlbl = newiTempLabel(NULL);
6542 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6543 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6545 if ( IC_TRUE(ifx) ) {
6549 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
6551 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
6552 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
6556 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
6559 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6560 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6565 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
6567 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6568 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6572 if(s>1 && IC_TRUE(ifx)) {
6573 pic16_emitpLabel(tlbl->key);
6574 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6578 /* mark the icode as generated */
6583 /* if they are both bit variables */
6584 if (AOP_TYPE(left) == AOP_CRY &&
6585 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6586 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
6587 if(AOP_TYPE(right) == AOP_LIT){
6588 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6590 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6591 pic16_emitcode("cpl","c");
6592 } else if(lit == 1L) {
6593 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6595 pic16_emitcode("clr","c");
6597 /* AOP_TYPE(right) == AOP_CRY */
6599 symbol *lbl = newiTempLabel(NULL);
6600 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6601 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6602 pic16_emitcode("cpl","c");
6603 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6606 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
6607 pic16_outBitC(result);
6611 genIfxJump (ifx,"c");
6614 /* if the result is used in an arithmetic operation
6615 then put the result in place */
6616 pic16_outBitC(result);
6619 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
6620 gencjne(left,right,result,ifx);
6623 gencjne(left,right,newiTempLabel(NULL));
6625 if(IC_TRUE(ifx)->key)
6626 gencjne(left,right,IC_TRUE(ifx)->key);
6628 gencjne(left,right,IC_FALSE(ifx)->key);
6632 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
6633 pic16_aopPut(AOP(result),"a",0);
6638 genIfxJump (ifx,"a");
6642 /* if the result is used in an arithmetic operation
6643 then put the result in place */
6645 if (AOP_TYPE(result) != AOP_CRY)
6646 pic16_outAcc(result);
6648 /* leave the result in acc */
6652 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6653 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6654 pic16_freeAsmop(result,NULL,ic,TRUE);
6658 /*-----------------------------------------------------------------*/
6659 /* ifxForOp - returns the icode containing the ifx for operand */
6660 /*-----------------------------------------------------------------*/
6661 static iCode *ifxForOp ( operand *op, iCode *ic )
6663 /* if true symbol then needs to be assigned */
6664 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6665 if (IS_TRUE_SYMOP(op))
6668 /* if this has register type condition and
6669 the next instruction is ifx with the same operand
6670 and live to of the operand is upto the ifx only then */
6672 && ic->next->op == IFX
6673 && IC_COND(ic->next)->key == op->key
6674 && OP_SYMBOL(op)->liveTo <= ic->next->seq
6676 DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
6681 ic->next->op == IFX &&
6682 IC_COND(ic->next)->key == op->key) {
6683 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6687 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6689 ic->next->op == IFX)
6690 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6693 ic->next->op == IFX &&
6694 IC_COND(ic->next)->key == op->key) {
6695 DEBUGpic16_emitcode ("; "," key is okay");
6696 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6697 OP_SYMBOL(op)->liveTo,
6702 /* the code below is completely untested
6703 * it just allows ulong2fs.c compile -- VR */
6706 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6707 __FILE__, __FUNCTION__, __LINE__);
6709 /* if this has register type condition and
6710 the next instruction is ifx with the same operand
6711 and live to of the operand is upto the ifx only then */
6713 ic->next->op == IFX &&
6714 IC_COND(ic->next)->key == op->key &&
6715 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6719 ic->next->op == IFX &&
6720 IC_COND(ic->next)->key == op->key) {
6721 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6725 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6726 __FILE__, __FUNCTION__, __LINE__);
6728 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6733 /*-----------------------------------------------------------------*/
6734 /* genAndOp - for && operation */
6735 /*-----------------------------------------------------------------*/
6736 static void genAndOp (iCode *ic)
6738 operand *left,*right, *result;
6741 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6742 /* note here that && operations that are in an
6743 if statement are taken away by backPatchLabels
6744 only those used in arthmetic operations remain */
6745 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6746 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6747 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6749 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6751 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6752 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6753 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6755 /* if both are bit variables */
6756 /* if (AOP_TYPE(left) == AOP_CRY && */
6757 /* AOP_TYPE(right) == AOP_CRY ) { */
6758 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6759 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6760 /* pic16_outBitC(result); */
6762 /* tlbl = newiTempLabel(NULL); */
6763 /* pic16_toBoolean(left); */
6764 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6765 /* pic16_toBoolean(right); */
6766 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6767 /* pic16_outBitAcc(result); */
6770 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6771 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6772 pic16_freeAsmop(result,NULL,ic,TRUE);
6776 /*-----------------------------------------------------------------*/
6777 /* genOrOp - for || operation */
6778 /*-----------------------------------------------------------------*/
6781 modified this code, but it doesn't appear to ever get called
6784 static void genOrOp (iCode *ic)
6786 operand *left,*right, *result;
6789 /* note here that || operations that are in an
6790 if statement are taken away by backPatchLabels
6791 only those used in arthmetic operations remain */
6792 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6793 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6794 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6795 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6797 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6799 /* if both are bit variables */
6800 if (AOP_TYPE(left) == AOP_CRY &&
6801 AOP_TYPE(right) == AOP_CRY ) {
6802 pic16_emitcode("clrc","");
6803 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6804 AOP(left)->aopu.aop_dir,
6805 AOP(left)->aopu.aop_dir);
6806 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6807 AOP(right)->aopu.aop_dir,
6808 AOP(right)->aopu.aop_dir);
6809 pic16_emitcode("setc","");
6812 tlbl = newiTempLabel(NULL);
6813 pic16_toBoolean(left);
6815 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
6816 pic16_toBoolean(right);
6817 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6819 pic16_outBitAcc(result);
6822 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6823 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6824 pic16_freeAsmop(result,NULL,ic,TRUE);
6827 /*-----------------------------------------------------------------*/
6828 /* isLiteralBit - test if lit == 2^n */
6829 /*-----------------------------------------------------------------*/
6830 static int isLiteralBit(unsigned long lit)
6832 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6833 0x100L,0x200L,0x400L,0x800L,
6834 0x1000L,0x2000L,0x4000L,0x8000L,
6835 0x10000L,0x20000L,0x40000L,0x80000L,
6836 0x100000L,0x200000L,0x400000L,0x800000L,
6837 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6838 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6841 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6842 for(idx = 0; idx < 32; idx++)
6848 /*-----------------------------------------------------------------*/
6849 /* continueIfTrue - */
6850 /*-----------------------------------------------------------------*/
6851 static void continueIfTrue (iCode *ic)
6853 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6855 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6859 /*-----------------------------------------------------------------*/
6861 /*-----------------------------------------------------------------*/
6862 static void jumpIfTrue (iCode *ic)
6864 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6866 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6870 /*-----------------------------------------------------------------*/
6871 /* jmpTrueOrFalse - */
6872 /*-----------------------------------------------------------------*/
6873 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6875 // ugly but optimized by peephole
6876 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6878 symbol *nlbl = newiTempLabel(NULL);
6879 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6880 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6881 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6882 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6885 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6886 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6891 /*-----------------------------------------------------------------*/
6892 /* genAnd - code for and */
6893 /*-----------------------------------------------------------------*/
6894 static void genAnd (iCode *ic, iCode *ifx)
6896 operand *left, *right, *result;
6898 unsigned long lit = 0L;
6903 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6904 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6905 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6906 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6908 resolveIfx(&rIfx,ifx);
6910 /* if left is a literal & right is not then exchange them */
6911 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6912 AOP_NEEDSACC(left)) {
6913 operand *tmp = right ;
6918 /* if result = right then exchange them */
6919 if(pic16_sameRegs(AOP(result),AOP(right))){
6920 operand *tmp = right ;
6925 /* if right is bit then exchange them */
6926 if (AOP_TYPE(right) == AOP_CRY &&
6927 AOP_TYPE(left) != AOP_CRY){
6928 operand *tmp = right ;
6932 if(AOP_TYPE(right) == AOP_LIT)
6933 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6935 size = AOP_SIZE(result);
6937 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6940 // result = bit & yy;
6941 if (AOP_TYPE(left) == AOP_CRY){
6942 // c = bit & literal;
6943 if(AOP_TYPE(right) == AOP_LIT){
6945 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6948 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6951 if(size && (AOP_TYPE(result) == AOP_CRY)){
6952 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6955 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6959 pic16_emitcode("clr","c");
6962 if (AOP_TYPE(right) == AOP_CRY){
6964 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6965 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6968 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6970 pic16_emitcode("rrc","a");
6971 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6977 pic16_outBitC(result);
6979 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6980 genIfxJump(ifx, "c");
6984 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6985 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6986 if((AOP_TYPE(right) == AOP_LIT) &&
6987 (AOP_TYPE(result) == AOP_CRY) &&
6988 (AOP_TYPE(left) != AOP_CRY)){
6989 int posbit = isLiteralBit(lit);
6993 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6996 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
7002 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7003 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
7005 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7006 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
7009 DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
7010 size = AOP_SIZE(left);
7013 int bp = posbit, ofs=0;
7020 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
7021 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
7025 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
7026 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7028 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
7035 symbol *tlbl = newiTempLabel(NULL);
7036 int sizel = AOP_SIZE(left);
7042 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
7044 /* patch provided by Aaron Colwell */
7045 if((posbit = isLiteralBit(bytelit)) != 0) {
7046 pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
7047 pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
7048 (posbit-1),0, PO_GPR_REGISTER));
7050 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
7051 // pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7053 if (bytelit == 0xff) {
7054 /* Aaron had a MOVF instruction here, changed to MOVFW cause
7055 * a peephole could optimize it out -- VR */
7056 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7058 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7059 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
7062 pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
7063 pic16_popGetLabel(tlbl->key));
7067 /* old code, left here for reference -- VR 09/2004 */
7068 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7070 if((posbit = isLiteralBit(bytelit)) != 0)
7071 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
7073 if(bytelit != 0x0FFL)
7074 pic16_emitcode("anl","a,%s",
7075 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
7076 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7082 // bit = left & literal
7085 pic16_emitpLabel(tlbl->key);
7087 // if(left & literal)
7090 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7091 pic16_emitpLabel(tlbl->key);
7098 pic16_outBitC(result);
7102 /* if left is same as result */
7103 if(pic16_sameRegs(AOP(result),AOP(left))){
7105 for(;size--; offset++,lit>>=8) {
7106 if(AOP_TYPE(right) == AOP_LIT){
7107 switch(lit & 0xff) {
7109 /* and'ing with 0 has clears the result */
7110 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7111 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7114 /* and'ing with 0xff is a nop when the result and left are the same */
7119 int p = my_powof2( (~lit) & 0xff );
7121 /* only one bit is set in the literal, so use a bcf instruction */
7122 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
7123 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7126 pic16_emitcode("movlw","0x%x", (lit & 0xff));
7127 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7128 if(know_W != (lit&0xff))
7129 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7131 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7136 if (AOP_TYPE(left) == AOP_ACC) {
7137 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7139 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7140 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7147 // left & result in different registers
7148 if(AOP_TYPE(result) == AOP_CRY){
7150 // if(size), result in bit
7151 // if(!size && ifx), conditional oper: if(left & right)
7152 symbol *tlbl = newiTempLabel(NULL);
7153 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
7155 pic16_emitcode("setb","c");
7157 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7158 pic16_emitcode("anl","a,%s",
7159 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7160 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7165 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7166 pic16_outBitC(result);
7168 jmpTrueOrFalse(ifx, tlbl);
7170 for(;(size--);offset++) {
7172 // result = left & right
7173 if(AOP_TYPE(right) == AOP_LIT){
7174 int t = (lit >> (offset*8)) & 0x0FFL;
7177 pic16_emitcode("clrf","%s",
7178 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7179 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7182 pic16_emitcode("movf","%s,w",
7183 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7184 pic16_emitcode("movwf","%s",
7185 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7186 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7187 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7190 pic16_emitcode("movlw","0x%x",t);
7191 pic16_emitcode("andwf","%s,w",
7192 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7193 pic16_emitcode("movwf","%s",
7194 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7196 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7197 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7198 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7203 if (AOP_TYPE(left) == AOP_ACC) {
7204 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7205 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7207 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7208 pic16_emitcode("andwf","%s,w",
7209 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7210 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7211 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7213 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7214 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7220 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7221 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7222 pic16_freeAsmop(result,NULL,ic,TRUE);
7225 /*-----------------------------------------------------------------*/
7226 /* genOr - code for or */
7227 /*-----------------------------------------------------------------*/
7228 static void genOr (iCode *ic, iCode *ifx)
7230 operand *left, *right, *result;
7232 unsigned long lit = 0L;
7234 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7236 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7237 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7238 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7240 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7242 /* if left is a literal & right is not then exchange them */
7243 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7244 AOP_NEEDSACC(left)) {
7245 operand *tmp = right ;
7250 /* if result = right then exchange them */
7251 if(pic16_sameRegs(AOP(result),AOP(right))){
7252 operand *tmp = right ;
7257 /* if right is bit then exchange them */
7258 if (AOP_TYPE(right) == AOP_CRY &&
7259 AOP_TYPE(left) != AOP_CRY){
7260 operand *tmp = right ;
7265 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7267 if(AOP_TYPE(right) == AOP_LIT)
7268 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7270 size = AOP_SIZE(result);
7274 if (AOP_TYPE(left) == AOP_CRY){
7275 if(AOP_TYPE(right) == AOP_LIT){
7276 // c = bit & literal;
7278 // lit != 0 => result = 1
7279 if(AOP_TYPE(result) == AOP_CRY){
7281 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7282 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7283 // AOP(result)->aopu.aop_dir,
7284 // AOP(result)->aopu.aop_dir);
7286 continueIfTrue(ifx);
7290 // lit == 0 => result = left
7291 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7293 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
7296 if (AOP_TYPE(right) == AOP_CRY){
7297 if(pic16_sameRegs(AOP(result),AOP(left))){
7299 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
7301 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7303 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7304 AOP(result)->aopu.aop_dir,
7305 AOP(result)->aopu.aop_dir);
7306 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7307 AOP(right)->aopu.aop_dir,
7308 AOP(right)->aopu.aop_dir);
7309 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7310 AOP(result)->aopu.aop_dir,
7311 AOP(result)->aopu.aop_dir);
7313 if( AOP_TYPE(result) == AOP_ACC) {
7314 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7315 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7316 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7317 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
7321 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7322 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7323 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7324 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7326 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7327 AOP(result)->aopu.aop_dir,
7328 AOP(result)->aopu.aop_dir);
7329 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
7330 AOP(right)->aopu.aop_dir,
7331 AOP(right)->aopu.aop_dir);
7332 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7333 AOP(left)->aopu.aop_dir,
7334 AOP(left)->aopu.aop_dir);
7335 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7336 AOP(result)->aopu.aop_dir,
7337 AOP(result)->aopu.aop_dir);
7342 symbol *tlbl = newiTempLabel(NULL);
7343 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7346 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7347 if( AOP_TYPE(right) == AOP_ACC) {
7348 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
7350 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7351 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7356 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
7357 pic16_emitcode(";XXX setb","c");
7358 pic16_emitcode(";XXX jb","%s,%05d_DS_",
7359 AOP(left)->aopu.aop_dir,tlbl->key+100);
7360 pic16_toBoolean(right);
7361 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7362 if((AOP_TYPE(result) == AOP_CRY) && ifx){
7363 jmpTrueOrFalse(ifx, tlbl);
7367 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7374 pic16_outBitC(result);
7376 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7377 genIfxJump(ifx, "c");
7381 // if(val | 0xZZ) - size = 0, ifx != FALSE -
7382 // bit = val | 0xZZ - size = 1, ifx = FALSE -
7383 if((AOP_TYPE(right) == AOP_LIT) &&
7384 (AOP_TYPE(result) == AOP_CRY) &&
7385 (AOP_TYPE(left) != AOP_CRY)){
7387 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7390 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
7392 continueIfTrue(ifx);
7395 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7396 // lit = 0, result = boolean(left)
7398 pic16_emitcode(";XXX setb","c");
7399 pic16_toBoolean(right);
7401 symbol *tlbl = newiTempLabel(NULL);
7402 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7404 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7406 genIfxJump (ifx,"a");
7410 pic16_outBitC(result);
7414 /* if left is same as result */
7415 if(pic16_sameRegs(AOP(result),AOP(left))){
7417 for(;size--; offset++,lit>>=8) {
7418 if(AOP_TYPE(right) == AOP_LIT){
7419 if((lit & 0xff) == 0)
7420 /* or'ing with 0 has no effect */
7423 int p = my_powof2(lit & 0xff);
7425 /* only one bit is set in the literal, so use a bsf instruction */
7426 pic16_emitpcode(POC_BSF,
7427 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7429 if(know_W != (lit & 0xff))
7430 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7431 know_W = lit & 0xff;
7432 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7437 if (AOP_TYPE(left) == AOP_ACC) {
7438 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
7439 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7441 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7442 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7444 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7445 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7451 // left & result in different registers
7452 if(AOP_TYPE(result) == AOP_CRY){
7454 // if(size), result in bit
7455 // if(!size && ifx), conditional oper: if(left | right)
7456 symbol *tlbl = newiTempLabel(NULL);
7457 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7458 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7462 pic16_emitcode(";XXX setb","c");
7464 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7465 pic16_emitcode(";XXX orl","a,%s",
7466 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7467 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7472 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7473 pic16_outBitC(result);
7475 jmpTrueOrFalse(ifx, tlbl);
7476 } else for(;(size--);offset++){
7478 // result = left & right
7479 if(AOP_TYPE(right) == AOP_LIT){
7480 int t = (lit >> (offset*8)) & 0x0FFL;
7483 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7484 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7486 pic16_emitcode("movf","%s,w",
7487 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7488 pic16_emitcode("movwf","%s",
7489 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7492 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7493 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7496 pic16_emitcode("movlw","0x%x",t);
7497 pic16_emitcode("iorwf","%s,w",
7498 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7499 pic16_emitcode("movwf","%s",
7500 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7506 // faster than result <- left, anl result,right
7507 // and better if result is SFR
7508 if (AOP_TYPE(left) == AOP_ACC) {
7509 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
7510 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7512 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7513 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7515 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7516 pic16_emitcode("iorwf","%s,w",
7517 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7519 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7520 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7525 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7526 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7527 pic16_freeAsmop(result,NULL,ic,TRUE);
7530 /*-----------------------------------------------------------------*/
7531 /* genXor - code for xclusive or */
7532 /*-----------------------------------------------------------------*/
7533 static void genXor (iCode *ic, iCode *ifx)
7535 operand *left, *right, *result;
7537 unsigned long lit = 0L;
7539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7541 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7542 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7543 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7545 /* if left is a literal & right is not ||
7546 if left needs acc & right does not */
7547 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7548 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
7549 operand *tmp = right ;
7554 /* if result = right then exchange them */
7555 if(pic16_sameRegs(AOP(result),AOP(right))){
7556 operand *tmp = right ;
7561 /* if right is bit then exchange them */
7562 if (AOP_TYPE(right) == AOP_CRY &&
7563 AOP_TYPE(left) != AOP_CRY){
7564 operand *tmp = right ;
7568 if(AOP_TYPE(right) == AOP_LIT)
7569 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7571 size = AOP_SIZE(result);
7575 if (AOP_TYPE(left) == AOP_CRY){
7576 if(AOP_TYPE(right) == AOP_LIT){
7577 // c = bit & literal;
7579 // lit>>1 != 0 => result = 1
7580 if(AOP_TYPE(result) == AOP_CRY){
7582 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
7583 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
7585 continueIfTrue(ifx);
7588 pic16_emitcode("setb","c");
7592 // lit == 0, result = left
7593 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7595 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7597 // lit == 1, result = not(left)
7598 if(size && pic16_sameRegs(AOP(result),AOP(left))){
7599 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
7600 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
7601 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
7604 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7605 pic16_emitcode("cpl","c");
7612 symbol *tlbl = newiTempLabel(NULL);
7613 if (AOP_TYPE(right) == AOP_CRY){
7615 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
7618 int sizer = AOP_SIZE(right);
7620 // if val>>1 != 0, result = 1
7621 pic16_emitcode("setb","c");
7623 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
7625 // test the msb of the lsb
7626 pic16_emitcode("anl","a,#0xfe");
7627 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7631 pic16_emitcode("rrc","a");
7633 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
7634 pic16_emitcode("cpl","c");
7635 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
7640 pic16_outBitC(result);
7642 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7643 genIfxJump(ifx, "c");
7647 if(pic16_sameRegs(AOP(result),AOP(left))){
7648 /* if left is same as result */
7649 for(;size--; offset++) {
7650 if(AOP_TYPE(right) == AOP_LIT){
7651 int t = (lit >> (offset*8)) & 0x0FFL;
7655 if (IS_AOP_PREG(left)) {
7656 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7657 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7658 pic16_aopPut(AOP(result),"a",offset);
7660 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7661 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7662 pic16_emitcode("xrl","%s,%s",
7663 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
7664 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7667 if (AOP_TYPE(left) == AOP_ACC)
7668 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7670 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7671 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7673 if (IS_AOP_PREG(left)) {
7674 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7675 pic16_aopPut(AOP(result),"a",offset);
7677 pic16_emitcode("xrl","%s,a",
7678 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7684 // left & result in different registers
7685 if(AOP_TYPE(result) == AOP_CRY){
7687 // if(size), result in bit
7688 // if(!size && ifx), conditional oper: if(left ^ right)
7689 symbol *tlbl = newiTempLabel(NULL);
7690 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7692 pic16_emitcode("setb","c");
7694 if((AOP_TYPE(right) == AOP_LIT) &&
7695 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
7696 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7698 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7699 pic16_emitcode("xrl","a,%s",
7700 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7702 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7707 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7708 pic16_outBitC(result);
7710 jmpTrueOrFalse(ifx, tlbl);
7711 } else for(;(size--);offset++){
7713 // result = left & right
7714 if(AOP_TYPE(right) == AOP_LIT){
7715 int t = (lit >> (offset*8)) & 0x0FFL;
7718 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7719 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7720 pic16_emitcode("movf","%s,w",
7721 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7722 pic16_emitcode("movwf","%s",
7723 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7726 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7727 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7728 pic16_emitcode("comf","%s,w",
7729 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7730 pic16_emitcode("movwf","%s",
7731 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7734 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7735 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7736 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7737 pic16_emitcode("movlw","0x%x",t);
7738 pic16_emitcode("xorwf","%s,w",
7739 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7740 pic16_emitcode("movwf","%s",
7741 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7747 // faster than result <- left, anl result,right
7748 // and better if result is SFR
7749 if (AOP_TYPE(left) == AOP_ACC) {
7750 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7751 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7753 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7754 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7755 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7756 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7758 if ( AOP_TYPE(result) != AOP_ACC){
7759 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7760 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7766 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7767 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7768 pic16_freeAsmop(result,NULL,ic,TRUE);
7771 /*-----------------------------------------------------------------*/
7772 /* genInline - write the inline code out */
7773 /*-----------------------------------------------------------------*/
7774 static void genInline (iCode *ic)
7776 char *buffer, *bp, *bp1;
7778 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7780 _G.inLine += (!options.asmpeep);
7782 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7783 strcpy(buffer,IC_INLINE(ic));
7785 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7787 /* emit each line as a code */
7793 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7801 /* print label, use this special format with NULL directive
7802 * to denote that the argument should not be indented with tab */
7803 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7810 if ((bp1 != bp) && *bp1)
7811 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7816 _G.inLine -= (!options.asmpeep);
7819 /*-----------------------------------------------------------------*/
7820 /* genRRC - rotate right with carry */
7821 /*-----------------------------------------------------------------*/
7822 static void genRRC (iCode *ic)
7824 operand *left , *result ;
7825 int size, offset = 0, same;
7827 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7829 /* rotate right with carry */
7831 result=IC_RESULT(ic);
7832 pic16_aopOp (left,ic,FALSE);
7833 pic16_aopOp (result,ic,FALSE);
7835 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7837 same = pic16_sameRegs(AOP(result),AOP(left));
7839 size = AOP_SIZE(result);
7841 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7843 /* get the lsb and put it into the carry */
7844 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7851 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7853 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7854 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7860 pic16_freeAsmop(left,NULL,ic,TRUE);
7861 pic16_freeAsmop(result,NULL,ic,TRUE);
7864 /*-----------------------------------------------------------------*/
7865 /* genRLC - generate code for rotate left with carry */
7866 /*-----------------------------------------------------------------*/
7867 static void genRLC (iCode *ic)
7869 operand *left , *result ;
7870 int size, offset = 0;
7873 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7874 /* rotate right with carry */
7876 result=IC_RESULT(ic);
7877 pic16_aopOp (left,ic,FALSE);
7878 pic16_aopOp (result,ic,FALSE);
7880 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7882 same = pic16_sameRegs(AOP(result),AOP(left));
7884 /* move it to the result */
7885 size = AOP_SIZE(result);
7887 /* get the msb and put it into the carry */
7888 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7895 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7897 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7898 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7905 pic16_freeAsmop(left,NULL,ic,TRUE);
7906 pic16_freeAsmop(result,NULL,ic,TRUE);
7910 /* gpasm can get the highest order bit with HIGH/UPPER
7911 * so the following probably is not needed -- VR */
7913 /*-----------------------------------------------------------------*/
7914 /* genGetHbit - generates code get highest order bit */
7915 /*-----------------------------------------------------------------*/
7916 static void genGetHbit (iCode *ic)
7918 operand *left, *result;
7920 result=IC_RESULT(ic);
7921 pic16_aopOp (left,ic,FALSE);
7922 pic16_aopOp (result,ic,FALSE);
7924 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7925 /* get the highest order byte into a */
7926 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7927 if(AOP_TYPE(result) == AOP_CRY){
7928 pic16_emitcode("rlc","a");
7929 pic16_outBitC(result);
7932 pic16_emitcode("rl","a");
7933 pic16_emitcode("anl","a,#0x01");
7934 pic16_outAcc(result);
7938 pic16_freeAsmop(left,NULL,ic,TRUE);
7939 pic16_freeAsmop(result,NULL,ic,TRUE);
7943 /*-----------------------------------------------------------------*/
7944 /* AccRol - rotate left accumulator by known count */
7945 /*-----------------------------------------------------------------*/
7946 static void AccRol (int shCount)
7948 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7949 shCount &= 0x0007; // shCount : 0..7
7954 pic16_emitcode("rl","a");
7957 pic16_emitcode("rl","a");
7958 pic16_emitcode("rl","a");
7961 pic16_emitcode("swap","a");
7962 pic16_emitcode("rr","a");
7965 pic16_emitcode("swap","a");
7968 pic16_emitcode("swap","a");
7969 pic16_emitcode("rl","a");
7972 pic16_emitcode("rr","a");
7973 pic16_emitcode("rr","a");
7976 pic16_emitcode("rr","a");
7982 /*-----------------------------------------------------------------*/
7983 /* AccLsh - left shift accumulator by known count */
7984 /*-----------------------------------------------------------------*/
7985 static void AccLsh (int shCount)
7987 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7993 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7996 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7997 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8000 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8001 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8004 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8007 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8008 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8011 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8012 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8015 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8019 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
8022 /*-----------------------------------------------------------------*/
8023 /* AccRsh - right shift accumulator by known count */
8024 /*-----------------------------------------------------------------*/
8025 static void AccRsh (int shCount, int andmask)
8027 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8032 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8035 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8036 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8039 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8040 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8043 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8046 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8047 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8050 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8051 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8054 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8059 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
8061 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
8065 /*-----------------------------------------------------------------*/
8066 /* AccSRsh - signed right shift accumulator by known count */
8067 /*-----------------------------------------------------------------*/
8068 static void AccSRsh (int shCount)
8071 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8074 pic16_emitcode("mov","c,acc.7");
8075 pic16_emitcode("rrc","a");
8076 } else if(shCount == 2){
8077 pic16_emitcode("mov","c,acc.7");
8078 pic16_emitcode("rrc","a");
8079 pic16_emitcode("mov","c,acc.7");
8080 pic16_emitcode("rrc","a");
8082 tlbl = newiTempLabel(NULL);
8083 /* rotate right accumulator */
8084 AccRol(8 - shCount);
8085 /* and kill the higher order bits */
8086 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
8087 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
8088 pic16_emitcode("orl","a,#0x%02x",
8089 (unsigned char)~SRMask[shCount]);
8090 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8096 /*-----------------------------------------------------------------*/
8097 /* shiftR1Left2Result - shift right one byte from left to result */
8098 /*-----------------------------------------------------------------*/
8099 static void shiftR1Left2ResultSigned (operand *left, int offl,
8100 operand *result, int offr,
8105 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8107 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8111 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8113 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8115 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8122 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8124 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8126 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8127 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8129 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8130 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8136 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8138 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8139 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8142 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8143 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8144 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8146 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8147 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
8149 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8153 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8154 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8155 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8156 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
8157 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8161 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8163 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8164 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8166 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8167 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
8168 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8169 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
8170 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8175 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8176 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8177 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
8178 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8179 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
8180 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8182 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8183 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8184 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8185 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8186 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8192 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8193 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8194 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8195 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8197 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8198 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8199 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8207 /*-----------------------------------------------------------------*/
8208 /* shiftR1Left2Result - shift right one byte from left to result */
8209 /*-----------------------------------------------------------------*/
8210 static void shiftR1Left2Result (operand *left, int offl,
8211 operand *result, int offr,
8212 int shCount, int sign)
8216 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8218 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8220 /* Copy the msb into the carry if signed. */
8222 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
8232 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8234 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8235 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8241 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8243 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8244 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8247 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8252 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8254 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8255 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8258 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8259 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8260 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8261 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8265 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8266 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8267 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8271 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8272 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0e));
8273 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8275 pic16_emitpcode(POC_RRNCF, pic16_popGet(AOP(result),offr));
8280 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left),offl));
8281 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x81));
8282 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8283 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8284 pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(result),offr));
8289 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8290 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8291 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8300 /*-----------------------------------------------------------------*/
8301 /* shiftL1Left2Result - shift left one byte from left to result */
8302 /*-----------------------------------------------------------------*/
8303 static void shiftL1Left2Result (operand *left, int offl,
8304 operand *result, int offr, int shCount)
8309 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8311 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
8312 DEBUGpic16_emitcode ("; ***","same = %d",same);
8313 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8315 /* shift left accumulator */
8316 //AccLsh(shCount); // don't comment out just yet...
8317 // pic16_aopPut(AOP(result),"a",offr);
8321 /* Shift left 1 bit position */
8322 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8324 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
8326 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
8327 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8331 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8332 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
8333 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8334 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8337 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8338 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
8339 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8340 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8341 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8344 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8345 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8346 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8349 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8350 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8351 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8352 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8355 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8356 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
8357 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8358 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8359 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8362 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8363 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8364 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8368 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
8373 /*-----------------------------------------------------------------*/
8374 /* movLeft2Result - move byte from left to result */
8375 /*-----------------------------------------------------------------*/
8376 static void movLeft2Result (operand *left, int offl,
8377 operand *result, int offr)
8380 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8381 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
8382 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8384 if (*l == '@' && (IS_AOP_PREG(result))) {
8385 pic16_emitcode("mov","a,%s",l);
8386 pic16_aopPut(AOP(result),"a",offr);
8388 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8389 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8394 /*-----------------------------------------------------------------*/
8395 /* shiftL2Left2Result - shift left two bytes from left to result */
8396 /*-----------------------------------------------------------------*/
8397 static void shiftL2Left2Result (operand *left, int offl,
8398 operand *result, int offr, int shCount)
8400 int same = pic16_sameRegs(AOP(result), AOP(left));
8403 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
8405 if (same && (offl != offr)) { // shift bytes
8408 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8409 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8411 } else { // just treat as different later on
8424 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
8425 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8426 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8430 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8431 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8437 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
8438 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
8439 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8440 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8441 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
8442 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8443 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8445 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8446 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8450 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8451 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8452 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8453 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8454 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8455 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8456 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8457 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8458 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8459 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8462 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8463 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8464 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8465 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8466 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8476 /* note, use a mov/add for the shift since the mov has a
8477 chance of getting optimized out */
8478 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8479 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8480 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8481 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8482 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8486 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8487 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8493 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8494 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
8495 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8496 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8497 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8498 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0F));
8499 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8500 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8504 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8505 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8509 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8510 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8511 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
8512 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8514 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8515 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8516 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8517 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8518 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8519 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8520 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8521 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8524 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8525 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8526 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8527 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8528 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8533 /*-----------------------------------------------------------------*/
8534 /* shiftR2Left2Result - shift right two bytes from left to result */
8535 /*-----------------------------------------------------------------*/
8536 static void shiftR2Left2Result (operand *left, int offl,
8537 operand *result, int offr,
8538 int shCount, int sign)
8540 int same = pic16_sameRegs(AOP(result), AOP(left));
8542 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
8544 if (same && (offl != offr)) { // shift right bytes
8547 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8548 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8550 } else { // just treat as different later on
8562 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8567 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8568 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8570 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8571 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8572 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8573 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8578 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8581 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8582 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8589 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
8590 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
8591 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8593 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8594 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
8595 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8596 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8598 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8599 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8600 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8602 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8603 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8604 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8605 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8606 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8610 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8611 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8615 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
8616 pic16_emitpcode(POC_BTFSC,
8617 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
8618 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8626 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8627 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8629 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8630 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8631 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8632 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8634 pic16_emitpcode(POC_BTFSC,
8635 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8636 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8638 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8639 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
8640 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8641 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8643 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8644 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8645 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8646 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8647 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8648 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8649 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
8650 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8652 pic16_emitpcode(POC_BTFSC,
8653 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8654 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8656 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8657 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8664 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8665 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8666 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8667 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
8670 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
8672 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8677 /*-----------------------------------------------------------------*/
8678 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
8679 /*-----------------------------------------------------------------*/
8680 static void shiftLLeftOrResult (operand *left, int offl,
8681 operand *result, int offr, int shCount)
8683 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8685 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8686 /* shift left accumulator */
8688 /* or with result */
8689 /* back to result */
8690 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8693 /*-----------------------------------------------------------------*/
8694 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
8695 /*-----------------------------------------------------------------*/
8696 static void shiftRLeftOrResult (operand *left, int offl,
8697 operand *result, int offr, int shCount)
8699 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8701 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8702 /* shift right accumulator */
8704 /* or with result */
8705 /* back to result */
8706 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8709 /*-----------------------------------------------------------------*/
8710 /* genlshOne - left shift a one byte quantity by known count */
8711 /*-----------------------------------------------------------------*/
8712 static void genlshOne (operand *result, operand *left, int shCount)
8714 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8715 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8718 /*-----------------------------------------------------------------*/
8719 /* genlshTwo - left shift two bytes by known amount != 0 */
8720 /*-----------------------------------------------------------------*/
8721 static void genlshTwo (operand *result,operand *left, int shCount)
8725 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8726 size = pic16_getDataSize(result);
8728 /* if shCount >= 8 */
8734 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8736 movLeft2Result(left, LSB, result, MSB16);
8738 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8741 /* 1 <= shCount <= 7 */
8744 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8746 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8750 /*-----------------------------------------------------------------*/
8751 /* shiftLLong - shift left one long from left to result */
8752 /* offr = LSB or MSB16 */
8753 /*-----------------------------------------------------------------*/
8754 static void shiftLLong (operand *left, operand *result, int offr )
8756 int size = AOP_SIZE(result);
8757 int same = pic16_sameRegs(AOP(left),AOP(result));
8760 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8762 if (same && (offr == MSB16)) { //shift one byte
8763 for(i=size-1;i>=MSB16;i--) {
8764 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8765 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8768 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8771 if (size > LSB+offr ){
8773 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8775 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8776 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8780 if(size > MSB16+offr){
8782 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8784 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8785 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8789 if(size > MSB24+offr){
8791 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8793 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8794 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8798 if(size > MSB32+offr){
8800 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8802 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8803 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8807 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8811 /*-----------------------------------------------------------------*/
8812 /* genlshFour - shift four byte by a known amount != 0 */
8813 /*-----------------------------------------------------------------*/
8814 static void genlshFour (operand *result, operand *left, int shCount)
8818 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8819 size = AOP_SIZE(result);
8821 /* if shifting more that 3 bytes */
8822 if (shCount >= 24 ) {
8825 /* lowest order of left goes to the highest
8826 order of the destination */
8827 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8829 movLeft2Result(left, LSB, result, MSB32);
8831 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8832 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8833 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8838 /* more than two bytes */
8839 else if ( shCount >= 16 ) {
8840 /* lower order two bytes goes to higher order two bytes */
8842 /* if some more remaining */
8844 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8846 movLeft2Result(left, MSB16, result, MSB32);
8847 movLeft2Result(left, LSB, result, MSB24);
8849 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8850 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8854 /* if more than 1 byte */
8855 else if ( shCount >= 8 ) {
8856 /* lower order three bytes goes to higher order three bytes */
8860 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8862 movLeft2Result(left, LSB, result, MSB16);
8864 else{ /* size = 4 */
8866 movLeft2Result(left, MSB24, result, MSB32);
8867 movLeft2Result(left, MSB16, result, MSB24);
8868 movLeft2Result(left, LSB, result, MSB16);
8869 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8871 else if(shCount == 1)
8872 shiftLLong(left, result, MSB16);
8874 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8875 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8876 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8877 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8882 /* 1 <= shCount <= 7 */
8883 else if(shCount <= 3)
8885 shiftLLong(left, result, LSB);
8886 while(--shCount >= 1)
8887 shiftLLong(result, result, LSB);
8889 /* 3 <= shCount <= 7, optimize */
8891 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8892 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8893 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8897 /*-----------------------------------------------------------------*/
8898 /* genLeftShiftLiteral - left shifting by known count */
8899 /*-----------------------------------------------------------------*/
8900 static void genLeftShiftLiteral (operand *left,
8905 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8908 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8909 pic16_freeAsmop(right,NULL,ic,TRUE);
8911 pic16_aopOp(left,ic,FALSE);
8912 pic16_aopOp(result,ic,FALSE);
8914 size = getSize(operandType(result));
8917 pic16_emitcode("; shift left ","result %d, left %d",size,
8921 /* I suppose that the left size >= result size */
8924 movLeft2Result(left, size, result, size);
8928 else if(shCount >= (size * 8))
8930 pic16_aopPut(AOP(result),zero,size);
8934 genlshOne (result,left,shCount);
8939 genlshTwo (result,left,shCount);
8943 genlshFour (result,left,shCount);
8947 pic16_freeAsmop(left,NULL,ic,TRUE);
8948 pic16_freeAsmop(result,NULL,ic,TRUE);
8951 /*-----------------------------------------------------------------*
8952 * genMultiAsm - repeat assembly instruction for size of register.
8953 * if endian == 1, then the high byte (i.e base address + size of
8954 * register) is used first else the low byte is used first;
8955 *-----------------------------------------------------------------*/
8956 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8961 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8974 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8979 /*-----------------------------------------------------------------*/
8980 /* genLeftShift - generates code for left shifting */
8981 /*-----------------------------------------------------------------*/
8982 static void genLeftShift (iCode *ic)
8984 operand *left,*right, *result;
8987 symbol *tlbl , *tlbl1;
8990 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8992 right = IC_RIGHT(ic);
8994 result = IC_RESULT(ic);
8996 pic16_aopOp(right,ic,FALSE);
8998 /* if the shift count is known then do it
8999 as efficiently as possible */
9000 if (AOP_TYPE(right) == AOP_LIT) {
9001 genLeftShiftLiteral (left,right,result,ic);
9005 /* shift count is unknown then we have to form
9006 * a loop. Get the loop count in WREG : Note: we take
9007 * only the lower order byte since shifting
9008 * more than 32 bits make no sense anyway, ( the
9009 * largest size of an object can be only 32 bits ) */
9011 pic16_aopOp(left,ic,FALSE);
9012 pic16_aopOp(result,ic,FALSE);
9014 /* now move the left to the result if they are not the
9015 * same, and if size > 1,
9016 * and if right is not same to result (!!!) -- VR */
9017 if (!pic16_sameRegs(AOP(left),AOP(result))
9018 && (AOP_SIZE(result) > 1)) {
9020 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9022 size = AOP_SIZE(result);
9027 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9028 if (*l == '@' && (IS_AOP_PREG(result))) {
9030 pic16_emitcode("mov","a,%s",l);
9031 pic16_aopPut(AOP(result),"a",offset);
9035 /* we don't know if left is a literal or a register, take care -- VR */
9036 mov2f(AOP(result), AOP(left), offset);
9042 size = AOP_SIZE(result);
9044 /* if it is only one byte then */
9046 if(optimized_for_speed) {
9047 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9048 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9049 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9050 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9051 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9052 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9053 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9054 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9055 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9056 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9057 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9058 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9063 tlbl = newiTempLabel(NULL);
9066 /* this is already done, why change it? */
9067 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9068 mov2f(AOP(result), AOP(left), 0);
9072 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9073 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9074 pic16_emitpLabel(tlbl->key);
9075 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9076 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9078 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9083 if (pic16_sameRegs(AOP(left),AOP(result))) {
9085 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9087 tlbl = newiTempLabel(NULL);
9088 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9089 genMultiAsm(POC_RRCF, result, size,1);
9090 pic16_emitpLabel(tlbl->key);
9091 genMultiAsm(POC_RLCF, result, size,0);
9092 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9094 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9098 //tlbl = newiTempLabel(NULL);
9100 //tlbl1 = newiTempLabel(NULL);
9102 //reAdjustPreg(AOP(result));
9104 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9105 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9106 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9108 //pic16_emitcode("add","a,acc");
9109 //pic16_aopPut(AOP(result),"a",offset++);
9111 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9113 // pic16_emitcode("rlc","a");
9114 // pic16_aopPut(AOP(result),"a",offset++);
9116 //reAdjustPreg(AOP(result));
9118 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9119 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9122 tlbl = newiTempLabel(NULL);
9123 tlbl1= newiTempLabel(NULL);
9125 size = AOP_SIZE(result);
9128 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9130 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9132 /* offset should be 0, 1 or 3 */
9134 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9136 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9138 pic16_emitpcode(POC_MOVWF, pctemp);
9141 pic16_emitpLabel(tlbl->key);
9144 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9146 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9148 pic16_emitpcode(POC_DECFSZ, pctemp);
9149 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9150 pic16_emitpLabel(tlbl1->key);
9152 pic16_popReleaseTempReg(pctemp,1);
9156 pic16_freeAsmop (right,NULL,ic,TRUE);
9157 pic16_freeAsmop(left,NULL,ic,TRUE);
9158 pic16_freeAsmop(result,NULL,ic,TRUE);
9164 #error old code (left here for reference)
9165 /*-----------------------------------------------------------------*/
9166 /* genLeftShift - generates code for left shifting */
9167 /*-----------------------------------------------------------------*/
9168 static void genLeftShift (iCode *ic)
9170 operand *left,*right, *result;
9173 symbol *tlbl , *tlbl1;
9176 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9178 right = IC_RIGHT(ic);
9180 result = IC_RESULT(ic);
9182 pic16_aopOp(right,ic,FALSE);
9184 /* if the shift count is known then do it
9185 as efficiently as possible */
9186 if (AOP_TYPE(right) == AOP_LIT) {
9187 genLeftShiftLiteral (left,right,result,ic);
9191 /* shift count is unknown then we have to form
9192 a loop get the loop count in B : Note: we take
9193 only the lower order byte since shifting
9194 more that 32 bits make no sense anyway, ( the
9195 largest size of an object can be only 32 bits ) */
9198 pic16_aopOp(left,ic,FALSE);
9199 pic16_aopOp(result,ic,FALSE);
9201 /* now move the left to the result if they are not the
9203 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9204 AOP_SIZE(result) > 1) {
9206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9208 size = AOP_SIZE(result);
9211 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9212 if (*l == '@' && (IS_AOP_PREG(result))) {
9214 pic16_emitcode("mov","a,%s",l);
9215 pic16_aopPut(AOP(result),"a",offset);
9218 /* we don't know if left is a literal or a register, take care -- VR */
9219 mov2f(AOP(result), AOP(left), offset);
9225 size = AOP_SIZE(result);
9227 /* if it is only one byte then */
9229 if(optimized_for_speed) {
9230 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9231 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9232 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9233 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9234 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9235 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9236 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9237 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9238 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9239 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9240 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9241 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9246 tlbl = newiTempLabel(NULL);
9247 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9248 mov2f(AOP(result), AOP(left), 0);
9250 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9251 // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9254 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9255 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9256 pic16_emitpLabel(tlbl->key);
9257 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9258 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9260 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9265 if (pic16_sameRegs(AOP(left),AOP(result))) {
9267 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9269 tlbl = newiTempLabel(NULL);
9270 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9271 genMultiAsm(POC_RRCF, result, size,1);
9272 pic16_emitpLabel(tlbl->key);
9273 genMultiAsm(POC_RLCF, result, size,0);
9274 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9276 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9280 //tlbl = newiTempLabel(NULL);
9282 //tlbl1 = newiTempLabel(NULL);
9284 //reAdjustPreg(AOP(result));
9286 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9287 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9288 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9290 //pic16_emitcode("add","a,acc");
9291 //pic16_aopPut(AOP(result),"a",offset++);
9293 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9295 // pic16_emitcode("rlc","a");
9296 // pic16_aopPut(AOP(result),"a",offset++);
9298 //reAdjustPreg(AOP(result));
9300 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9301 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9304 tlbl = newiTempLabel(NULL);
9305 tlbl1= newiTempLabel(NULL);
9307 size = AOP_SIZE(result);
9310 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9312 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9314 /* offset should be 0, 1 or 3 */
9316 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9318 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9320 pic16_emitpcode(POC_MOVWF, pctemp);
9323 pic16_emitpLabel(tlbl->key);
9326 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9328 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9330 pic16_emitpcode(POC_DECFSZ, pctemp);
9331 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9332 pic16_emitpLabel(tlbl1->key);
9334 pic16_popReleaseTempReg(pctemp,1);
9338 pic16_freeAsmop (right,NULL,ic,TRUE);
9339 pic16_freeAsmop(left,NULL,ic,TRUE);
9340 pic16_freeAsmop(result,NULL,ic,TRUE);
9344 /*-----------------------------------------------------------------*/
9345 /* genrshOne - right shift a one byte quantity by known count */
9346 /*-----------------------------------------------------------------*/
9347 static void genrshOne (operand *result, operand *left,
9348 int shCount, int sign)
9350 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9351 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
9354 /*-----------------------------------------------------------------*/
9355 /* genrshTwo - right shift two bytes by known amount != 0 */
9356 /*-----------------------------------------------------------------*/
9357 static void genrshTwo (operand *result,operand *left,
9358 int shCount, int sign)
9360 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
9361 /* if shCount >= 8 */
9365 shiftR1Left2Result(left, MSB16, result, LSB,
9368 movLeft2Result(left, MSB16, result, LSB);
9370 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
9373 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9374 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
9378 /* 1 <= shCount <= 7 */
9380 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
9383 /*-----------------------------------------------------------------*/
9384 /* shiftRLong - shift right one long from left to result */
9385 /* offl = LSB or MSB16 */
9386 /*-----------------------------------------------------------------*/
9387 static void shiftRLong (operand *left, int offl,
9388 operand *result, int sign)
9390 int size = AOP_SIZE(result);
9391 int same = pic16_sameRegs(AOP(left),AOP(result));
9393 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
9395 if (same && (offl == MSB16)) { //shift one byte right
9396 for(i=MSB16;i<size;i++) {
9397 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
9398 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
9403 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
9409 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
9411 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
9412 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
9416 /* add sign of "a" */
9417 pic16_addSign(result, MSB32, sign);
9421 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
9423 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
9424 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
9428 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
9430 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
9431 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
9435 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
9438 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
9439 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
9444 /*-----------------------------------------------------------------*/
9445 /* genrshFour - shift four byte by a known amount != 0 */
9446 /*-----------------------------------------------------------------*/
9447 static void genrshFour (operand *result, operand *left,
9448 int shCount, int sign)
9450 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9451 /* if shifting more that 3 bytes */
9452 if(shCount >= 24 ) {
9455 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
9457 movLeft2Result(left, MSB32, result, LSB);
9459 pic16_addSign(result, MSB16, sign);
9461 else if(shCount >= 16){
9464 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
9466 movLeft2Result(left, MSB24, result, LSB);
9467 movLeft2Result(left, MSB32, result, MSB16);
9469 pic16_addSign(result, MSB24, sign);
9471 else if(shCount >= 8){
9474 shiftRLong(left, MSB16, result, sign);
9475 else if(shCount == 0){
9476 movLeft2Result(left, MSB16, result, LSB);
9477 movLeft2Result(left, MSB24, result, MSB16);
9478 movLeft2Result(left, MSB32, result, MSB24);
9479 pic16_addSign(result, MSB32, sign);
9481 else{ //shcount >= 2
9482 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
9483 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
9484 /* the last shift is signed */
9485 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
9486 pic16_addSign(result, MSB32, sign);
9489 else{ /* 1 <= shCount <= 7 */
9491 shiftRLong(left, LSB, result, sign);
9493 shiftRLong(result, LSB, result, sign);
9496 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
9497 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
9498 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
9503 /*-----------------------------------------------------------------*/
9504 /* genRightShiftLiteral - right shifting by known count */
9505 /*-----------------------------------------------------------------*/
9506 static void genRightShiftLiteral (operand *left,
9512 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
9515 pic16_freeAsmop(right,NULL,ic,TRUE);
9517 pic16_aopOp(left,ic,FALSE);
9518 pic16_aopOp(result,ic,FALSE);
9520 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
9523 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
9527 lsize = pic16_getDataSize(left);
9528 res_size = pic16_getDataSize(result);
9529 /* test the LEFT size !!! */
9531 /* I suppose that the left size >= result size */
9534 movLeft2Result(left, lsize, result, res_size);
9537 else if(shCount >= (lsize * 8)){
9540 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
9542 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9543 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
9548 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
9549 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9550 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9552 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
9557 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
9564 genrshOne (result,left,shCount,sign);
9568 genrshTwo (result,left,shCount,sign);
9572 genrshFour (result,left,shCount,sign);
9580 pic16_freeAsmop(left,NULL,ic,TRUE);
9581 pic16_freeAsmop(result,NULL,ic,TRUE);
9584 /*-----------------------------------------------------------------*/
9585 /* genSignedRightShift - right shift of signed number */
9586 /*-----------------------------------------------------------------*/
9587 static void genSignedRightShift (iCode *ic)
9589 operand *right, *left, *result;
9592 symbol *tlbl, *tlbl1 ;
9595 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
9597 /* we do it the hard way put the shift count in b
9598 and loop thru preserving the sign */
9599 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9601 right = IC_RIGHT(ic);
9603 result = IC_RESULT(ic);
9605 pic16_aopOp(right,ic,FALSE);
9606 pic16_aopOp(left,ic,FALSE);
9607 pic16_aopOp(result,ic,FALSE);
9610 if ( AOP_TYPE(right) == AOP_LIT) {
9611 genRightShiftLiteral (left,right,result,ic,1);
9614 /* shift count is unknown then we have to form
9615 a loop get the loop count in B : Note: we take
9616 only the lower order byte since shifting
9617 more that 32 bits make no sense anyway, ( the
9618 largest size of an object can be only 32 bits ) */
9620 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9621 //pic16_emitcode("inc","b");
9622 //pic16_freeAsmop (right,NULL,ic,TRUE);
9623 //pic16_aopOp(left,ic,FALSE);
9624 //pic16_aopOp(result,ic,FALSE);
9626 /* now move the left to the result if they are not the
9628 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9629 AOP_SIZE(result) > 1) {
9631 size = AOP_SIZE(result);
9635 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9636 if (*l == '@' && IS_AOP_PREG(result)) {
9638 pic16_emitcode("mov","a,%s",l);
9639 pic16_aopPut(AOP(result),"a",offset);
9641 pic16_aopPut(AOP(result),l,offset);
9643 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
9644 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9650 /* mov the highest order bit to OVR */
9651 tlbl = newiTempLabel(NULL);
9652 tlbl1= newiTempLabel(NULL);
9654 size = AOP_SIZE(result);
9657 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9659 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9661 /* offset should be 0, 1 or 3 */
9662 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
9664 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9666 pic16_emitpcode(POC_MOVWF, pctemp);
9669 pic16_emitpLabel(tlbl->key);
9671 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
9672 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
9675 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
9678 pic16_emitpcode(POC_DECFSZ, pctemp);
9679 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9680 pic16_emitpLabel(tlbl1->key);
9682 pic16_popReleaseTempReg(pctemp,1);
9684 size = AOP_SIZE(result);
9686 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
9687 pic16_emitcode("rlc","a");
9688 pic16_emitcode("mov","ov,c");
9689 /* if it is only one byte then */
9691 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9693 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9694 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9695 pic16_emitcode("mov","c,ov");
9696 pic16_emitcode("rrc","a");
9697 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9698 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9699 pic16_aopPut(AOP(result),"a",0);
9703 reAdjustPreg(AOP(result));
9704 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9705 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9706 pic16_emitcode("mov","c,ov");
9708 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9710 pic16_emitcode("rrc","a");
9711 pic16_aopPut(AOP(result),"a",offset--);
9713 reAdjustPreg(AOP(result));
9714 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9715 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9720 pic16_freeAsmop(left,NULL,ic,TRUE);
9721 pic16_freeAsmop(result,NULL,ic,TRUE);
9722 pic16_freeAsmop(right,NULL,ic,TRUE);
9725 /*-----------------------------------------------------------------*/
9726 /* genRightShift - generate code for right shifting */
9727 /*-----------------------------------------------------------------*/
9728 static void genRightShift (iCode *ic)
9730 operand *right, *left, *result;
9734 symbol *tlbl, *tlbl1 ;
9736 /* if signed then we do it the hard way preserve the
9737 sign bit moving it inwards */
9738 letype = getSpec(operandType(IC_LEFT(ic)));
9739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9741 if (!SPEC_USIGN(letype)) {
9742 genSignedRightShift (ic);
9746 /* signed & unsigned types are treated the same : i.e. the
9747 signed is NOT propagated inwards : quoting from the
9748 ANSI - standard : "for E1 >> E2, is equivalent to division
9749 by 2**E2 if unsigned or if it has a non-negative value,
9750 otherwise the result is implementation defined ", MY definition
9751 is that the sign does not get propagated */
9753 right = IC_RIGHT(ic);
9755 result = IC_RESULT(ic);
9757 pic16_aopOp(right,ic,FALSE);
9759 /* if the shift count is known then do it
9760 as efficiently as possible */
9761 if (AOP_TYPE(right) == AOP_LIT) {
9762 genRightShiftLiteral (left,right,result,ic, 0);
9766 /* shift count is unknown then we have to form
9767 a loop get the loop count in B : Note: we take
9768 only the lower order byte since shifting
9769 more that 32 bits make no sense anyway, ( the
9770 largest size of an object can be only 32 bits ) */
9772 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9773 pic16_emitcode("inc","b");
9774 pic16_aopOp(left,ic,FALSE);
9775 pic16_aopOp(result,ic,FALSE);
9777 /* now move the left to the result if they are not the
9779 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9780 AOP_SIZE(result) > 1) {
9782 size = AOP_SIZE(result);
9785 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9786 if (*l == '@' && IS_AOP_PREG(result)) {
9788 pic16_emitcode("mov","a,%s",l);
9789 pic16_aopPut(AOP(result),"a",offset);
9791 pic16_aopPut(AOP(result),l,offset);
9796 tlbl = newiTempLabel(NULL);
9797 tlbl1= newiTempLabel(NULL);
9798 size = AOP_SIZE(result);
9801 /* if it is only one byte then */
9804 tlbl = newiTempLabel(NULL);
9805 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9806 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9807 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9810 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9811 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9812 pic16_emitpLabel(tlbl->key);
9813 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9814 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9816 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9821 reAdjustPreg(AOP(result));
9822 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9823 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9826 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9828 pic16_emitcode("rrc","a");
9829 pic16_aopPut(AOP(result),"a",offset--);
9831 reAdjustPreg(AOP(result));
9833 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9834 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9837 pic16_freeAsmop(left,NULL,ic,TRUE);
9838 pic16_freeAsmop (right,NULL,ic,TRUE);
9839 pic16_freeAsmop(result,NULL,ic,TRUE);
9843 void pic16_loadFSR0(operand *op)
9845 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9848 /*-----------------------------------------------------------------*/
9849 /* genUnpackBits - generates code for unpacking bits */
9850 /*-----------------------------------------------------------------*/
9851 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
9858 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9859 etype = getSpec(operandType(result));
9861 /* the following call to pic16_loadFSR0 is temporary until
9862 * optimization to handle single bit assignments is added
9863 * to the function. Until then use the old safe way! -- VR */
9864 pic16_loadFSR0( left );
9866 /* read the first byte */
9873 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9876 pic16_emitcode("clr","a");
9877 pic16_emitcode("movc","a","@a+dptr");
9882 /* if we have bitdisplacement then it fits */
9883 /* into this byte completely or if length is */
9884 /* less than a byte */
9885 if ((shCnt = SPEC_BSTR(etype)) ||
9886 (SPEC_BLEN(etype) <= 8)) {
9888 /* shift right acc */
9891 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9892 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
9894 /* VR -- normally I would use the following, but since we use the hack,
9895 * to avoid the masking from AccRsh, why not mask it right now? */
9898 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
9901 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9907 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9908 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9911 /* bit field did not fit in a byte */
9912 rlen = SPEC_BLEN(etype) - 8;
9913 pic16_aopPut(AOP(result),"a",offset++);
9920 pic16_emitcode("inc","%s",rname);
9921 pic16_emitcode("mov","a,@%s",rname);
9925 pic16_emitcode("inc","%s",rname);
9926 pic16_emitcode("movx","a,@%s",rname);
9930 pic16_emitcode("inc","dptr");
9931 pic16_emitcode("movx","a,@dptr");
9935 pic16_emitcode("clr","a");
9936 pic16_emitcode("inc","dptr");
9937 pic16_emitcode("movc","a","@a+dptr");
9941 pic16_emitcode("inc","dptr");
9942 pic16_emitcode("lcall","__gptrget");
9947 /* if we are done */
9951 pic16_aopPut(AOP(result),"a",offset++);
9956 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9957 pic16_aopPut(AOP(result),"a",offset);
9964 static void genDataPointerGet(operand *left,
9968 int size, offset = 0, leoffset=0 ;
9970 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9971 pic16_aopOp(result, ic, FALSE);
9973 size = AOP_SIZE(result);
9974 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9978 /* The following tests may save a redudant movff instruction when
9979 * accessing unions */
9981 /* if they are the same */
9982 if (operandsEqu (left, result)) {
9983 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9989 /* if they are the same registers */
9990 if (pic16_sameRegs(AOP(left),AOP(result))) {
9991 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9997 if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
9998 pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
9999 DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
10006 if ( AOP_TYPE(left) == AOP_PCODE) {
10007 fprintf(stderr,"genDataPointerGet %s, %d\n",
10008 AOP(left)->aopu.pcop->name,
10009 (AOP(left)->aopu.pcop->type == PO_DIR)?
10010 PCOR(AOP(left)->aopu.pcop)->instance:
10011 PCOI(AOP(left)->aopu.pcop)->offset);
10015 if(AOP(left)->aopu.pcop->type == PO_DIR)
10016 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
10018 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10021 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
10023 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
10024 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
10025 mov2w(AOP(left), offset); // patch 8
10026 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
10028 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
10029 pic16_popGet(AOP(left), offset), //patch 8
10030 pic16_popGet(AOP(result), offset)));
10038 pic16_freeAsmop(result,NULL,ic,TRUE);
10043 /*-----------------------------------------------------------------*/
10044 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
10045 /*-----------------------------------------------------------------*/
10046 static void genNearPointerGet (operand *left,
10051 //regs *preg = NULL ;
10052 sym_link *rtype, *retype;
10053 sym_link *ltype = operandType(left);
10055 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10056 rtype = operandType(result);
10057 retype= getSpec(rtype);
10059 pic16_aopOp(left,ic,FALSE);
10061 // pic16_DumpOp("(left)",left);
10062 // pic16_DumpOp("(result)",result);
10064 /* if left is rematerialisable and
10065 * result is not bit variable type and
10066 * the left is pointer to data space i.e
10067 * lower 128 bytes of space */
10068 if (AOP_TYPE(left) == AOP_PCODE
10069 && !IS_BITFIELD(retype)
10070 && DCL_TYPE(ltype) == POINTER) {
10072 genDataPointerGet (left,result,ic);
10073 pic16_freeAsmop(left, NULL, ic, TRUE);
10077 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10079 /* if the value is already in a pointer register
10080 * then don't need anything more */
10081 if (!AOP_INPREG(AOP(left))) {
10082 /* otherwise get a free pointer register */
10083 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10085 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
10086 if( (AOP_TYPE(left) == AOP_PCODE)
10087 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10088 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
10090 if(!IS_BITFIELD(retype))
10091 pic16_loadFSR0( left ); // patch 10
10093 // set up FSR0 with address from left
10094 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10095 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10099 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10101 pic16_aopOp (result,ic,FALSE);
10103 /* if bitfield then unpack the bits */
10104 if (IS_BITFIELD(retype))
10105 genUnpackBits (result, left, NULL, POINTER);
10107 /* we have can just get the values */
10108 int size = AOP_SIZE(result);
10111 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10114 /* fsr0 is loaded already -- VR */
10115 // pic16_loadFSR0( left );
10117 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
10118 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
10122 pic16_emitpcode(POC_MOVFF,
10123 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
10124 pic16_popGet(AOP(result), offset++)));
10126 pic16_emitpcode(POC_MOVFF,
10127 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
10128 pic16_popGet(AOP(result), offset++)));
10132 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
10133 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
10135 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
10139 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
10141 pic16_emitcode("mov","a,@%s",rname);
10142 pic16_aopPut(AOP(result),"a",offset);
10144 sprintf(buffer,"@%s",rname);
10145 pic16_aopPut(AOP(result),buffer,offset);
10149 pic16_emitcode("inc","%s",rname);
10154 /* now some housekeeping stuff */
10156 /* we had to allocate for this iCode */
10157 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10158 pic16_freeAsmop(NULL,aop,ic,TRUE);
10160 /* we did not allocate which means left
10161 already in a pointer register, then
10162 if size > 0 && this could be used again
10163 we have to point it back to where it
10165 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10166 if (AOP_SIZE(result) > 1 &&
10167 !OP_SYMBOL(left)->remat &&
10168 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10170 // int size = AOP_SIZE(result) - 1;
10172 // pic16_emitcode("dec","%s",rname);
10177 pic16_freeAsmop(left,NULL,ic,TRUE);
10178 pic16_freeAsmop(result,NULL,ic,TRUE);
10182 /*-----------------------------------------------------------------*/
10183 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
10184 /*-----------------------------------------------------------------*/
10185 static void genPagedPointerGet (operand *left,
10190 regs *preg = NULL ;
10192 sym_link *rtype, *retype;
10194 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10196 rtype = operandType(result);
10197 retype= getSpec(rtype);
10199 pic16_aopOp(left,ic,FALSE);
10201 /* if the value is already in a pointer register
10202 then don't need anything more */
10203 if (!AOP_INPREG(AOP(left))) {
10204 /* otherwise get a free pointer register */
10206 preg = getFreePtr(ic,&aop,FALSE);
10207 pic16_emitcode("mov","%s,%s",
10209 pic16_aopGet(AOP(left),0,FALSE,TRUE));
10210 rname = preg->name ;
10212 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10214 pic16_freeAsmop(left,NULL,ic,TRUE);
10215 pic16_aopOp (result,ic,FALSE);
10217 /* if bitfield then unpack the bits */
10218 if (IS_BITFIELD(retype))
10219 genUnpackBits (result,left,rname,PPOINTER);
10221 /* we have can just get the values */
10222 int size = AOP_SIZE(result);
10227 pic16_emitcode("movx","a,@%s",rname);
10228 pic16_aopPut(AOP(result),"a",offset);
10233 pic16_emitcode("inc","%s",rname);
10237 /* now some housekeeping stuff */
10239 /* we had to allocate for this iCode */
10240 pic16_freeAsmop(NULL,aop,ic,TRUE);
10242 /* we did not allocate which means left
10243 already in a pointer register, then
10244 if size > 0 && this could be used again
10245 we have to point it back to where it
10247 if (AOP_SIZE(result) > 1 &&
10248 !OP_SYMBOL(left)->remat &&
10249 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10251 int size = AOP_SIZE(result) - 1;
10253 pic16_emitcode("dec","%s",rname);
10258 pic16_freeAsmop(result,NULL,ic,TRUE);
10263 /*-----------------------------------------------------------------*/
10264 /* genFarPointerGet - gget value from far space */
10265 /*-----------------------------------------------------------------*/
10266 static void genFarPointerGet (operand *left,
10267 operand *result, iCode *ic)
10270 sym_link *retype = getSpec(operandType(result));
10272 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10274 pic16_aopOp(left,ic,FALSE);
10276 /* if the operand is already in dptr
10277 then we do nothing else we move the value to dptr */
10278 if (AOP_TYPE(left) != AOP_STR) {
10279 /* if this is remateriazable */
10280 if (AOP_TYPE(left) == AOP_IMMD)
10281 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10282 else { /* we need to get it byte by byte */
10283 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10284 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10285 if (options.model == MODEL_FLAT24)
10287 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10291 /* so dptr know contains the address */
10292 pic16_freeAsmop(left,NULL,ic,TRUE);
10293 pic16_aopOp(result,ic,FALSE);
10295 /* if bit then unpack */
10296 if (IS_BITFIELD(retype))
10297 genUnpackBits(result,left,"dptr",FPOINTER);
10299 size = AOP_SIZE(result);
10303 pic16_emitcode("movx","a,@dptr");
10304 pic16_aopPut(AOP(result),"a",offset++);
10306 pic16_emitcode("inc","dptr");
10310 pic16_freeAsmop(result,NULL,ic,TRUE);
10313 /*-----------------------------------------------------------------*/
10314 /* genCodePointerGet - get value from code space */
10315 /*-----------------------------------------------------------------*/
10316 static void genCodePointerGet (operand *left,
10317 operand *result, iCode *ic)
10320 sym_link *retype = getSpec(operandType(result));
10322 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10324 pic16_aopOp(left,ic,FALSE);
10326 /* if the operand is already in dptr
10327 then we do nothing else we move the value to dptr */
10328 if (AOP_TYPE(left) != AOP_STR) {
10329 /* if this is remateriazable */
10330 if (AOP_TYPE(left) == AOP_IMMD)
10331 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10332 else { /* we need to get it byte by byte */
10333 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10334 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10335 if (options.model == MODEL_FLAT24)
10337 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10341 /* so dptr know contains the address */
10342 pic16_freeAsmop(left,NULL,ic,TRUE);
10343 pic16_aopOp(result,ic,FALSE);
10345 /* if bit then unpack */
10346 if (IS_BITFIELD(retype))
10347 genUnpackBits(result,left,"dptr",CPOINTER);
10349 size = AOP_SIZE(result);
10353 pic16_emitcode("clr","a");
10354 pic16_emitcode("movc","a,@a+dptr");
10355 pic16_aopPut(AOP(result),"a",offset++);
10357 pic16_emitcode("inc","dptr");
10361 pic16_freeAsmop(result,NULL,ic,TRUE);
10365 /*-----------------------------------------------------------------*/
10366 /* genGenPointerGet - gget value from generic pointer space */
10367 /*-----------------------------------------------------------------*/
10368 static void genGenPointerGet (operand *left,
10369 operand *result, iCode *ic)
10371 int size, offset, lit;
10372 sym_link *retype = getSpec(operandType(result));
10374 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10375 pic16_aopOp(left,ic,FALSE);
10376 pic16_aopOp(result,ic,FALSE);
10377 size = AOP_SIZE(result);
10379 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10381 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10383 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10384 // load FSR0 from immediate
10385 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10387 // pic16_loadFSR0( left );
10392 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10394 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10401 else { /* we need to get it byte by byte */
10402 // set up FSR0 with address from left
10403 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10404 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10410 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10412 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10419 /* if bit then unpack */
10420 if (IS_BITFIELD(retype))
10421 genUnpackBits(result,left,"BAD",GPOINTER);
10424 pic16_freeAsmop(left,NULL,ic,TRUE);
10425 pic16_freeAsmop(result,NULL,ic,TRUE);
10430 extern set *externs;
10432 /*-----------------------------------------------------------------*/
10433 /* genGenPointerGet - gget value from generic pointer space */
10434 /*-----------------------------------------------------------------*/
10435 static void genGenPointerGet (operand *left,
10436 operand *result, iCode *ic)
10438 int size, offset, lit;
10439 sym_link *retype = getSpec(operandType(result));
10442 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10443 pic16_aopOp(left,ic,FALSE);
10444 pic16_aopOp(result,ic,FALSE);
10445 size = AOP_SIZE(result);
10447 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10449 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10451 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10452 // load FSR0 from immediate
10453 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10455 werror(W_POSSBUG2, __FILE__, __LINE__);
10460 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10462 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10469 } else { /* we need to get it byte by byte */
10471 /* set up WREG:PRODL:FSR0L with address from left */
10472 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10473 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
10474 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
10477 case 1: strcpy(fgptrget, "__gptrget1"); break;
10478 case 2: strcpy(fgptrget, "__gptrget2"); break;
10479 case 3: strcpy(fgptrget, "__gptrget3"); break;
10480 case 4: strcpy(fgptrget, "__gptrget4"); break;
10482 werror(W_POSSBUG2, __FILE__, __LINE__);
10486 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget ));
10488 assignResultValue(result, 1);
10493 sym = newSymbol( fgptrget, 0 );
10494 strcpy(sym->rname, fgptrget);
10495 checkAddSym(&externs, sym);
10497 // fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
10503 /* if bit then unpack */
10504 if (IS_BITFIELD(retype))
10505 genUnpackBits(result,left,"BAD",GPOINTER);
10508 pic16_freeAsmop(left,NULL,ic,TRUE);
10509 pic16_freeAsmop(result,NULL,ic,TRUE);
10512 /*-----------------------------------------------------------------*/
10513 /* genConstPointerGet - get value from const generic pointer space */
10514 /*-----------------------------------------------------------------*/
10515 static void genConstPointerGet (operand *left,
10516 operand *result, iCode *ic)
10518 //sym_link *retype = getSpec(operandType(result));
10519 // symbol *albl = newiTempLabel(NULL); // patch 15
10520 // symbol *blbl = newiTempLabel(NULL); //
10521 // PIC_OPCODE poc; // patch 15
10525 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10526 pic16_aopOp(left,ic,FALSE);
10527 pic16_aopOp(result,ic,TRUE);
10528 size = AOP_SIZE(result);
10530 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10532 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
10534 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
10535 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
10536 pic16_emitpLabel(albl->key);
10538 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
10540 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
10541 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
10542 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
10543 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
10544 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
10546 pic16_emitpLabel(blbl->key);
10548 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
10552 // set up table pointer
10553 if( (AOP_TYPE(left) == AOP_PCODE)
10554 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10555 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
10557 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
10558 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
10559 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
10560 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
10561 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
10562 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
10566 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
10567 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
10568 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
10574 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
10575 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
10579 pic16_freeAsmop(left,NULL,ic,TRUE);
10580 pic16_freeAsmop(result,NULL,ic,TRUE);
10585 /*-----------------------------------------------------------------*/
10586 /* genPointerGet - generate code for pointer get */
10587 /*-----------------------------------------------------------------*/
10588 static void genPointerGet (iCode *ic)
10590 operand *left, *result ;
10591 sym_link *type, *etype;
10594 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10596 left = IC_LEFT(ic);
10597 result = IC_RESULT(ic) ;
10599 /* depending on the type of pointer we need to
10600 move it to the correct pointer register */
10601 type = operandType(left);
10602 etype = getSpec(type);
10605 if (IS_PTR_CONST(type))
10607 if (IS_CODEPTR(type))
10609 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
10611 /* if left is of type of pointer then it is simple */
10612 if (IS_PTR(type) && !IS_FUNC(type->next))
10613 p_type = DCL_TYPE(type);
10615 /* we have to go by the storage class */
10616 p_type = PTR_TYPE(SPEC_OCLS(etype));
10618 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
10620 if (SPEC_OCLS(etype)->codesp ) {
10621 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
10622 //p_type = CPOINTER ;
10625 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
10626 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
10627 /*p_type = FPOINTER ;*/
10629 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
10630 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
10631 /* p_type = PPOINTER; */
10633 if (SPEC_OCLS(etype) == idata )
10634 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
10635 /* p_type = IPOINTER; */
10637 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
10638 /* p_type = POINTER ; */
10641 /* now that we have the pointer type we assign
10642 the pointer values */
10647 genNearPointerGet (left,result,ic);
10651 genPagedPointerGet(left,result,ic);
10655 genFarPointerGet (left,result,ic);
10659 genConstPointerGet (left,result,ic);
10660 //pic16_emitcodePointerGet (left,result,ic);
10665 if (IS_PTR_CONST(type))
10666 genConstPointerGet (left,result,ic);
10669 genGenPointerGet (left,result,ic);
10673 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10674 "genPointerGet: illegal pointer type");
10680 /*-----------------------------------------------------------------*/
10681 /* genPackBits - generates code for packed bit storage */
10682 /*-----------------------------------------------------------------*/
10683 static void genPackBits (sym_link *etype , operand *result,
10685 char *rname, int p_type)
10693 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10694 blen = SPEC_BLEN(etype);
10695 bstr = SPEC_BSTR(etype);
10697 if(AOP_TYPE(right) == AOP_LIT) {
10698 if((blen == 1) && (bstr < 8)) {
10700 /* it is a single bit, so use the appropriate bit instructions */
10702 DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
10704 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10705 // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10706 if((p_type == POINTER) && (result)) {
10707 /* workaround to reduce the extra lfsr instruction */
10709 pic16_emitpcode(POC_BSF,
10710 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10712 pic16_emitpcode(POC_BCF,
10713 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10718 pic16_emitpcode(POC_BSF,
10719 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10721 pic16_emitpcode(POC_BCF,
10722 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10729 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
10732 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
10734 /* if the bit lenth is less than or */
10735 /* it exactly fits a byte then */
10736 if((shCnt=SPEC_BSTR(etype))
10737 || SPEC_BLEN(etype) <= 8 ) {
10739 /* shift left acc */
10742 /* using PRODL as a temporary register here */
10743 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
10749 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10750 // pic16_emitcode ("mov","b,a");
10751 // pic16_emitcode("mov","a,@%s",rname);
10755 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
10756 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
10757 (unsigned char)(0xff >> (8-bstr))) ));
10758 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
10759 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10766 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
10767 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
10772 if ( SPEC_BLEN(etype) <= 8 )
10775 pic16_emitcode("inc","%s",rname);
10776 rLen = SPEC_BLEN(etype) ;
10780 /* now generate for lengths greater than one byte */
10783 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
10793 pic16_emitcode("mov","@%s,a",rname);
10795 pic16_emitcode("mov","@%s,%s",rname,l);
10800 pic16_emitcode("movx","@dptr,a");
10805 DEBUGpic16_emitcode(";lcall","__gptrput");
10808 pic16_emitcode ("inc","%s",rname);
10813 /* last last was not complete */
10815 /* save the byte & read byte */
10818 pic16_emitcode ("mov","b,a");
10819 pic16_emitcode("mov","a,@%s",rname);
10823 pic16_emitcode ("mov","b,a");
10824 pic16_emitcode("movx","a,@dptr");
10828 pic16_emitcode ("push","b");
10829 pic16_emitcode ("push","acc");
10830 pic16_emitcode ("lcall","__gptrget");
10831 pic16_emitcode ("pop","b");
10835 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
10836 pic16_emitcode ("orl","a,b");
10839 if (p_type == GPOINTER)
10840 pic16_emitcode("pop","b");
10845 pic16_emitcode("mov","@%s,a",rname);
10849 pic16_emitcode("movx","@dptr,a");
10853 DEBUGpic16_emitcode(";lcall","__gptrput");
10857 /*-----------------------------------------------------------------*/
10858 /* genDataPointerSet - remat pointer to data space */
10859 /*-----------------------------------------------------------------*/
10860 static void genDataPointerSet(operand *right,
10864 int size, offset = 0, resoffset=0 ;
10866 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10867 pic16_aopOp(right,ic,FALSE);
10869 size = AOP_SIZE(right);
10871 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
10874 if ( AOP_TYPE(result) == AOP_PCODE) {
10875 fprintf(stderr,"genDataPointerSet %s, %d\n",
10876 AOP(result)->aopu.pcop->name,
10877 (AOP(result)->aopu.pcop->type == PO_DIR)?
10878 PCOR(AOP(result)->aopu.pcop)->instance:
10879 PCOI(AOP(result)->aopu.pcop)->offset);
10883 if(AOP(result)->aopu.pcop->type == PO_DIR)
10884 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
10887 if (AOP_TYPE(right) == AOP_LIT) {
10890 if(!IS_FLOAT(operandType( right )))
10891 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
10894 unsigned long lit_int;
10898 /* take care if literal is a float */
10899 info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
10900 lit = info.lit_int;
10903 lit = lit >> (8*offset);
10905 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
10906 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
10908 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
10911 mov2w(AOP(right), offset);
10912 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
10918 pic16_freeAsmop(right,NULL,ic,TRUE);
10923 /*-----------------------------------------------------------------*/
10924 /* genNearPointerSet - pic16_emitcode for near pointer put */
10925 /*-----------------------------------------------------------------*/
10926 static void genNearPointerSet (operand *right,
10933 sym_link *ptype = operandType(result);
10934 sym_link *resetype;
10936 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10937 retype= getSpec(operandType(right));
10938 resetype = getSpec(operandType(result));
10940 pic16_aopOp(result,ic,FALSE);
10942 /* if the result is rematerializable &
10943 * in data space & not a bit variable */
10945 /* and result is not a bit variable */
10946 if (AOP_TYPE(result) == AOP_PCODE
10947 // && AOP_TYPE(result) == AOP_IMMD
10948 && DCL_TYPE(ptype) == POINTER
10949 && !IS_BITFIELD(retype)
10950 && !IS_BITFIELD(resetype)) {
10952 genDataPointerSet (right,result,ic);
10953 pic16_freeAsmop(result,NULL,ic,TRUE);
10957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10958 pic16_aopOp(right,ic,FALSE);
10959 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10961 /* if the value is already in a pointer register
10962 * then don't need anything more */
10963 if (!AOP_INPREG(AOP(result))) {
10964 /* otherwise get a free pointer register */
10965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10967 if( (AOP_TYPE(result) == AOP_PCODE)
10968 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
10969 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
10971 if(!IS_BITFIELD(resetype))
10972 pic16_loadFSR0( result ); // patch 10
10974 // set up FSR0 with address of result
10975 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10976 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10981 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10983 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10985 /* if bitfield then unpack the bits */
10986 if (IS_BITFIELD(resetype)) {
10987 genPackBits (resetype, result, right, NULL, POINTER);
10989 /* we have can just get the values */
10990 int size = AOP_SIZE(right);
10993 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10995 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10998 //pic16_emitcode("mov","@%s,a",rname);
10999 pic16_emitcode("movf","indf0,w ;1");
11002 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
11003 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
11005 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
11007 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
11009 } else { // no literal //
11011 pic16_emitpcode(POC_MOVFF, //
11012 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
11013 pic16_popCopyReg(&pic16_pc_postinc0))); //
11015 pic16_emitpcode(POC_MOVFF, //
11016 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
11017 pic16_popCopyReg(&pic16_pc_indf0))); //
11025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11026 /* now some housekeeping stuff */
11028 /* we had to allocate for this iCode */
11029 pic16_freeAsmop(NULL,aop,ic,TRUE);
11031 /* we did not allocate which means left
11032 * already in a pointer register, then
11033 * if size > 0 && this could be used again
11034 * we have to point it back to where it
11036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11037 if (AOP_SIZE(right) > 1
11038 && !OP_SYMBOL(result)->remat
11039 && ( OP_SYMBOL(result)->liveTo > ic->seq
11042 int size = AOP_SIZE(right) - 1;
11045 pic16_emitcode("decf","fsr0,f");
11046 //pic16_emitcode("dec","%s",rname);
11050 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11053 pic16_freeAsmop(right,NULL,ic,TRUE);
11054 pic16_freeAsmop(result,NULL,ic,TRUE);
11057 /*-----------------------------------------------------------------*/
11058 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
11059 /*-----------------------------------------------------------------*/
11060 static void genPagedPointerSet (operand *right,
11065 regs *preg = NULL ;
11069 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11071 retype= getSpec(operandType(right));
11073 pic16_aopOp(result,ic,FALSE);
11075 /* if the value is already in a pointer register
11076 then don't need anything more */
11077 if (!AOP_INPREG(AOP(result))) {
11078 /* otherwise get a free pointer register */
11080 preg = getFreePtr(ic,&aop,FALSE);
11081 pic16_emitcode("mov","%s,%s",
11083 pic16_aopGet(AOP(result),0,FALSE,TRUE));
11084 rname = preg->name ;
11086 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11088 pic16_freeAsmop(result,NULL,ic,TRUE);
11089 pic16_aopOp (right,ic,FALSE);
11091 /* if bitfield then unpack the bits */
11092 if (IS_BITFIELD(retype))
11093 genPackBits (retype,result,right,rname,PPOINTER);
11095 /* we have can just get the values */
11096 int size = AOP_SIZE(right);
11100 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
11103 pic16_emitcode("movx","@%s,a",rname);
11106 pic16_emitcode("inc","%s",rname);
11112 /* now some housekeeping stuff */
11114 /* we had to allocate for this iCode */
11115 pic16_freeAsmop(NULL,aop,ic,TRUE);
11117 /* we did not allocate which means left
11118 already in a pointer register, then
11119 if size > 0 && this could be used again
11120 we have to point it back to where it
11122 if (AOP_SIZE(right) > 1 &&
11123 !OP_SYMBOL(result)->remat &&
11124 ( OP_SYMBOL(result)->liveTo > ic->seq ||
11126 int size = AOP_SIZE(right) - 1;
11128 pic16_emitcode("dec","%s",rname);
11133 pic16_freeAsmop(right,NULL,ic,TRUE);
11138 /*-----------------------------------------------------------------*/
11139 /* genFarPointerSet - set value from far space */
11140 /*-----------------------------------------------------------------*/
11141 static void genFarPointerSet (operand *right,
11142 operand *result, iCode *ic)
11145 sym_link *retype = getSpec(operandType(right));
11147 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11148 pic16_aopOp(result,ic,FALSE);
11150 /* if the operand is already in dptr
11151 then we do nothing else we move the value to dptr */
11152 if (AOP_TYPE(result) != AOP_STR) {
11153 /* if this is remateriazable */
11154 if (AOP_TYPE(result) == AOP_IMMD)
11155 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
11156 else { /* we need to get it byte by byte */
11157 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
11158 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
11159 if (options.model == MODEL_FLAT24)
11161 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
11165 /* so dptr know contains the address */
11166 pic16_freeAsmop(result,NULL,ic,TRUE);
11167 pic16_aopOp(right,ic,FALSE);
11169 /* if bit then unpack */
11170 if (IS_BITFIELD(retype))
11171 genPackBits(retype,result,right,"dptr",FPOINTER);
11173 size = AOP_SIZE(right);
11177 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11179 pic16_emitcode("movx","@dptr,a");
11181 pic16_emitcode("inc","dptr");
11185 pic16_freeAsmop(right,NULL,ic,TRUE);
11188 /*-----------------------------------------------------------------*/
11189 /* genGenPointerSet - set value from generic pointer space */
11190 /*-----------------------------------------------------------------*/
11192 static void genGenPointerSet (operand *right,
11193 operand *result, iCode *ic)
11195 int i, size, offset, lit;
11196 sym_link *retype = getSpec(operandType(right));
11198 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11200 pic16_aopOp(result,ic,FALSE);
11201 pic16_aopOp(right,ic,FALSE);
11202 size = AOP_SIZE(right);
11205 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11207 /* if the operand is already in dptr
11208 then we do nothing else we move the value to dptr */
11209 if (AOP_TYPE(result) != AOP_STR) {
11210 /* if this is remateriazable */
11211 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11212 // WARNING: anythig until "else" is untested!
11213 if (AOP_TYPE(result) == AOP_IMMD) {
11214 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11215 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
11216 // load FSR0 from immediate
11217 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11221 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11223 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11229 else { /* we need to get it byte by byte */
11230 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11231 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11233 // set up FSR0 with address of result
11234 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11235 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11237 /* hack hack! see if this the FSR. If so don't load W */
11238 if(AOP_TYPE(right) != AOP_ACC) {
11240 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11242 if(AOP_TYPE(right) == AOP_LIT)
11245 // note: pic16_popGet handles sign extension
11246 for(i=0;i<size;i++) {
11247 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
11249 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
11251 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
11256 for(i=0;i<size;i++) {
11258 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11259 pic16_popCopyReg(&pic16_pc_postinc0)));
11261 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11262 pic16_popCopyReg(&pic16_pc_indf0)));
11268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11269 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11271 } // if (AOP_TYPE(result) != AOP_IMMD)
11273 } // if (AOP_TYPE(result) != AOP_STR)
11274 /* so dptr know contains the address */
11277 /* if bit then unpack */
11278 if (IS_BITFIELD(retype))
11279 genPackBits(retype,result,right,"dptr",GPOINTER);
11281 size = AOP_SIZE(right);
11284 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11286 // set up FSR0 with address of result
11287 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11288 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11291 if (AOP_TYPE(right) == AOP_LIT) {
11292 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11294 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
11296 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11298 } else { // no literal
11300 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11302 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11310 pic16_freeAsmop(right,NULL,ic,TRUE);
11311 pic16_freeAsmop(result,NULL,ic,TRUE);
11315 static void genGenPointerSet (operand *right,
11316 operand *result, iCode *ic)
11319 sym_link *retype = getSpec(operandType(right));
11322 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11324 pic16_aopOp(result,ic,FALSE);
11325 pic16_aopOp(right,ic,FALSE);
11326 size = AOP_SIZE(right);
11328 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11331 /* if bit then unpack */
11332 if (IS_BITFIELD(retype)) {
11333 // pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11334 genPackBits(retype,result,right,"dptr",GPOINTER);
11338 size = AOP_SIZE(right);
11340 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11344 /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
11346 /* value of right+0 is placed on stack, which will be retrieved
11347 * by the support function this restoring the stack. The important
11348 * thing is that there is no need to manually restore stack pointer
11350 mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
11351 if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
11352 if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
11353 if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
11355 /* load address to write to in WREG:FSR0H:FSR0L */
11356 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
11357 pic16_popCopyReg(&pic16_pc_fsr0l)));
11358 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
11359 pic16_popCopyReg(&pic16_pc_prodl)));
11360 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
11363 /* put code here */
11365 case 1: strcpy(fgptrput, "__gptrput1"); break;
11366 case 2: strcpy(fgptrput, "__gptrput2"); break;
11367 case 3: strcpy(fgptrput, "__gptrput3"); break;
11368 case 4: strcpy(fgptrput, "__gptrput4"); break;
11370 werror(W_POSSBUG2, __FILE__, __LINE__);
11374 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput ));
11379 sym = newSymbol( fgptrput, 0 );
11380 strcpy(sym->rname, fgptrput);
11381 checkAddSym(&externs, sym);
11385 pic16_freeAsmop(right,NULL,ic,TRUE);
11386 pic16_freeAsmop(result,NULL,ic,TRUE);
11389 /*-----------------------------------------------------------------*/
11390 /* genPointerSet - stores the value into a pointer location */
11391 /*-----------------------------------------------------------------*/
11392 static void genPointerSet (iCode *ic)
11394 operand *right, *result ;
11395 sym_link *type, *etype;
11398 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11400 right = IC_RIGHT(ic);
11401 result = IC_RESULT(ic) ;
11403 /* depending on the type of pointer we need to
11404 move it to the correct pointer register */
11405 type = operandType(result);
11406 etype = getSpec(type);
11407 /* if left is of type of pointer then it is simple */
11408 if (IS_PTR(type) && !IS_FUNC(type->next)) {
11409 p_type = DCL_TYPE(type);
11412 /* we have to go by the storage class */
11413 p_type = PTR_TYPE(SPEC_OCLS(etype));
11415 /* if (SPEC_OCLS(etype)->codesp ) { */
11416 /* p_type = CPOINTER ; */
11419 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
11420 /* p_type = FPOINTER ; */
11422 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
11423 /* p_type = PPOINTER ; */
11425 /* if (SPEC_OCLS(etype) == idata ) */
11426 /* p_type = IPOINTER ; */
11428 /* p_type = POINTER ; */
11431 /* now that we have the pointer type we assign
11432 the pointer values */
11437 genNearPointerSet (right,result,ic);
11441 genPagedPointerSet (right,result,ic);
11445 genFarPointerSet (right,result,ic);
11449 genGenPointerSet (right,result,ic);
11453 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
11454 "genPointerSet: illegal pointer type");
11458 /*-----------------------------------------------------------------*/
11459 /* genIfx - generate code for Ifx statement */
11460 /*-----------------------------------------------------------------*/
11461 static void genIfx (iCode *ic, iCode *popIc)
11463 operand *cond = IC_COND(ic);
11466 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11468 pic16_aopOp(cond,ic,FALSE);
11470 /* get the value into acc */
11471 if (AOP_TYPE(cond) != AOP_CRY)
11472 pic16_toBoolean(cond);
11475 /* the result is now in the accumulator */
11476 pic16_freeAsmop(cond,NULL,ic,TRUE);
11478 /* if there was something to be popped then do it */
11482 /* if the condition is a bit variable */
11483 if (isbit && IS_ITEMP(cond) &&
11485 genIfxJump(ic,SPIL_LOC(cond)->rname);
11486 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
11489 if (isbit && !IS_ITEMP(cond))
11490 genIfxJump(ic,OP_SYMBOL(cond)->rname);
11492 genIfxJump(ic,"a");
11498 /*-----------------------------------------------------------------*/
11499 /* genAddrOf - generates code for address of */
11500 /*-----------------------------------------------------------------*/
11501 static void genAddrOf (iCode *ic)
11503 operand *result, *left;
11505 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
11506 pCodeOp *pcop0, *pcop1, *pcop2;
11508 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11510 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
11512 sym = OP_SYMBOL( IC_LEFT(ic) );
11515 /* get address of symbol on stack */
11516 DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
11518 fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__,
11519 OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack);
11522 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
11523 pic16_popCopyReg(&pic16_pc_fsr2l),
11524 pic16_popGet(AOP(result), 0)));
11525 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
11526 pic16_popCopyReg(&pic16_pc_fsr2h),
11527 pic16_popGet(AOP(result), 1)));
11529 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( OP_SYMBOL( IC_LEFT(ic))->stack ) /*+ _G.stack_lat*/);
11530 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 0));
11532 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 1));
11537 // if(pic16_debug_verbose) {
11538 // fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
11539 // __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
11542 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
11543 size = AOP_SIZE(IC_RESULT(ic));
11546 /* Assume that what we want the address of is in data space
11547 * since there is no stack on the PIC, yet! -- VR */
11549 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11550 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11551 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11554 pic16_emitpcode(POC_MOVLW, pcop0);
11555 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
11556 pic16_emitpcode(POC_MOVLW, pcop1);
11557 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
11558 pic16_emitpcode(POC_MOVLW, pcop2);
11559 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
11562 pic16_emitpcode(POC_MOVLW, pcop0);
11563 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11564 pic16_emitpcode(POC_MOVLW, pcop1);
11565 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
11567 pic16_emitpcode(POC_MOVLW, pcop0);
11568 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11571 pic16_freeAsmop(left, NULL, ic, FALSE);
11573 pic16_freeAsmop(result,NULL,ic,TRUE);
11578 /*-----------------------------------------------------------------*/
11579 /* genFarFarAssign - assignment when both are in far space */
11580 /*-----------------------------------------------------------------*/
11581 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
11583 int size = AOP_SIZE(right);
11586 /* first push the right side on to the stack */
11588 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11590 pic16_emitcode ("push","acc");
11593 pic16_freeAsmop(right,NULL,ic,FALSE);
11594 /* now assign DPTR to result */
11595 pic16_aopOp(result,ic,FALSE);
11596 size = AOP_SIZE(result);
11598 pic16_emitcode ("pop","acc");
11599 pic16_aopPut(AOP(result),"a",--offset);
11601 pic16_freeAsmop(result,NULL,ic,FALSE);
11606 /*-----------------------------------------------------------------*/
11607 /* genAssign - generate code for assignment */
11608 /*-----------------------------------------------------------------*/
11609 static void genAssign (iCode *ic)
11611 operand *result, *right;
11612 int size, offset,know_W;
11613 unsigned long lit = 0L;
11615 result = IC_RESULT(ic);
11616 right = IC_RIGHT(ic) ;
11618 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11620 /* if they are the same */
11621 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
11624 /* reversed order operands are aopOp'ed so that result operand
11625 * is effective in case right is a stack symbol. This maneauver
11626 * allows to use the _G.resDirect flag later */
11627 pic16_aopOp(result,ic,TRUE);
11628 pic16_aopOp(right,ic,FALSE);
11630 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11632 /* if they are the same registers */
11633 if (pic16_sameRegs(AOP(right),AOP(result)))
11636 /* if the result is a bit */
11637 if (AOP_TYPE(result) == AOP_CRY) {
11638 /* if the right size is a literal then
11639 we know what the value is */
11640 if (AOP_TYPE(right) == AOP_LIT) {
11642 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
11643 pic16_popGet(AOP(result),0));
11645 if (((int) operandLitValue(right)))
11646 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11647 AOP(result)->aopu.aop_dir,
11648 AOP(result)->aopu.aop_dir);
11650 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11651 AOP(result)->aopu.aop_dir,
11652 AOP(result)->aopu.aop_dir);
11656 /* the right is also a bit variable */
11657 if (AOP_TYPE(right) == AOP_CRY) {
11658 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11659 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11660 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11662 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11663 AOP(result)->aopu.aop_dir,
11664 AOP(result)->aopu.aop_dir);
11665 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
11666 AOP(right)->aopu.aop_dir,
11667 AOP(right)->aopu.aop_dir);
11668 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11669 AOP(result)->aopu.aop_dir,
11670 AOP(result)->aopu.aop_dir);
11674 /* we need to or */
11675 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11676 pic16_toBoolean(right);
11678 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11679 //pic16_aopPut(AOP(result),"a",0);
11683 /* bit variables done */
11685 size = AOP_SIZE(result);
11688 if(AOP_TYPE(right) == AOP_LIT) {
11689 if(!IS_FLOAT(operandType( right )))
11690 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
11693 unsigned long lit_int;
11697 /* take care if literal is a float */
11698 info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
11699 lit = info.lit_int;
11703 // fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
11704 // sizeof(unsigned long int), sizeof(float));
11706 if(AOP_TYPE(right) != AOP_LIT
11707 && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
11708 && !IS_FUNC(OP_SYM_TYPE(right))
11710 DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
11711 // fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
11713 // set up table pointer
11714 if( (AOP_TYPE(right) == AOP_PCODE)
11715 && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
11716 // || (AOP(right)->aopu.pcop->type == PO_DIR)
11720 // fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
11721 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
11722 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
11723 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
11724 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
11725 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
11726 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
11728 // fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
11729 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
11730 pic16_popCopyReg(&pic16_pc_tblptrl)));
11731 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
11732 pic16_popCopyReg(&pic16_pc_tblptrh)));
11733 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
11734 pic16_popCopyReg(&pic16_pc_tblptru)));
11737 size = min(AOP_SIZE(right), AOP_SIZE(result));
11739 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
11740 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
11741 pic16_popGet(AOP(result),offset)));
11745 if(AOP_SIZE(result) > AOP_SIZE(right)) {
11746 size = AOP_SIZE(result) - AOP_SIZE(right);
11748 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
11758 /* VR - What is this?! */
11759 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
11760 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11761 if(aopIdx(AOP(result),0) == 4) {
11763 /* this is a workaround to save value of right into wreg too,
11764 * value of wreg is going to be used later */
11765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11766 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11767 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11771 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
11777 DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
11778 if(AOP_TYPE(right) == AOP_LIT) {
11780 if(know_W != (lit&0xff))
11781 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
11783 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11785 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11789 } else if (AOP_TYPE(right) == AOP_CRY) {
11790 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11792 debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
11793 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
11794 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
11796 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
11797 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11798 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11800 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11802 if(!_G.resDirect) /* use this aopForSym feature */
11803 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
11810 pic16_freeAsmop (right,NULL,ic,FALSE);
11811 pic16_freeAsmop (result,NULL,ic,TRUE);
11814 /*-----------------------------------------------------------------*/
11815 /* genJumpTab - generates code for jump table */
11816 /*-----------------------------------------------------------------*/
11817 static void genJumpTab (iCode *ic)
11822 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11824 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
11825 /* get the condition into accumulator */
11826 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
11828 /* multiply by three */
11829 pic16_emitcode("add","a,acc");
11830 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
11832 jtab = newiTempLabel(NULL);
11833 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
11834 pic16_emitcode("jmp","@a+dptr");
11835 pic16_emitcode("","%05d_DS_:",jtab->key+100);
11837 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
11838 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
11840 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
11841 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
11842 pic16_emitpLabel(jtab->key);
11844 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
11846 /* now generate the jump labels */
11847 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
11848 jtab = setNextItem(IC_JTLABELS(ic))) {
11849 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
11850 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
11856 /*-----------------------------------------------------------------*/
11857 /* genMixedOperation - gen code for operators between mixed types */
11858 /*-----------------------------------------------------------------*/
11860 TSD - Written for the PIC port - but this unfortunately is buggy.
11861 This routine is good in that it is able to efficiently promote
11862 types to different (larger) sizes. Unfortunately, the temporary
11863 variables that are optimized out by this routine are sometimes
11864 used in other places. So until I know how to really parse the
11865 iCode tree, I'm going to not be using this routine :(.
11867 static int genMixedOperation (iCode *ic)
11870 operand *result = IC_RESULT(ic);
11871 sym_link *ctype = operandType(IC_LEFT(ic));
11872 operand *right = IC_RIGHT(ic);
11878 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
11880 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11886 nextright = IC_RIGHT(nextic);
11887 nextleft = IC_LEFT(nextic);
11888 nextresult = IC_RESULT(nextic);
11890 pic16_aopOp(right,ic,FALSE);
11891 pic16_aopOp(result,ic,FALSE);
11892 pic16_aopOp(nextright, nextic, FALSE);
11893 pic16_aopOp(nextleft, nextic, FALSE);
11894 pic16_aopOp(nextresult, nextic, FALSE);
11896 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
11898 operand *t = right;
11902 pic16_emitcode(";remove right +","");
11904 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
11906 operand *t = right;
11910 pic16_emitcode(";remove left +","");
11914 big = AOP_SIZE(nextleft);
11915 small = AOP_SIZE(nextright);
11917 switch(nextic->op) {
11920 pic16_emitcode(";optimize a +","");
11921 /* if unsigned or not an integral type */
11922 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
11923 pic16_emitcode(";add a bit to something","");
11926 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
11928 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
11929 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
11930 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
11932 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
11940 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11941 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11942 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11945 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11947 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
11948 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
11949 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
11950 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11951 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
11954 pic16_emitcode("rlf","known_zero,w");
11961 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11962 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11963 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11965 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11975 pic16_freeAsmop(right,NULL,ic,TRUE);
11976 pic16_freeAsmop(result,NULL,ic,TRUE);
11977 pic16_freeAsmop(nextright,NULL,ic,TRUE);
11978 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
11980 nextic->generated = 1;
11987 /*-----------------------------------------------------------------*/
11988 /* genCast - gen code for casting */
11989 /*-----------------------------------------------------------------*/
11990 static void genCast (iCode *ic)
11992 operand *result = IC_RESULT(ic);
11993 sym_link *ctype = operandType(IC_LEFT(ic));
11994 sym_link *rtype = operandType(IC_RIGHT(ic));
11995 operand *right = IC_RIGHT(ic);
11998 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11999 /* if they are equivalent then do nothing */
12000 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
12003 pic16_aopOp(right,ic,FALSE) ;
12004 pic16_aopOp(result,ic,FALSE);
12006 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
12008 /* if the result is a bit */
12009 if (AOP_TYPE(result) == AOP_CRY) {
12011 /* if the right size is a literal then
12012 * we know what the value is */
12013 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12015 if (AOP_TYPE(right) == AOP_LIT) {
12016 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
12017 pic16_popGet(AOP(result),0));
12019 if (((int) operandLitValue(right)))
12020 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
12021 AOP(result)->aopu.aop_dir,
12022 AOP(result)->aopu.aop_dir);
12024 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
12025 AOP(result)->aopu.aop_dir,
12026 AOP(result)->aopu.aop_dir);
12030 /* the right is also a bit variable */
12031 if (AOP_TYPE(right) == AOP_CRY) {
12033 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12035 pic16_emitcode("clrc","");
12036 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
12037 AOP(right)->aopu.aop_dir,
12038 AOP(right)->aopu.aop_dir);
12039 pic16_aopPut(AOP(result),"c",0);
12043 /* we need to or */
12044 if (AOP_TYPE(right) == AOP_REG) {
12045 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
12046 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
12047 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
12049 pic16_toBoolean(right);
12050 pic16_aopPut(AOP(result),"a",0);
12054 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
12057 size = AOP_SIZE(result);
12059 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12061 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
12062 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12063 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
12066 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12071 /* if they are the same size : or less */
12072 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
12074 /* if they are in the same place */
12075 if (pic16_sameRegs(AOP(right),AOP(result)))
12078 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12080 if (IS_PTR_CONST(rtype))
12082 if (IS_CODEPTR(rtype))
12084 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
12087 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
12089 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
12091 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
12094 if(AOP_TYPE(right) == AOP_IMMD) {
12095 pCodeOp *pcop0, *pcop1, *pcop2;
12096 symbol *sym = OP_SYMBOL( right );
12098 size = AOP_SIZE(result);
12100 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12102 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12104 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12107 pic16_emitpcode(POC_MOVLW, pcop0);
12108 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
12109 pic16_emitpcode(POC_MOVLW, pcop1);
12110 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
12111 pic16_emitpcode(POC_MOVLW, pcop2);
12112 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
12115 pic16_emitpcode(POC_MOVLW, pcop0);
12116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12117 pic16_emitpcode(POC_MOVLW, pcop1);
12118 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12120 pic16_emitpcode(POC_MOVLW, pcop0);
12121 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12125 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12126 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
12127 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12128 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
12129 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12130 if(AOP_SIZE(result) <2)
12131 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
12133 /* if they in different places then copy */
12134 size = AOP_SIZE(result);
12137 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
12138 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12145 /* if the result is of type pointer */
12146 if (IS_PTR(ctype)) {
12148 sym_link *type = operandType(right);
12149 sym_link *etype = getSpec(type);
12151 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
12153 /* pointer to generic pointer */
12154 if (IS_GENPTR(ctype)) {
12158 p_type = DCL_TYPE(type);
12160 /* we have to go by the storage class */
12161 p_type = PTR_TYPE(SPEC_OCLS(etype));
12163 /* if (SPEC_OCLS(etype)->codesp ) */
12164 /* p_type = CPOINTER ; */
12166 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
12167 /* p_type = FPOINTER ; */
12169 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
12170 /* p_type = PPOINTER; */
12172 /* if (SPEC_OCLS(etype) == idata ) */
12173 /* p_type = IPOINTER ; */
12175 /* p_type = POINTER ; */
12178 /* the first two bytes are known */
12179 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
12180 size = GPTRSIZE - 1;
12183 if(offset < AOP_SIZE(right)) {
12184 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
12185 mov2f(AOP(result), AOP(right), offset);
12187 if ((AOP_TYPE(right) == AOP_PCODE) &&
12188 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12189 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
12190 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12193 pic16_aopPut(AOP(result),
12194 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12199 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
12202 /* the last byte depending on type */
12206 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
12207 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
12208 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
12212 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12216 pic16_emitcode(";BUG!? ","%d",__LINE__);
12220 pic16_emitcode(";BUG!? ","%d",__LINE__);
12225 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12229 /* this should never happen */
12230 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12231 "got unknown pointer type");
12234 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
12238 /* just copy the pointers */
12239 size = AOP_SIZE(result);
12242 pic16_aopPut(AOP(result),
12243 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12252 /* so we now know that the size of destination is greater
12253 than the size of the source.
12254 Now, if the next iCode is an operator then we might be
12255 able to optimize the operation without performing a cast.
12257 if(genMixedOperation(ic))
12260 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12262 /* we move to result for the size of source */
12263 size = AOP_SIZE(right);
12266 mov2f(AOP(result), AOP(right), offset);
12270 /* now depending on the sign of the destination */
12271 size = AOP_SIZE(result) - AOP_SIZE(right);
12272 /* if unsigned or not an integral type */
12273 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
12275 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12277 /* we need to extend the sign :( */
12280 /* Save one instruction of casting char to int */
12281 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
12282 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12283 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
12285 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
12288 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12290 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12292 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
12295 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
12300 pic16_freeAsmop(right,NULL,ic,TRUE);
12301 pic16_freeAsmop(result,NULL,ic,TRUE);
12305 /*-----------------------------------------------------------------*/
12306 /* genDjnz - generate decrement & jump if not zero instrucion */
12307 /*-----------------------------------------------------------------*/
12308 static int genDjnz (iCode *ic, iCode *ifx)
12310 symbol *lbl, *lbl1;
12311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12316 /* if the if condition has a false label
12317 then we cannot save */
12321 /* if the minus is not of the form
12323 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
12324 !IS_OP_LITERAL(IC_RIGHT(ic)))
12327 if (operandLitValue(IC_RIGHT(ic)) != 1)
12330 /* if the size of this greater than one then no
12332 if (getSize(operandType(IC_RESULT(ic))) > 1)
12335 /* otherwise we can save BIG */
12336 lbl = newiTempLabel(NULL);
12337 lbl1= newiTempLabel(NULL);
12339 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12341 if (IS_AOP_PREG(IC_RESULT(ic))) {
12342 pic16_emitcode("dec","%s",
12343 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12344 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12345 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
12349 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
12350 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
12352 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12353 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
12357 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12358 ifx->generated = 1;
12362 /*-----------------------------------------------------------------*/
12363 /* genReceive - generate code for a receive iCode */
12364 /*-----------------------------------------------------------------*/
12365 static void genReceive (iCode *ic)
12367 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12370 fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__,
12371 OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack);
12373 // pic16_DumpOp(__FUNCTION__, IC_RESULT(ic));
12375 if (isOperandInFarSpace(IC_RESULT(ic))
12376 && ( OP_SYMBOL(IC_RESULT(ic))->isspilt
12377 || IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
12379 int size = getSize(operandType(IC_RESULT(ic)));
12380 int offset = pic16_fReturnSizePic - size;
12384 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
12385 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
12389 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
12391 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12392 size = AOP_SIZE(IC_RESULT(ic));
12395 pic16_emitcode ("pop","acc");
12396 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
12399 DEBUGpic16_emitcode ("; ***","2 %s %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
12402 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12404 assignResultValue(IC_RESULT(ic), 0);
12407 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12410 /*-----------------------------------------------------------------*/
12411 /* genDummyRead - generate code for dummy read of volatiles */
12412 /*-----------------------------------------------------------------*/
12414 genDummyRead (iCode * ic)
12416 pic16_emitcode ("; genDummyRead","");
12417 pic16_emitcode ("; not implemented","");
12422 /*-----------------------------------------------------------------*/
12423 /* genpic16Code - generate code for pic16 based controllers */
12424 /*-----------------------------------------------------------------*/
12426 * At this point, ralloc.c has gone through the iCode and attempted
12427 * to optimize in a way suitable for a PIC. Now we've got to generate
12428 * PIC instructions that correspond to the iCode.
12430 * Once the instructions are generated, we'll pass through both the
12431 * peep hole optimizer and the pCode optimizer.
12432 *-----------------------------------------------------------------*/
12434 void genpic16Code (iCode *lic)
12439 lineHead = lineCurr = NULL;
12441 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
12442 pic16_addpBlock(pb);
12445 /* if debug information required */
12446 if (options.debug && currFunc) {
12448 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
12453 for (ic = lic ; ic ; ic = ic->next ) {
12455 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
12456 if ( cln != ic->lineno ) {
12457 if ( options.debug ) {
12458 debugFile->writeCLine (ic);
12461 if(!options.noCcodeInAsm) {
12462 pic16_addpCode2pBlock(pb,
12463 pic16_newpCodeCSource(ic->lineno, ic->filename,
12464 printCLine(ic->filename, ic->lineno)));
12470 if(options.iCodeInAsm) {
12472 /* insert here code to print iCode as comment */
12473 l = Safe_strdup(printILine(ic));
12474 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
12477 /* if the result is marked as
12478 spilt and rematerializable or code for
12479 this has already been generated then
12481 if (resultRemat(ic) || ic->generated )
12484 /* depending on the operation */
12503 /* IPOP happens only when trying to restore a
12504 spilt live range, if there is an ifx statement
12505 following this pop then the if statement might
12506 be using some of the registers being popped which
12507 would destroy the contents of the register so
12508 we need to check for this condition and handle it */
12510 ic->next->op == IFX &&
12511 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
12512 genIfx (ic->next,ic);
12530 genEndFunction (ic);
12546 pic16_genPlus (ic) ;
12550 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
12551 pic16_genMinus (ic);
12567 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
12571 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
12578 /* note these two are xlated by algebraic equivalence
12579 during parsing SDCC.y */
12580 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12581 "got '>=' or '<=' shouldn't have come here");
12585 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
12597 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
12601 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
12605 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
12629 genRightShift (ic);
12632 case GET_VALUE_AT_ADDRESS:
12637 if (POINTER_SET(ic))
12664 addSet(&_G.sendSet,ic);
12665 /* create a reversed list of SEND iCodes */
12666 // addSetHead(&_G.sendSet, ic);
12669 case DUMMY_READ_VOLATILE:
12679 /* now we are ready to call the
12680 peep hole optimizer */
12681 if (!options.nopeep) {
12682 peepHole (&lineHead);
12684 /* now do the actual printing */
12685 printLine (lineHead, codeOutFile);
12688 DFPRINTF((stderr,"printing pBlock\n\n"));
12689 pic16_printpBlock(stdout,pb);