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 /* this is the down and dirty file with all kinds of
98 kludgy & hacky stuff. This is what it is all about
99 CODE GENERATION for a specific MCU . some of the
100 routines may be reusable, will have to see */
102 static char *zero = "#0x00";
103 static char *one = "#0x01";
104 //static char *spname = "sp";
108 * Function return value policy (MSB-->LSB):
110 * 16 bits -> PRODL:WREG
111 * 24 bits -> PRODH:PRODL:WREG
112 * 32 bits -> FSR0L:PRODH:PRODL:WREG
113 * >32 bits -> on stack, and FSR0 points to the beginning
118 char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
119 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
120 static char **fReturn = fReturnpic16;
122 static char *accUse[] = {"WREG"};
124 //static short rbank = -1;
140 int stack_lat; /* stack offset latency */
142 int useWreg; /* flag when WREG is used to pass function parameter */
145 /* Resolved ifx structure. This structure stores information
146 about an iCode ifx that makes it easier to generate code.
148 typedef struct resolvedIfx {
149 symbol *lbl; /* pointer to a label */
150 int condition; /* true or false ifx */
151 int generated; /* set true when the code associated with the ifx
155 extern int pic16_ptrRegReq ;
156 extern int pic16_nRegs;
157 extern FILE *codeOutFile;
158 //static void saverbank (int, iCode *,bool);
160 static lineNode *lineHead = NULL;
161 static lineNode *lineCurr = NULL;
163 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
164 0xE0, 0xC0, 0x80, 0x00};
165 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
166 0x07, 0x03, 0x01, 0x00};
170 /*-----------------------------------------------------------------*/
171 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
172 /* exponent of 2 is returned, otherwise -1 is */
174 /* note that this is similar to the function `powof2' in SDCCsymt */
178 /*-----------------------------------------------------------------*/
179 static int my_powof2 (unsigned long num)
182 if( (num & (num-1)) == 0) {
195 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
197 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
199 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
200 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
201 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
202 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
203 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
204 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
205 ((result) ? AOP_SIZE(result) : 0));
208 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
211 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
213 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
214 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
215 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
216 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
217 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
218 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
222 void pic16_emitpcomment (char *fmt, ...)
225 char lb[INITIAL_INLINEASM];
231 vsprintf(lb+1,fmt,ap);
233 while (isspace(*lbp)) lbp++;
236 lineCurr = (lineCurr ?
237 connectLine(lineCurr,newLineNode(lb)) :
238 (lineHead = newLineNode(lb)));
239 lineCurr->isInline = _G.inLine;
240 lineCurr->isDebug = _G.debugLine;
242 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
245 // fprintf(stderr, "%s\n", lb);
248 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
251 char lb[INITIAL_INLINEASM];
254 if(!pic16_debug_verbose)
261 sprintf(lb,"%s\t",inst);
263 sprintf(lb,"%s",inst);
264 vsprintf(lb+(strlen(lb)),fmt,ap);
268 while (isspace(*lbp)) lbp++;
271 lineCurr = (lineCurr ?
272 connectLine(lineCurr,newLineNode(lb)) :
273 (lineHead = newLineNode(lb)));
274 lineCurr->isInline = _G.inLine;
275 lineCurr->isDebug = _G.debugLine;
277 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
280 // fprintf(stderr, "%s\n", lb);
283 void pic16_emitpLabel(int key)
285 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset));
288 void pic16_emitpLabelFORCE(int key)
290 pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
293 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
297 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
299 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
302 void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop)
305 pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop));
307 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
310 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
313 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
319 #define pic16_emitcode DEBUGpic16_emitcode
321 /*-----------------------------------------------------------------*/
322 /* pic16_emitcode - writes the code into a file : for now it is simple */
323 /*-----------------------------------------------------------------*/
324 void pic16_emitcode (char *inst,char *fmt, ...)
327 char lb[INITIAL_INLINEASM];
334 sprintf(lb,"%s\t",inst);
336 sprintf(lb,"%s",inst);
337 vsprintf(lb+(strlen(lb)),fmt,ap);
341 while (isspace(*lbp)) lbp++;
344 lineCurr = (lineCurr ?
345 connectLine(lineCurr,newLineNode(lb)) :
346 (lineHead = newLineNode(lb)));
347 lineCurr->isInline = _G.inLine;
348 lineCurr->isDebug = _G.debugLine;
350 // VR fprintf(stderr, "lb = <%s>\n", lbp);
352 // if(pic16_debug_verbose)
353 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
360 /*-----------------------------------------------------------------*/
361 /* pic16_emitDebuggerSymbol - associate the current code location */
362 /* with a debugger symbol */
363 /*-----------------------------------------------------------------*/
365 pic16_emitDebuggerSymbol (char * debugSym)
368 pic16_emitcode (";", "%s ==.", debugSym);
373 /*-----------------------------------------------------------------*/
374 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
375 /*-----------------------------------------------------------------*/
376 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
378 // bool r0iu = FALSE , r1iu = FALSE;
379 // bool r0ou = FALSE , r1ou = FALSE;
380 bool fsr0iu = FALSE, fsr0ou;
381 bool fsr2iu = FALSE, fsr2ou;
383 fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
386 fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
387 fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
389 fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
390 fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
392 if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
393 fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
394 DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
397 if(!fsr0iu && !fsr0ou) {
398 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
399 (*aopp)->type = AOP_FSR0;
401 fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
403 return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
407 /* no usage of FSR2 */
408 if(!fsr2iu && !fsr2ou) {
409 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
410 (*aopp)->type = AOP_FSR2;
412 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
416 /* now we know they both have usage */
417 /* if fsr0 not used in this instruction */
419 if (!_G.fsr0Pushed) {
420 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
421 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
425 ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
426 (*aopp)->type = AOP_FSR0;
428 // fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__);
430 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
434 fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
439 /* the logic: if r0 & r1 used in the instruction
440 then we are in trouble otherwise */
442 /* first check if r0 & r1 are used by this
443 instruction, in which case we are in trouble */
444 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
445 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
450 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
451 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
453 /* if no usage of r0 then return it */
454 if (!r0iu && !r0ou) {
455 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
456 (*aopp)->type = AOP_R0;
458 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
461 /* if no usage of r1 then return it */
462 if (!r1iu && !r1ou) {
463 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
464 (*aopp)->type = AOP_R1;
466 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
469 /* now we know they both have usage */
470 /* if r0 not used in this instruction */
472 /* push it if not already pushed */
474 //pic16_emitcode ("push","%s",
475 // pic16_regWithIdx(R0_IDX)->dname);
479 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
480 (*aopp)->type = AOP_R0;
482 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
485 /* if r1 not used then */
488 /* push it if not already pushed */
490 //pic16_emitcode ("push","%s",
491 // pic16_regWithIdx(R1_IDX)->dname);
495 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
496 (*aopp)->type = AOP_R1;
497 return pic16_regWithIdx(R1_IDX);
501 /* I said end of world but not quite end of world yet */
502 /* if this is a result then we can push it on the stack*/
504 (*aopp)->type = AOP_STK;
508 /* other wise this is true end of the world */
509 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
510 "getFreePtr should never reach here");
515 /*-----------------------------------------------------------------*/
516 /* newAsmop - creates a new asmOp */
517 /*-----------------------------------------------------------------*/
518 static asmop *newAsmop (short type)
522 aop = Safe_calloc(1,sizeof(asmop));
527 static void genSetDPTR(int n)
531 pic16_emitcode(";", "Select standard DPTR");
532 pic16_emitcode("mov", "dps, #0x00");
536 pic16_emitcode(";", "Select alternate DPTR");
537 pic16_emitcode("mov", "dps, #0x01");
541 /*-----------------------------------------------------------------*/
542 /* resolveIfx - converts an iCode ifx into a form more useful for */
543 /* generating code */
544 /*-----------------------------------------------------------------*/
545 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
548 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
554 resIfx->condition = 1; /* assume that the ifx is true */
555 resIfx->generated = 0; /* indicate that the ifx has not been used */
558 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
561 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
562 __FUNCTION__,__LINE__,resIfx->lbl->key);
567 resIfx->lbl = IC_TRUE(ifx);
569 resIfx->lbl = IC_FALSE(ifx);
570 resIfx->condition = 0;
575 DEBUGpic16_emitcode("; ***","ifx true is non-null");
577 DEBUGpic16_emitcode("; ***","ifx false is non-null");
581 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset);
585 /*-----------------------------------------------------------------*/
586 /* pointerCode - returns the code for a pointer type */
587 /*-----------------------------------------------------------------*/
588 static int pointerCode (sym_link *etype)
591 return PTR_TYPE(SPEC_OCLS(etype));
596 /*-----------------------------------------------------------------*/
597 /* aopForSym - for a true symbol */
598 /*-----------------------------------------------------------------*/
599 static asmop *aopForSym (iCode *ic, operand *op, bool result)
601 symbol *sym=OP_SYMBOL(op);
603 memmap *space= SPEC_OCLS(sym->etype);
605 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
607 _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
609 // sym = OP_SYMBOL(op);
611 /* if already has one */
613 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
618 /* if symbol was initially placed onStack then we must re-place it
619 * to direct memory, since pic16 does not have a specific stack */
621 fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
626 /* assign depending on the storage class */
627 /* if it is on the stack or indirectly addressable */
628 /* space we need to assign either r0 or r1 to it */
629 if (sym->onStack || sym->iaccess) {
633 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
634 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
636 /* acquire a temporary register -- it is saved in function */
638 sym->aop = aop = newAsmop(AOP_STA);
639 aop->aopu.stk.stk = sym->stack;
640 aop->size = getSize(sym->type);
643 DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
644 pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
645 if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
646 && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
648 for(i=0;i<aop->size;i++)
649 aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
650 _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
652 for(i=0;i<aop->size;i++) {
653 aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
654 _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
658 // fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
661 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
664 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
667 for(i=0;i<aop->size;i++) {
669 /* initialise for stack access via frame pointer */
670 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack + i + _G.stack_lat));
672 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
673 pic16_popCopyReg(&pic16_pc_plusw2), pcop[i]));
677 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
684 /* now assign the address of the variable to
685 the pointer register */
686 if (aop->type != AOP_STK) {
690 pic16_emitcode("push","acc");
692 pic16_emitcode("mov","a,_bp");
693 pic16_emitcode("add","a,#0x%02x",
695 ((char)(sym->stack - _G.nRegsSaved )) :
696 ((char)sym->stack)) & 0xff);
697 pic16_emitcode("mov","%s,a",
698 aop->aopu.aop_ptr->name);
701 pic16_emitcode("pop","acc");
703 pic16_emitcode("mov","%s,#%s",
704 aop->aopu.aop_ptr->name,
706 aop->paged = space->paged;
708 aop->aopu.aop_stk = sym->stack;
716 if (sym->onStack && options.stack10bit)
718 /* It's on the 10 bit stack, which is located in
722 //DEBUGpic16_emitcode(";","%d",__LINE__);
725 pic16_emitcode("push","acc");
727 pic16_emitcode("mov","a,_bp");
728 pic16_emitcode("add","a,#0x%02x",
730 ((char)(sym->stack - _G.nRegsSaved )) :
731 ((char)sym->stack)) & 0xff);
734 pic16_emitcode ("mov","dpx1,#0x40");
735 pic16_emitcode ("mov","dph1,#0x00");
736 pic16_emitcode ("mov","dpl1, a");
740 pic16_emitcode("pop","acc");
742 sym->aop = aop = newAsmop(AOP_DPTR2);
743 aop->size = getSize(sym->type);
749 /* special case for a function */
750 if (IS_FUNC(sym->type)) {
751 sym->aop = aop = newAsmop(AOP_PCODE);
752 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
753 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
754 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
755 PCOI(aop->aopu.pcop)->index = 0;
756 aop->size = FPTRSIZE;
757 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
764 //DEBUGpic16_emitcode(";","%d",__LINE__);
765 /* if in bit space */
766 if (IN_BITSPACE(space)) {
767 sym->aop = aop = newAsmop (AOP_CRY);
768 aop->aopu.aop_dir = sym->rname ;
769 aop->size = getSize(sym->type);
770 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
773 /* if it is in direct space */
774 if (IN_DIRSPACE(space)) {
775 sym->aop = aop = newAsmop (AOP_DIR);
776 aop->aopu.aop_dir = sym->rname ;
777 aop->size = getSize(sym->type);
778 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
779 pic16_allocDirReg( IC_LEFT(ic) );
784 if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
785 sym->aop = aop = newAsmop (AOP_DIR);
786 aop->aopu.aop_dir = sym->rname ;
787 aop->size = getSize(sym->type);
788 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
789 pic16_allocDirReg( IC_LEFT(ic) );
794 /* only remaining is far space */
795 sym->aop = aop = newAsmop(AOP_PCODE);
797 /* change the next if to 1 to revert to good old immediate code */
798 if(IN_CODESPACE(space)) {
799 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
800 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
801 PCOI(aop->aopu.pcop)->index = 0;
803 /* try to allocate via direct register */
804 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
805 // aop->size = getSize( sym->type );
808 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
809 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
812 if(!pic16_allocDirReg (IC_LEFT(ic)))
816 if(IN_DIRSPACE( space ))
818 else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
819 aop->size = FPTRSIZE;
820 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
821 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
822 else if(sym->onStack) {
828 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
830 /* if it is in code space */
831 if (IN_CODESPACE(space))
837 /*-----------------------------------------------------------------*/
838 /* aopForRemat - rematerialzes an object */
839 /*-----------------------------------------------------------------*/
840 static asmop *aopForRemat (operand *op) // x symbol *sym)
842 symbol *sym = OP_SYMBOL(op);
844 iCode *ic = NULL, *oldic;
845 asmop *aop = newAsmop(AOP_PCODE);
851 ic = sym->rematiCode;
853 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
855 if(IS_OP_POINTER(op)) {
856 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
862 // pic16_emitpcomment("ic: %s\n", printILine(ic));
865 val += (int) operandLitValue(IC_RIGHT(ic));
866 } else if (ic->op == '-') {
867 val -= (int) operandLitValue(IC_RIGHT(ic));
871 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
874 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
877 if(!op->isaddr)viaimmd++; else viaimmd=0;
879 /* set the following if to 1 to revert to good old immediate code */
880 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
883 DEBUGpic16_emitcode(";", "%s:%d immediate", __FILE__, __LINE__);
885 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
888 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
890 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
893 PCOI(aop->aopu.pcop)->index = val;
895 DEBUGpic16_emitcode(";", "%s:%d dir", __FILE__, __LINE__);
897 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
898 getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
899 // aop->size = AOP_SIZE( IC_LEFT(ic) );
903 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
904 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
906 val, IS_PTR_CONST(operandType(op)));
908 val, IS_CODEPTR(operandType(op)));
911 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
913 pic16_allocDirReg (IC_LEFT(ic));
915 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
922 static int aopIdx (asmop *aop, int offset)
927 if(aop->type != AOP_REG)
930 return aop->aopu.aop_reg[offset]->rIdx;
935 /*-----------------------------------------------------------------*/
936 /* regsInCommon - two operands have some registers in common */
937 /*-----------------------------------------------------------------*/
938 static bool regsInCommon (operand *op1, operand *op2)
943 /* if they have registers in common */
944 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
947 sym1 = OP_SYMBOL(op1);
948 sym2 = OP_SYMBOL(op2);
950 if (sym1->nRegs == 0 || sym2->nRegs == 0)
953 for (i = 0 ; i < sym1->nRegs ; i++) {
958 for (j = 0 ; j < sym2->nRegs ;j++ ) {
962 if (sym2->regs[j] == sym1->regs[i])
970 /*-----------------------------------------------------------------*/
971 /* operandsEqu - equivalent */
972 /*-----------------------------------------------------------------*/
973 static bool operandsEqu ( operand *op1, operand *op2)
977 /* if they not symbols */
978 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
981 sym1 = OP_SYMBOL(op1);
982 sym2 = OP_SYMBOL(op2);
984 /* if both are itemps & one is spilt
985 and the other is not then false */
986 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
987 sym1->isspilt != sym2->isspilt )
990 /* if they are the same */
994 if (sym1->rname[0] && sym2->rname[0]
995 && strcmp (sym1->rname, sym2->rname) == 0)
999 /* if left is a tmp & right is not */
1000 if (IS_ITEMP(op1) &&
1003 (sym1->usl.spillLoc == sym2))
1006 if (IS_ITEMP(op2) &&
1010 (sym2->usl.spillLoc == sym1))
1016 /*-----------------------------------------------------------------*/
1017 /* pic16_sameRegs - two asmops have the same registers */
1018 /*-----------------------------------------------------------------*/
1019 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
1026 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
1027 pic16_AopType(aop1->type), pic16_AopType(aop2->type));
1029 if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
1031 if (aop1->type != AOP_REG ||
1032 aop2->type != AOP_REG )
1035 if (aop1->size != aop2->size )
1038 for (i = 0 ; i < aop1->size ; i++ ) {
1039 // if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE;
1041 // if(aop1->aopu.aop_reg[i]->type == AOP_REG)
1042 if (strcmp(aop1->aopu.aop_reg[i]->name, aop2->aopu.aop_reg[i]->name ))
1049 bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
1051 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
1052 pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
1054 if(aop1 == aop2)return TRUE;
1055 if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
1057 if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
1063 /*-----------------------------------------------------------------*/
1064 /* pic16_aopOp - allocates an asmop for an operand : */
1065 /*-----------------------------------------------------------------*/
1066 void pic16_aopOp (operand *op, iCode *ic, bool result)
1075 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
1077 /* if this a literal */
1078 if (IS_OP_LITERAL(op)) {
1079 op->aop = aop = newAsmop(AOP_LIT);
1080 aop->aopu.aop_lit = op->operand.valOperand;
1081 aop->size = getSize(operandType(op));
1086 sym_link *type = operandType(op);
1088 if(IS_PTR_CONST(type))
1090 if(IS_CODEPTR(type))
1092 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1095 /* if already has a asmop then continue */
1099 /* if the underlying symbol has a aop */
1100 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
1101 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
1102 op->aop = OP_SYMBOL(op)->aop;
1106 /* if this is a true symbol */
1107 if (IS_TRUE_SYMOP(op)) {
1108 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
1109 op->aop = aopForSym(ic, op, result);
1113 /* this is a temporary : this has
1119 e) can be a return use only */
1121 sym = OP_SYMBOL(op);
1123 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
1124 /* if the type is a conditional */
1125 if (sym->regType == REG_CND) {
1126 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
1131 /* if it is spilt then two situations
1133 b) has a spill location */
1134 if (sym->isspilt || sym->nRegs == 0) {
1136 DEBUGpic16_emitcode(";","%d",__LINE__);
1137 /* rematerialize it NOW */
1140 sym->aop = op->aop = aop = aopForRemat (op);
1141 aop->size = getSize(sym->type);
1142 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
1149 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
1150 aop->size = getSize(sym->type);
1151 for ( i = 0 ; i < 1 ; i++ ) {
1152 aop->aopu.aop_str[i] = accUse[i];
1153 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
1155 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
1156 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
1164 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1165 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1166 //pic16_allocDirReg (IC_LEFT(ic));
1167 aop->size = getSize(sym->type);
1172 aop = op->aop = sym->aop = newAsmop(AOP_STR);
1173 aop->size = getSize(sym->type);
1174 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
1175 aop->aopu.aop_str[i] = fReturn[i];
1177 DEBUGpic16_emitcode(";","%d",__LINE__);
1181 /* else spill location */
1182 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
1183 /* force a new aop if sizes differ */
1184 sym->usl.spillLoc->aop = NULL;
1188 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1189 __FUNCTION__,__LINE__,
1190 sym->usl.spillLoc->rname,
1191 sym->rname, sym->usl.spillLoc->offset);
1194 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1195 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1196 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1198 sym->usl.spillLoc->offset, op);
1199 aop->size = getSize(sym->type);
1205 sym_link *type = operandType(op);
1207 if(IS_PTR_CONST(type))
1209 if(IS_CODEPTR(type))
1211 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1214 /* must be in a register */
1215 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1216 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1217 aop->size = sym->nRegs;
1218 for ( i = 0 ; i < sym->nRegs ;i++)
1219 aop->aopu.aop_reg[i] = sym->regs[i];
1222 /*-----------------------------------------------------------------*/
1223 /* pic16_freeAsmop - free up the asmop given to an operand */
1224 /*----------------------------------------------------------------*/
1225 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1242 /* depending on the asmop type only three cases need work AOP_RO
1243 , AOP_R1 && AOP_STK */
1245 switch (aop->type) {
1247 if (_G.fsr0Pushed ) {
1249 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
1250 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
1251 // pic16_emitcode ("pop","ar0");
1255 bitVectUnSetBit(ic->rUsed,IDX_FSR0);
1259 bitVectUnSetBit(ic->rUsed,IDX_FSR2);
1265 pic16_emitcode ("pop","ar0");
1269 bitVectUnSetBit(ic->rUsed,R0_IDX);
1275 pic16_emitcode ("pop","ar1");
1279 bitVectUnSetBit(ic->rUsed,R1_IDX);
1286 /* we must store the result on stack */
1287 if((op == IC_RESULT(ic)) && RESULTONSTA(ic)) {
1288 if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1289 for(i=0;i<aop->size;i++) {
1290 /* initialise for stack access via frame pointer */
1291 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(OP_SYMBOL(IC_RESULT(ic))->stack + i + _G.stack_lat));
1293 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1294 aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2)));
1297 if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1301 for(i=0;i<aop->size;i++)
1302 PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
1311 int stk = aop->aopu.aop_stk + aop->size;
1312 bitVectUnSetBit(ic->rUsed,R0_IDX);
1313 bitVectUnSetBit(ic->rUsed,R1_IDX);
1315 getFreePtr(ic,&aop,FALSE);
1317 if (options.stack10bit)
1319 /* I'm not sure what to do here yet... */
1322 "*** Warning: probably generating bad code for "
1323 "10 bit stack mode.\n");
1327 pic16_emitcode ("mov","a,_bp");
1328 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1329 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1331 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1335 pic16_emitcode("pop","acc");
1336 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1338 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1341 pic16_freeAsmop(op,NULL,ic,TRUE);
1343 pic16_emitcode("pop","ar0");
1348 pic16_emitcode("pop","ar1");
1358 /* all other cases just dealloc */
1362 OP_SYMBOL(op)->aop = NULL;
1363 /* if the symbol has a spill */
1365 SPIL_LOC(op)->aop = NULL;
1370 /*-----------------------------------------------------------------*/
1371 /* pic16_aopGet - for fetching value of the aop */
1372 /*-----------------------------------------------------------------*/
1373 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1378 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1380 /* offset is greater than size then zero */
1381 if (offset > (aop->size - 1) &&
1382 aop->type != AOP_LIT)
1385 /* depending on type */
1386 switch (aop->type) {
1390 sprintf(s, "%s", aop->aopu.aop_ptr->name);
1391 rs = Safe_calloc(1, strlen(s)+1);
1396 /* if we need to increment it */
1397 while (offset > aop->coff)
1399 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1403 while (offset < aop->coff)
1405 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1411 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
1412 return (dname ? "acc" : "a");
1414 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
1415 rs = Safe_calloc (1, strlen (s) + 1);
1423 sprintf (s,"%s",aop->aopu.aop_immd);
1426 sprintf(s,"(%s >> %d)",
1431 aop->aopu.aop_immd);
1432 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1433 rs = Safe_calloc(1,strlen(s)+1);
1439 sprintf(s,"(%s + %d)",
1442 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1444 sprintf(s,"%s",aop->aopu.aop_dir);
1445 rs = Safe_calloc(1,strlen(s)+1);
1451 // return aop->aopu.aop_reg[offset]->dname;
1453 return aop->aopu.aop_reg[offset]->name;
1456 //pic16_emitcode(";","%d",__LINE__);
1457 return aop->aopu.aop_dir;
1460 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
1461 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1463 // return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1464 rs = Safe_strdup("WREG");
1468 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1469 rs = Safe_calloc(1,strlen(s)+1);
1474 aop->coff = offset ;
1475 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1478 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1480 return aop->aopu.aop_str[offset];
1484 pCodeOp *pcop = aop->aopu.pcop;
1485 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1487 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1488 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1489 sprintf(s,"%s", pcop->name);
1491 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1494 rs = Safe_calloc(1,strlen(s)+1);
1499 rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
1503 // pCodeOp *pcop = aop->aop
1508 fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type));
1509 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1510 "aopget got unsupported aop->type");
1516 /* lock has the following meaning: When allocating temporary registers
1517 * for stack variables storage, the value of the temporary register is
1518 * saved on stack. Its value is restored at the end. This procedure is
1519 * done via calls to pic16_aopOp and pic16_freeAsmop functions. There is
1520 * a possibility that before a call to pic16_aopOp, a temporary register
1521 * is allocated for a while and it is freed after some time, this will
1522 * mess the stack and values will not be restored properly. So use lock=1
1523 * to allocate temporary registers used internally by the programmer, and
1524 * lock=0 to allocate registers for stack use. lock=1 will emit a warning
1525 * to inform the compiler developer about a possible bug. This is an internal
1526 * feature for developing the compiler -- VR */
1528 int _TempReg_lock = 0;
1529 /*-----------------------------------------------------------------*/
1530 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1531 /*-----------------------------------------------------------------*/
1532 pCodeOp *pic16_popGetTempReg(int lock)
1537 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1539 werror(W_POSSBUG2, __FILE__, __LINE__);
1542 _TempReg_lock += lock;
1547 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1548 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1549 PCOR(pcop)->r->wasUsed=1;
1550 PCOR(pcop)->r->isFree=0;
1552 /* push value on stack */
1553 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1561 /*-----------------------------------------------------------------*/
1562 /* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */
1563 /* don't save if inside v */
1564 /*-----------------------------------------------------------------*/
1565 pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
1570 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1573 werror(W_POSSBUG2, __FILE__, __LINE__);
1576 _TempReg_lock += lock;
1581 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1582 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1583 PCOR(pcop)->r->wasUsed=1;
1584 PCOR(pcop)->r->isFree=0;
1586 if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
1587 /* push value on stack */
1588 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1598 /*-----------------------------------------------------------------*/
1599 /* pic16_popReleaseTempReg - create a new temporary pCodeOp */
1600 /*-----------------------------------------------------------------*/
1601 void pic16_popReleaseTempReg(pCodeOp *pcop, int lock)
1603 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1605 _TempReg_lock -= lock;
1607 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1608 PCOR(pcop)->r->isFree = 1;
1609 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1612 /*-----------------------------------------------------------------*/
1613 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1614 /*-----------------------------------------------------------------*/
1615 pCodeOp *pic16_popGetLabel(unsigned int key)
1618 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
1623 return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset);
1626 /*-----------------------------------------------------------------*/
1627 /* pic16_popCopyReg - copy a pcode operator */
1628 /*-----------------------------------------------------------------*/
1629 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1633 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1634 pcor->pcop.type = pc->pcop.type;
1636 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1637 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1639 pcor->pcop.name = NULL;
1642 pcor->rIdx = pc->rIdx;
1645 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1650 /*-----------------------------------------------------------------*/
1651 /* pic16_popGetLit - asm operator to pcode operator conversion */
1652 /*-----------------------------------------------------------------*/
1653 pCodeOp *pic16_popGetLit(int lit)
1655 return pic16_newpCodeOpLit(lit);
1658 /*-----------------------------------------------------------------*/
1659 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1660 /*-----------------------------------------------------------------*/
1661 pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2)
1663 return pic16_newpCodeOpLit2(lit, arg2);
1667 /*-----------------------------------------------------------------*/
1668 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1669 /*-----------------------------------------------------------------*/
1670 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1672 return pic16_newpCodeOpImmd(name, offset,index, 0);
1676 /*-----------------------------------------------------------------*/
1677 /* pic16_popGet - asm operator to pcode operator conversion */
1678 /*-----------------------------------------------------------------*/
1679 pCodeOp *pic16_popGetWithString(char *str)
1685 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1689 pcop = pic16_newpCodeOp(str,PO_STR);
1694 /*-----------------------------------------------------------------*/
1695 /* pic16_popRegFromString - */
1696 /*-----------------------------------------------------------------*/
1697 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op)
1700 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1701 pcop->type = PO_DIR;
1703 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1704 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1709 pcop->name = Safe_calloc(1,strlen(str)+1);
1710 strcpy(pcop->name,str);
1712 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1714 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1716 /* make sure that register doesn't exist,
1717 * and operand isn't NULL
1718 * and symbol isn't in codespace (codespace symbols are handled elsewhere) */
1719 if((PCOR(pcop)->r == NULL)
1721 && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
1722 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1723 // __FUNCTION__, __LINE__, str, size, offset);
1725 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
1726 fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
1729 PCOR(pcop)->instance = offset;
1734 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1738 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1740 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1741 PCOR(pcop)->rIdx = rIdx;
1742 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1744 PCOR(pcop)->r->isFree = 0;
1745 PCOR(pcop)->r->wasUsed = 1;
1747 pcop->type = PCOR(pcop)->r->pc_type;
1752 /*---------------------------------------------------------------------------------*/
1753 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1755 /*---------------------------------------------------------------------------------*/
1756 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1761 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1763 /* comment the following check, so errors to throw up */
1764 // if(!pcop2)return NULL;
1766 temp = pic16_popGet(aop_dst, offset);
1767 pcop2->pcop2 = temp;
1774 /*--------------------------------------------------------------------------------.-*/
1775 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1776 /* VR 030601 , adapted by Hans Dorn */
1777 /*--------------------------------------------------------------------------------.-*/
1778 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1782 pcop2 = (pCodeOpReg2 *)src;
1790 /*---------------------------------------------------------------------------------*/
1791 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1792 /* movff instruction */
1793 /*---------------------------------------------------------------------------------*/
1794 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1799 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1800 pcop2->pcop2 = pic16_popCopyReg(dst);
1802 /* the pCodeOp may be already allocated */
1803 pcop2 = (pCodeOpReg2 *)(src);
1804 pcop2->pcop2 = (pCodeOp *)(dst);
1811 /*-----------------------------------------------------------------*/
1812 /* pic16_popGet - asm operator to pcode operator conversion */
1813 /*-----------------------------------------------------------------*/
1814 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1816 //char *s = buffer ;
1820 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1821 /* offset is greater than
1824 // if (offset > (aop->size - 1) &&
1825 // aop->type != AOP_LIT)
1826 // return NULL; //zero;
1828 /* depending on type */
1829 switch (aop->type) {
1835 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1836 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1843 pcop = Safe_calloc(1, sizeof(pCodeOpReg));
1844 PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
1845 PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
1846 PCOR(pcop)->r->wasUsed = 1;
1847 PCOR(pcop)->r->isFree = 0;
1849 PCOR(pcop)->instance = offset;
1850 pcop->type = PCOR(pcop)->r->pc_type;
1854 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1855 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1858 /* pCodeOp is already allocated from aopForSym */
1859 DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
1860 pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
1866 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1868 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1870 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1872 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1873 PCOR(pcop)->rIdx = rIdx;
1874 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1875 PCOR(pcop)->r->wasUsed=1;
1876 PCOR(pcop)->r->isFree=0;
1878 PCOR(pcop)->instance = offset;
1879 pcop->type = PCOR(pcop)->r->pc_type;
1880 // rs = aop->aopu.aop_reg[offset]->name;
1881 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1885 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1886 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1892 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1893 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
1897 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1899 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1901 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1902 // pcop->type = PO_GPR_REGISTER;
1903 PCOR(pcop)->rIdx = rIdx;
1904 PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
1905 PCOR(pcop)->r->wasUsed=1;
1906 PCOR(pcop)->r->isFree=0;
1908 PCOR(pcop)->instance = offset;
1909 pcop->type = PCOR(pcop)->r->pc_type;
1910 rs = aop->aopu.aop_reg[offset]->name;
1911 DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs);
1916 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1918 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
1919 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1920 //if(PCOR(pcop)->r == NULL)
1921 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1925 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1926 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1929 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1930 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1933 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1934 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1935 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1936 pcop->type = PCOR(pcop)->r->pc_type;
1937 pcop->name = PCOR(pcop)->r->name;
1943 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1945 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1946 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1948 switch( aop->aopu.pcop->type ) {
1949 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1950 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1952 assert( 0 ); /* should never reach here */;
1955 PCOI(pcop)->offset = offset;
1960 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1961 "pic16_popGet got unsupported aop->type");
1964 /*-----------------------------------------------------------------*/
1965 /* pic16_aopPut - puts a string for a aop */
1966 /*-----------------------------------------------------------------*/
1967 void pic16_aopPut (asmop *aop, char *s, int offset)
1974 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1976 if (aop->size && offset > ( aop->size - 1)) {
1977 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1978 "pic16_aopPut got offset > aop->size");
1982 /* will assign value to value */
1983 /* depending on where it is ofcourse */
1984 switch (aop->type) {
1987 sprintf(d,"(%s + %d)",
1988 aop->aopu.aop_dir,offset);
1989 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1992 sprintf(d,"%s",aop->aopu.aop_dir);
1995 DEBUGpic16_emitcode(";","%d",__LINE__);
1997 pic16_emitcode("movf","%s,w",s);
1998 pic16_emitcode("movwf","%s",d);
2001 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
2002 if(offset >= aop->size) {
2003 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2006 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
2009 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2016 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
2017 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
2020 strcmp(s,"r0") == 0 ||
2021 strcmp(s,"r1") == 0 ||
2022 strcmp(s,"r2") == 0 ||
2023 strcmp(s,"r3") == 0 ||
2024 strcmp(s,"r4") == 0 ||
2025 strcmp(s,"r5") == 0 ||
2026 strcmp(s,"r6") == 0 ||
2027 strcmp(s,"r7") == 0 )
2028 pic16_emitcode("mov","%s,%s ; %d",
2029 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
2033 if(strcmp(s,"W")==0 )
2034 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
2036 pic16_emitcode("movwf","%s",
2037 aop->aopu.aop_reg[offset]->name);
2039 if(strcmp(s,zero)==0) {
2040 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2042 } else if(strcmp(s,"W")==0) {
2043 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
2044 pcop->type = PO_GPR_REGISTER;
2046 PCOR(pcop)->rIdx = -1;
2047 PCOR(pcop)->r = NULL;
2049 DEBUGpic16_emitcode(";","%d",__LINE__);
2050 pcop->name = Safe_strdup(s);
2051 pic16_emitpcode(POC_MOVFW,pcop);
2052 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2053 } else if(strcmp(s,one)==0) {
2054 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2055 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
2057 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2065 if (aop->type == AOP_DPTR2)
2071 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2072 "pic16_aopPut writting to code space");
2076 while (offset > aop->coff) {
2078 pic16_emitcode ("inc","dptr");
2081 while (offset < aop->coff) {
2083 pic16_emitcode("lcall","__decdptr");
2088 /* if not in accumulater */
2091 pic16_emitcode ("movx","@dptr,a");
2093 if (aop->type == AOP_DPTR2)
2101 while (offset > aop->coff) {
2103 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
2105 while (offset < aop->coff) {
2107 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
2113 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
2118 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
2120 if (strcmp(s,"r0") == 0 ||
2121 strcmp(s,"r1") == 0 ||
2122 strcmp(s,"r2") == 0 ||
2123 strcmp(s,"r3") == 0 ||
2124 strcmp(s,"r4") == 0 ||
2125 strcmp(s,"r5") == 0 ||
2126 strcmp(s,"r6") == 0 ||
2127 strcmp(s,"r7") == 0 ) {
2129 sprintf(buffer,"a%s",s);
2130 pic16_emitcode("mov","@%s,%s",
2131 aop->aopu.aop_ptr->name,buffer);
2133 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
2138 if (strcmp(s,"a") == 0)
2139 pic16_emitcode("push","acc");
2141 pic16_emitcode("push","%s",s);
2146 /* if bit variable */
2147 if (!aop->aopu.aop_dir) {
2148 pic16_emitcode("clr","a");
2149 pic16_emitcode("rlc","a");
2152 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
2155 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
2158 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2160 lbl = newiTempLabel(NULL);
2162 if (strcmp(s,"a")) {
2165 pic16_emitcode("clr","c");
2166 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
2167 pic16_emitcode("cpl","c");
2168 pic16_emitcode("","%05d_DS_:",lbl->key+100);
2169 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2176 if (strcmp(aop->aopu.aop_str[offset],s))
2177 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
2182 if (!offset && (strcmp(s,"acc") == 0))
2185 if (strcmp(aop->aopu.aop_str[offset],s))
2186 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
2190 fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type);
2191 // werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2192 // "pic16_aopPut got unsupported aop->type");
2198 /*-----------------------------------------------------------------*/
2199 /* mov2w - generate either a MOVLW or MOVFW based operand type */
2200 /*-----------------------------------------------------------------*/
2201 static void mov2w (asmop *aop, int offset)
2203 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
2206 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
2208 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
2211 static void mov2f(asmop *dst, asmop *src, int offset)
2213 if(is_LitAOp(src)) {
2214 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2215 pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
2217 if(pic16_sameRegsOfs(src, dst, offset))return;
2218 pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset),
2219 pic16_popGet(dst, offset)));
2223 static void mov2fp(pCodeOp *dst, asmop *src, int offset)
2225 if(is_LitAOp(src)) {
2226 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2227 pic16_emitpcode(POC_MOVWF, dst);
2229 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(src, offset), dst));
2234 /* push pcop into stack */
2235 void pic16_pushpCodeOp(pCodeOp *pcop)
2237 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2238 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
2241 /* pop pcop from stack */
2242 void pic16_poppCodeOp(pCodeOp *pcop)
2244 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
2248 /*-----------------------------------------------------------------*/
2249 /* pushw - pushes wreg to stack */
2250 /*-----------------------------------------------------------------*/
2253 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2254 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2258 /*-----------------------------------------------------------------*/
2259 /* pushaop - pushes aop to stack */
2260 /*-----------------------------------------------------------------*/
2261 void pushaop(asmop *aop, int offset)
2263 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2264 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
2267 /*-----------------------------------------------------------------*/
2268 /* popaop - pops aop from stack */
2269 /*-----------------------------------------------------------------*/
2270 void popaop(asmop *aop, int offset)
2272 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
2273 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
2276 void popaopidx(asmop *aop, int offset, int index)
2280 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2282 if(STACK_MODEL_LARGE)ofs++;
2284 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
2285 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
2288 /*-----------------------------------------------------------------*/
2289 /* reAdjustPreg - points a register back to where it should */
2290 /*-----------------------------------------------------------------*/
2291 static void reAdjustPreg (asmop *aop)
2295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2297 if ((size = aop->size) <= 1)
2300 switch (aop->type) {
2304 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
2308 if (aop->type == AOP_DPTR2)
2314 pic16_emitcode("lcall","__decdptr");
2317 if (aop->type == AOP_DPTR2)
2329 /*-----------------------------------------------------------------*/
2330 /* opIsGptr: returns non-zero if the passed operand is */
2331 /* a generic pointer type. */
2332 /*-----------------------------------------------------------------*/
2333 static int opIsGptr(operand *op)
2335 sym_link *type = operandType(op);
2337 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2338 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2346 /*-----------------------------------------------------------------*/
2347 /* pic16_getDataSize - get the operand data size */
2348 /*-----------------------------------------------------------------*/
2349 int pic16_getDataSize(operand *op)
2351 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2354 return AOP_SIZE(op);
2356 // tsd- in the pic port, the genptr size is 1, so this code here
2357 // fails. ( in the 8051 port, the size was 4).
2360 size = AOP_SIZE(op);
2361 if (size == GPTRSIZE)
2363 sym_link *type = operandType(op);
2364 if (IS_GENPTR(type))
2366 /* generic pointer; arithmetic operations
2367 * should ignore the high byte (pointer type).
2370 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2377 /*-----------------------------------------------------------------*/
2378 /* pic16_outAcc - output Acc */
2379 /*-----------------------------------------------------------------*/
2380 void pic16_outAcc(operand *result)
2383 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2384 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2387 size = pic16_getDataSize(result);
2389 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2392 /* unsigned or positive */
2394 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2399 /*-----------------------------------------------------------------*/
2400 /* pic16_outBitC - output a bit C */
2401 /* Move to result the value of Carry flag -- VR */
2402 /*-----------------------------------------------------------------*/
2403 void pic16_outBitC(operand *result)
2407 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2408 /* if the result is bit */
2409 if (AOP_TYPE(result) == AOP_CRY) {
2410 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2411 pic16_aopPut(AOP(result),"c",0);
2414 i = AOP_SIZE(result);
2416 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2418 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2421 pic16_emitcode("clr","a ; %d", __LINE__);
2422 pic16_emitcode("rlc","a");
2423 pic16_outAcc(result);
2428 /*-----------------------------------------------------------------*/
2429 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2430 /*-----------------------------------------------------------------*/
2431 void pic16_toBoolean(operand *oper)
2433 int size = AOP_SIZE(oper) - 1;
2436 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2438 if ( AOP_TYPE(oper) != AOP_ACC) {
2439 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2442 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2447 #if !defined(GEN_Not)
2448 /*-----------------------------------------------------------------*/
2449 /* genNot - generate code for ! operation */
2450 /*-----------------------------------------------------------------*/
2451 static void pic16_genNot (iCode *ic)
2456 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2457 /* assign asmOps to operand & result */
2458 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2459 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2461 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2462 /* if in bit space then a special case */
2463 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2464 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2465 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2466 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2468 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2469 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2470 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2475 size = AOP_SIZE(IC_LEFT(ic));
2477 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2478 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2479 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2482 pic16_toBoolean(IC_LEFT(ic));
2484 tlbl = newiTempLabel(NULL);
2485 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2486 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2487 pic16_outBitC(IC_RESULT(ic));
2490 /* release the aops */
2491 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2492 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2497 #if !defined(GEN_Cpl)
2498 /*-----------------------------------------------------------------*/
2499 /* genCpl - generate code for complement */
2500 /*-----------------------------------------------------------------*/
2501 static void pic16_genCpl (iCode *ic)
2507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2508 /* assign asmOps to operand & result */
2509 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2510 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2512 /* if both are in bit space then
2514 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2515 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2517 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2518 pic16_emitcode("cpl","c");
2519 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2523 size = AOP_SIZE(IC_RESULT(ic));
2526 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2528 pic16_emitcode("cpl","a");
2529 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2531 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2532 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2534 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2535 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2543 /* release the aops */
2544 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2545 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2549 /*-----------------------------------------------------------------*/
2550 /* genUminusFloat - unary minus for floating points */
2551 /*-----------------------------------------------------------------*/
2552 static void genUminusFloat(operand *op,operand *result)
2554 int size ,offset =0 ;
2557 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2558 /* for this we just need to flip the
2559 first it then copy the rest in place */
2560 size = AOP_SIZE(op) - 1;
2561 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2565 pic16_emitcode("cpl","acc.7");
2566 pic16_aopPut(AOP(result),"a",3);
2569 pic16_aopPut(AOP(result),
2570 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2576 /*-----------------------------------------------------------------*/
2577 /* genUminus - unary minus code generation */
2578 /*-----------------------------------------------------------------*/
2579 static void genUminus (iCode *ic)
2582 sym_link *optype, *rtype;
2584 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2587 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2588 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2590 /* if both in bit space then special case */
2591 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
2592 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2594 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2595 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2596 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2601 optype = operandType(IC_LEFT(ic));
2602 rtype = operandType(IC_RESULT(ic));
2604 /* if float then do float stuff */
2605 if (IS_FLOAT(optype)) {
2606 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2610 /* otherwise subtract from zero by taking the 2's complement */
2611 size = AOP_SIZE(IC_LEFT(ic));
2613 for(i=0; i<size; i++) {
2614 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2615 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2617 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2618 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2622 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2623 for(i=1; i<size; i++) {
2625 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2629 /* release the aops */
2630 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2631 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2635 /*-----------------------------------------------------------------*/
2636 /* saveRegisters - will look for a call and save the registers */
2637 /*-----------------------------------------------------------------*/
2638 static void saveRegisters(iCode *lic)
2645 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 for (ic = lic ; ic ; ic = ic->next)
2648 if (ic->op == CALL || ic->op == PCALL)
2652 fprintf(stderr,"found parameter push with no function call\n");
2656 /* if the registers have been saved already then
2658 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2661 /* find the registers in use at this time
2662 and push them away to safety */
2663 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2667 if (options.useXstack) {
2668 if (bitVectBitValue(rsave,R0_IDX))
2669 pic16_emitcode("mov","b,r0");
2670 pic16_emitcode("mov","r0,%s",spname);
2671 for (i = 0 ; i < pic16_nRegs ; i++) {
2672 if (bitVectBitValue(rsave,i)) {
2674 pic16_emitcode("mov","a,b");
2676 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2677 pic16_emitcode("movx","@r0,a");
2678 pic16_emitcode("inc","r0");
2681 pic16_emitcode("mov","%s,r0",spname);
2682 if (bitVectBitValue(rsave,R0_IDX))
2683 pic16_emitcode("mov","r0,b");
2685 //for (i = 0 ; i < pic16_nRegs ; i++) {
2686 // if (bitVectBitValue(rsave,i))
2687 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2690 dtype = operandType(IC_LEFT(ic));
2691 if (currFunc && dtype &&
2692 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2693 IFFUNC_ISISR(currFunc->type) &&
2696 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2699 /*-----------------------------------------------------------------*/
2700 /* unsaveRegisters - pop the pushed registers */
2701 /*-----------------------------------------------------------------*/
2702 static void unsaveRegisters (iCode *ic)
2707 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2708 /* find the registers in use at this time
2709 and push them away to safety */
2710 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2713 if (options.useXstack) {
2714 pic16_emitcode("mov","r0,%s",spname);
2715 for (i = pic16_nRegs ; i >= 0 ; i--) {
2716 if (bitVectBitValue(rsave,i)) {
2717 pic16_emitcode("dec","r0");
2718 pic16_emitcode("movx","a,@r0");
2720 pic16_emitcode("mov","b,a");
2722 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2726 pic16_emitcode("mov","%s,r0",spname);
2727 if (bitVectBitValue(rsave,R0_IDX))
2728 pic16_emitcode("mov","r0,b");
2730 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2731 // if (bitVectBitValue(rsave,i))
2732 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2739 /*-----------------------------------------------------------------*/
2741 /*-----------------------------------------------------------------*/
2742 static void pushSide(operand * oper, int size)
2745 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2747 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2748 if (AOP_TYPE(oper) != AOP_REG &&
2749 AOP_TYPE(oper) != AOP_DIR &&
2751 pic16_emitcode("mov","a,%s",l);
2752 pic16_emitcode("push","acc");
2754 pic16_emitcode("push","%s",l);
2759 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2761 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2762 pic16_emitpcode(POC_MOVFW, src);
2763 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2765 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2766 src, pic16_popGet(AOP(op), offset)));
2771 /*-----------------------------------------------------------------*/
2772 /* assignResultValue - assign results to oper, rescall==1 is */
2773 /* called from genCall() or genPCall() */
2774 /*-----------------------------------------------------------------*/
2775 static void assignResultValue(operand * oper, int rescall)
2777 int size = AOP_SIZE(oper);
2780 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2781 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2784 /* assign result from a call/pcall function() */
2786 /* function results are stored in a special order,
2787 * see top of file with Function return policy, or manual */
2790 /* 8-bits, result in WREG */
2791 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2794 /* 16-bits, result in PRODL:WREG */
2795 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2799 /* 24-bits, result in PRODH:PRODL:WREG */
2800 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2804 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2805 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2809 /* >32-bits, result on stack, and FSR0 points to beginning.
2810 * Fix stack when done */
2813 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2814 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2816 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2821 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2822 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2823 if(STACK_MODEL_LARGE) {
2825 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2829 int areg = 0; /* matching argument register */
2831 areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
2834 /* its called from genReceive (probably) -- VR */
2835 if(!GpsuedoStkPtr && _G.useWreg) {
2836 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2838 /* The last byte in the assignment is in W */
2839 if(areg <= GpsuedoStkPtr) {
2841 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
2846 _G.stack_lat = AOP_SIZE(oper)-1;
2851 popaopidx(AOP(oper), offset, GpsuedoStkPtr);
2858 /*-----------------------------------------------------------------*/
2859 /* genIpush - generate code for pushing this gets a little complex */
2860 /*-----------------------------------------------------------------*/
2861 static void genIpush (iCode *ic)
2863 // int size, offset=0;
2865 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2869 pic16_aopOp(IC_LEFT(ic), ic, FALSE );
2871 /* send to stack as normal */
2872 addSet(&_G.sendSet,ic);
2873 // addSetHead(&_G.sendSet,ic);
2874 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2879 int size, offset = 0 ;
2883 /* if this is not a parm push : ie. it is spill push
2884 and spill push is always done on the local stack */
2885 if (!ic->parmPush) {
2887 /* and the item is spilt then do nothing */
2888 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2891 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2892 size = AOP_SIZE(IC_LEFT(ic));
2893 /* push it on the stack */
2895 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2900 pic16_emitcode("push","%s",l);
2905 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2909 /*-----------------------------------------------------------------*/
2910 /* genIpop - recover the registers: can happen only for spilling */
2911 /*-----------------------------------------------------------------*/
2912 static void genIpop (iCode *ic)
2914 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2919 /* if the temp was not pushed then */
2920 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2923 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2924 size = AOP_SIZE(IC_LEFT(ic));
2927 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2930 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2935 /*-----------------------------------------------------------------*/
2936 /* unsaverbank - restores the resgister bank from stack */
2937 /*-----------------------------------------------------------------*/
2938 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2940 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2946 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2948 if (options.useXstack) {
2950 r = getFreePtr(ic,&aop,FALSE);
2953 pic16_emitcode("mov","%s,_spx",r->name);
2954 pic16_emitcode("movx","a,@%s",r->name);
2955 pic16_emitcode("mov","psw,a");
2956 pic16_emitcode("dec","%s",r->name);
2959 pic16_emitcode ("pop","psw");
2962 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2963 if (options.useXstack) {
2964 pic16_emitcode("movx","a,@%s",r->name);
2965 //pic16_emitcode("mov","(%s+%d),a",
2966 // regspic16[i].base,8*bank+regspic16[i].offset);
2967 pic16_emitcode("dec","%s",r->name);
2970 pic16_emitcode("pop",""); //"(%s+%d)",
2971 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2974 if (options.useXstack) {
2976 pic16_emitcode("mov","_spx,%s",r->name);
2977 pic16_freeAsmop(NULL,aop,ic,TRUE);
2983 /*-----------------------------------------------------------------*/
2984 /* saverbank - saves an entire register bank on the stack */
2985 /*-----------------------------------------------------------------*/
2986 static void saverbank (int bank, iCode *ic, bool pushPsw)
2988 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2994 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2995 if (options.useXstack) {
2998 r = getFreePtr(ic,&aop,FALSE);
2999 pic16_emitcode("mov","%s,_spx",r->name);
3003 for (i = 0 ; i < pic16_nRegs ;i++) {
3004 if (options.useXstack) {
3005 pic16_emitcode("inc","%s",r->name);
3006 //pic16_emitcode("mov","a,(%s+%d)",
3007 // regspic16[i].base,8*bank+regspic16[i].offset);
3008 pic16_emitcode("movx","@%s,a",r->name);
3010 pic16_emitcode("push","");// "(%s+%d)",
3011 //regspic16[i].base,8*bank+regspic16[i].offset);
3015 if (options.useXstack) {
3016 pic16_emitcode("mov","a,psw");
3017 pic16_emitcode("movx","@%s,a",r->name);
3018 pic16_emitcode("inc","%s",r->name);
3019 pic16_emitcode("mov","_spx,%s",r->name);
3020 pic16_freeAsmop (NULL,aop,ic,TRUE);
3023 pic16_emitcode("push","psw");
3025 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
3033 /*-----------------------------------------------------------------*/
3034 /* genCall - generates a call statement */
3035 /*-----------------------------------------------------------------*/
3036 static void genCall (iCode *ic)
3043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3045 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3046 /* if caller saves & we have not saved then */
3047 // if (!ic->regsSaved)
3048 // saveRegisters(ic);
3050 /* initialise stackParms for IPUSH pushes */
3051 // stackParms = psuedoStkPtr;
3052 // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
3053 fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
3056 gpsimDebug_StackDump(__FILE__, __LINE__, fname );
3059 /* if send set is not empty the assign */
3062 int psuedoStkPtr=-1;
3063 int firstTimeThruLoop = 1;
3067 /* reverse sendSet if function is not reentrant */
3068 if(!IFFUNC_ISREENT(ftype))
3069 _G.sendSet = reverseSet(_G.sendSet);
3072 /* First figure how many parameters are getting passed */
3074 /* do we really need to know this ? -- VR
3075 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3076 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3077 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
3078 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
3083 // stackParms = psuedoStkPtr;
3087 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3088 int size, offset = 0;
3090 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3091 size = AOP_SIZE(IC_LEFT(sic));
3096 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3097 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3098 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3100 if(!firstTimeThruLoop) {
3101 /* If this is not the first time we've been through the loop
3102 * then we need to save the parameter in a temporary
3103 * register. The last byte of the last parameter is
3107 // --psuedoStkPtr; // sanity check
3110 firstTimeThruLoop=0;
3112 mov2w (AOP(IC_LEFT(sic)), size);
3116 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3119 /* save last parameter to stack if functions has varargs */
3120 if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
3121 else use_wreg = 1; /* last parameter in WREG */
3123 _G.stackRegSet = _G.sendSet;
3128 pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
3131 /* if we need to assign a result value */
3132 if ((IS_ITEMP(IC_RESULT(ic))
3133 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3134 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3135 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3138 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3141 assignResultValue(IC_RESULT(ic), 1);
3143 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3144 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3146 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3149 if(!stackParms && ic->parmBytes) {
3150 stackParms = ic->parmBytes;
3153 stackParms -= use_wreg;
3156 if(stackParms == 1) {
3157 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
3159 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3160 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3162 if(STACK_MODEL_LARGE) {
3164 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3169 gpsimDebug_StackDump(__FILE__, __LINE__, fname);
3172 /* adjust the stack for parameters if required */
3173 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3176 /* if register bank was saved then pop them */
3178 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3180 /* if we hade saved some registers then unsave them */
3181 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3182 unsaveRegisters (ic);
3188 /*-----------------------------------------------------------------*/
3189 /* genPcall - generates a call by pointer statement */
3190 /* new version, created from genCall - HJD */
3191 /*-----------------------------------------------------------------*/
3192 static void genPcall (iCode *ic)
3196 symbol *retlbl = newiTempLabel(NULL);
3197 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
3200 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3202 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3204 /* if send set is not empty the assign */
3207 int psuedoStkPtr=-1;
3208 int firstTimeThruLoop = 1;
3210 /* For the Pic port, there is no data stack.
3211 * So parameters passed to functions are stored
3212 * in registers. (The pCode optimizer will get
3213 * rid of most of these :). */
3217 /* reverse sendSet if function is not reentrant */
3218 if(!IFFUNC_ISREENT(ftype))
3219 _G.sendSet = reverseSet(_G.sendSet);
3222 /* First figure how many parameters are getting passed */
3224 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3225 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3226 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
3227 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
3231 // stackParms = psuedoStkPtr;
3234 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3235 int size, offset = 0;
3237 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3238 size = AOP_SIZE(IC_LEFT(sic));
3242 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3243 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3244 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3246 if(!firstTimeThruLoop) {
3247 /* If this is not the first time we've been through the loop
3248 * then we need to save the parameter in a temporary
3249 * register. The last byte of the last parameter is
3253 --psuedoStkPtr; // sanity check
3256 firstTimeThruLoop=0;
3258 mov2w (AOP(IC_LEFT(sic)), size);
3264 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3267 if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
3268 else use_wreg = 1; /* last parameter in WREG */
3270 _G.stackRegSet = _G.sendSet;
3274 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3276 // push return address
3277 // push $ on return stack, then replace with retlbl
3279 pic16_emitpcodeNULLop(POC_PUSH);
3281 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
3282 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
3283 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
3284 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
3285 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
3286 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
3288 /* make the call by writing the pointer into pc */
3289 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
3290 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
3292 // note: MOVFF to PCL not allowed
3293 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
3294 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
3297 /* return address is here: (X) */
3298 pic16_emitpLabelFORCE(retlbl->key);
3300 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3303 /* if we need assign a result value */
3304 if ((IS_ITEMP(IC_RESULT(ic))
3305 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3306 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3307 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3310 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3313 assignResultValue(IC_RESULT(ic), 1);
3315 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3316 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3318 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3321 stackParms -= use_wreg;
3324 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3325 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3326 if(STACK_MODEL_LARGE) {
3327 /* this implies that stackParms < 256 !!! -- VR */
3329 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3334 /*-----------------------------------------------------------------*/
3335 /* resultRemat - result is rematerializable */
3336 /*-----------------------------------------------------------------*/
3337 static int resultRemat (iCode *ic)
3339 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3340 if (SKIP_IC(ic) || ic->op == IFX)
3343 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3344 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3345 if (sym->remat && !POINTER_SET(ic))
3352 #if defined(__BORLANDC__) || defined(_MSC_VER)
3353 #define STRCASECMP stricmp
3355 #define STRCASECMP strcasecmp
3359 /*-----------------------------------------------------------------*/
3360 /* inExcludeList - return 1 if the string is in exclude Reg list */
3361 /*-----------------------------------------------------------------*/
3362 static bool inExcludeList(char *s)
3364 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3367 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3368 if (options.excludeRegs[i] &&
3369 STRCASECMP(options.excludeRegs[i],"none") == 0)
3372 for ( i = 0 ; options.excludeRegs[i]; i++) {
3373 if (options.excludeRegs[i] &&
3374 STRCASECMP(s,options.excludeRegs[i]) == 0)
3381 /*-----------------------------------------------------------------*/
3382 /* genFunction - generated code for function entry */
3383 /*-----------------------------------------------------------------*/
3384 static void genFunction (iCode *ic)
3389 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
3391 pic16_labelOffset += (max_key+4);
3396 ftype = operandType(IC_LEFT(ic));
3397 sym = OP_SYMBOL(IC_LEFT(ic));
3399 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3400 /* create an absolute section at the interrupt vector:
3401 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3409 sym = OP_SYMBOL( IC_LEFT(ic));
3411 if(interrupts[i]->name
3412 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3419 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3420 __FILE__, __LINE__, sym->name);
3423 _G.interruptvector = found;
3426 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3427 asym = newSymbol(asymname, 0);
3429 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3430 pic16_addpBlock( apb );
3432 pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
3433 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3434 pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3436 /* mark the end of this tiny function */
3437 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3442 abSym = Safe_calloc(1, sizeof(absSym));
3443 strcpy(abSym->name, asymname);
3445 switch( _G.interruptvector ) {
3446 case 0: abSym->address = 0x000000; break;
3447 case 1: abSym->address = 0x000008; break;
3448 case 2: abSym->address = 0x000018; break;
3451 /* relocate interrupt vectors if needed */
3452 abSym->address += pic16_options.ivt_loc;
3454 addSet(&absSymSet, abSym);
3458 /* create the function header */
3459 pic16_emitcode(";","-----------------------------------------");
3460 pic16_emitcode(";"," function %s",sym->name);
3461 pic16_emitcode(";","-----------------------------------------");
3463 pic16_emitcode("","%s:",sym->rname);
3464 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3470 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) {
3471 if(!strcmp(ab->name, sym->rname)) {
3472 pic16_pBlockConvert2Absolute(pb);
3479 if(IFFUNC_ISNAKED(ftype)) {
3480 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3484 /* if critical function then turn interrupts off */
3485 if (IFFUNC_ISCRITICAL(ftype)) {
3486 //pic16_emitcode("clr","ea");
3489 _G.fregsUsed = sym->regsUsed;
3491 /* if this is an interrupt service routine then
3492 * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
3493 if (IFFUNC_ISISR(sym->type)) {
3494 _G.usefastretfie = 1; /* use shadow registers by default */
3496 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3497 if(!(_G.interruptvector == 1)) {
3498 /* do not save WREG,STATUS,BSR for high priority interrupts
3499 * because they are stored in the hardware shadow registers already */
3500 _G.usefastretfie = 0;
3501 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3502 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3503 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3506 /* these should really be optimized somehow, because not all
3507 * interrupt handlers modify them */
3508 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3509 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3510 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3511 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3513 // pic16_pBlockConvert2ISR(pb);
3517 /* emit code to setup stack frame if user enabled,
3518 * and function is not main() */
3520 //fprintf(stderr, "function name: %s\n", sym->name);
3521 if(strcmp(sym->name, "main")) {
3522 if(1 /*!options.ommitFramePtr || sym->regsUsed*/) {
3523 /* setup the stack frame */
3524 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3525 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3526 if(STACK_MODEL_LARGE)
3527 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3531 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3534 if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
3536 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3537 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3539 pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
3542 if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
3544 else _G.useWreg = 1;
3546 /* if callee-save to be used for this function
3547 * then save the registers being used in this function */
3548 // if (IFFUNC_CALLEESAVES(sym->type))
3552 /* if any registers used */
3553 if (sym->regsUsed) {
3554 /* save the registers used */
3555 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3556 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
3557 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3558 if (bitVectBitValue(sym->regsUsed,i)) {
3559 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3562 if(!pic16_regWithIdx(i)->wasUsed) {
3563 fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
3564 __FILE__, __LINE__, pic16_regWithIdx(i)->name);
3565 pic16_regWithIdx(i)->wasUsed = 1;
3569 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
3573 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3574 // fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
3577 /*-----------------------------------------------------------------*/
3578 /* genEndFunction - generates epilogue for functions */
3579 /*-----------------------------------------------------------------*/
3580 static void genEndFunction (iCode *ic)
3582 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3584 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3586 if(IFFUNC_ISNAKED(sym->type)) {
3587 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3593 /* add code for ISCRITICAL */
3594 if(IFFUNC_ISCRITICAL(sym->type)) {
3595 /* if critical function, turn on interrupts */
3597 /* TODO: add code here -- VR */
3600 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3602 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3603 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3605 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
3608 /* now we need to restore the registers */
3609 /* if any registers used */
3610 if (sym->regsUsed) {
3613 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
3614 /* restore registers used */
3615 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3616 for ( i = sym->regsUsed->size; i >= 0; i--) {
3617 if (bitVectBitValue(sym->regsUsed,i)) {
3618 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3622 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
3626 if(strcmp(sym->name, "main")) {
3627 if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
3628 /* restore stack frame */
3629 if(STACK_MODEL_LARGE)
3630 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3631 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3637 if (IFFUNC_ISISR(sym->type)) {
3638 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3639 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3640 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3641 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3643 if(!(_G.interruptvector == 1)) {
3644 /* do not restore interrupt vector for WREG,STATUS,BSR
3645 * for high priority interrupt, see genFunction */
3646 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3647 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3648 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3650 _G.interruptvector = 0; /* sanity check */
3653 /* if debug then send end of function */
3654 /* if (options.debug && currFunc) */
3656 debugFile->writeEndFunction (currFunc, ic, 1);
3659 if(_G.usefastretfie)
3660 pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
3662 pic16_emitpcodeNULLop(POC_RETFIE);
3664 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3666 _G.usefastretfie = 0;
3670 if (IFFUNC_ISCRITICAL(sym->type)) {
3671 pic16_emitcode("setb","ea");
3674 /* if debug then send end of function */
3676 debugFile->writeEndFunction (currFunc, ic, 1);
3679 /* insert code to restore stack frame, if user enabled it
3680 * and function is not main() */
3683 pic16_emitpcodeNULLop(POC_RETURN);
3685 /* Mark the end of a function */
3686 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3690 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3693 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
3694 if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
3696 if(dest->type == PO_WREG && (offset == 0)) {
3697 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3700 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
3704 /*-----------------------------------------------------------------*/
3705 /* genRet - generate code for return statement */
3706 /*-----------------------------------------------------------------*/
3707 static void genRet (iCode *ic)
3712 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3713 /* if we have no return value then
3714 * just generate the "ret" */
3719 /* we have something to return then
3720 * move the return value into place */
3721 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3722 size = AOP_SIZE(IC_LEFT(ic));
3726 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3727 // pic16_emitpcode(POC_MOVFF,
3728 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3731 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3732 // pic16_emitpcode(POC_MOVFF,
3733 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3736 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3737 // pic16_emitpcode(POC_MOVFF,
3738 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3741 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3743 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3744 // pic16_emitpcode(POC_MOVFF,
3745 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3748 /* >32-bits, setup stack and FSR0 */
3750 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3751 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3753 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3755 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3760 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3761 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3763 if(STACK_MODEL_LARGE) {
3764 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3765 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3767 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3772 /* old code, left here for reference -- VR */
3776 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3778 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3779 pic16_emitpcomment("push %s",l);
3782 DEBUGpic16_emitcode(";", "%d", __LINE__);
3783 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3784 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3786 if (strcmp(fReturn[offset],l)) {
3787 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3788 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3789 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3791 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3795 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3805 if (strcmp(fReturn[pushed],"a"))
3806 pic16_emitcode("pop",fReturn[pushed]);
3808 pic16_emitcode("pop","acc");
3814 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3817 /* generate a jump to the return label
3818 * if the next is not the return statement */
3819 if (!(ic->next && ic->next->op == LABEL
3820 && IC_LABEL(ic->next) == returnLabel)) {
3822 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3823 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
3827 /*-----------------------------------------------------------------*/
3828 /* genLabel - generates a label */
3829 /*-----------------------------------------------------------------*/
3830 static void genLabel (iCode *ic)
3834 /* special case never generate */
3835 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3836 if (IC_LABEL(ic) == entryLabel)
3839 pic16_emitpLabel(IC_LABEL(ic)->key);
3840 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset));
3843 /*-----------------------------------------------------------------*/
3844 /* genGoto - generates a goto */
3845 /*-----------------------------------------------------------------*/
3847 static void genGoto (iCode *ic)
3849 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3850 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset);
3854 /*-----------------------------------------------------------------*/
3855 /* genMultbits :- multiplication of bits */
3856 /*-----------------------------------------------------------------*/
3857 static void genMultbits (operand *left,
3861 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3863 if(!pic16_sameRegs(AOP(result),AOP(right)))
3864 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3866 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3867 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3868 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3873 /*-----------------------------------------------------------------*/
3874 /* genMultOneByte : 8 bit multiplication & division */
3875 /*-----------------------------------------------------------------*/
3876 static void genMultOneByte (operand *left,
3881 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3882 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3883 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3885 /* (if two literals, the value is computed before) */
3886 /* if one literal, literal on the right */
3887 if (AOP_TYPE(left) == AOP_LIT){
3893 /* size is already checked in genMult == 1 */
3894 // size = AOP_SIZE(result);
3896 if (AOP_TYPE(right) == AOP_LIT){
3897 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3898 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3899 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3900 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3902 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3903 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3904 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3905 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3908 pic16_genMult8X8_8 (left, right,result);
3911 /*-----------------------------------------------------------------*/
3912 /* genMultOneWord : 16 bit multiplication */
3913 /*-----------------------------------------------------------------*/
3914 static void genMultOneWord (operand *left,
3919 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3920 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3921 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3923 /* (if two literals, the value is computed before)
3924 * if one literal, literal on the right */
3925 if (AOP_TYPE(left) == AOP_LIT){
3931 /* size is checked already == 2 */
3932 // size = AOP_SIZE(result);
3934 if (AOP_TYPE(right) == AOP_LIT) {
3935 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3936 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3937 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3938 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3940 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3941 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3942 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3943 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3946 pic16_genMult16X16_16(left, right,result);
3949 /*-----------------------------------------------------------------*/
3950 /* genMultOneLong : 32 bit multiplication */
3951 /*-----------------------------------------------------------------*/
3952 static void genMultOneLong (operand *left,
3957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3958 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3959 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3961 /* (if two literals, the value is computed before)
3962 * if one literal, literal on the right */
3963 if (AOP_TYPE(left) == AOP_LIT){
3969 /* size is checked already == 4 */
3970 // size = AOP_SIZE(result);
3972 if (AOP_TYPE(right) == AOP_LIT) {
3973 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3974 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3975 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3976 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3978 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3979 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3980 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3981 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3984 pic16_genMult32X32_32(left, right,result);
3989 /*-----------------------------------------------------------------*/
3990 /* genMult - generates code for multiplication */
3991 /*-----------------------------------------------------------------*/
3992 static void genMult (iCode *ic)
3994 operand *left = IC_LEFT(ic);
3995 operand *right = IC_RIGHT(ic);
3996 operand *result= IC_RESULT(ic);
3998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3999 /* assign the amsops */
4000 pic16_aopOp (left,ic,FALSE);
4001 pic16_aopOp (right,ic,FALSE);
4002 pic16_aopOp (result,ic,TRUE);
4004 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4006 /* special cases first *
4008 if (AOP_TYPE(left) == AOP_CRY
4009 && AOP_TYPE(right)== AOP_CRY) {
4010 genMultbits(left,right,result);
4014 /* if both are of size == 1 */
4015 if(AOP_SIZE(left) == 1
4016 && AOP_SIZE(right) == 1) {
4017 genMultOneByte(left,right,result);
4021 /* if both are of size == 2 */
4022 if(AOP_SIZE(left) == 2
4023 && AOP_SIZE(right) == 2) {
4024 genMultOneWord(left, right, result);
4028 /* if both are of size == 4 */
4029 if(AOP_SIZE(left) == 4
4030 && AOP_SIZE(right) == 4) {
4031 genMultOneLong(left, right, result);
4035 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
4038 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
4039 /* should have been converted to function call */
4043 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4044 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4045 pic16_freeAsmop(result,NULL,ic,TRUE);
4048 /*-----------------------------------------------------------------*/
4049 /* genDivbits :- division of bits */
4050 /*-----------------------------------------------------------------*/
4051 static void genDivbits (operand *left,
4058 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4059 /* the result must be bit */
4060 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4061 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4065 pic16_emitcode("div","ab");
4066 pic16_emitcode("rrc","a");
4067 pic16_aopPut(AOP(result),"c",0);
4070 /*-----------------------------------------------------------------*/
4071 /* genDivOneByte : 8 bit division */
4072 /*-----------------------------------------------------------------*/
4073 static void genDivOneByte (operand *left,
4077 sym_link *opetype = operandType(result);
4082 /* result = divident / divisor
4083 * - divident may be a register or a literal,
4084 * - divisor may be a register or a literal,
4085 * so there are 3 cases (literal / literal is optimized
4086 * by the front-end) to handle.
4087 * In addition we must handle signed and unsigned, which
4088 * result in 6 final different cases -- VR */
4090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4091 size = AOP_SIZE(result) - 1;
4093 /* signed or unsigned */
4094 if (SPEC_USIGN(opetype)) {
4095 pCodeOp *pct1, /* count */
4098 symbol *label1, *label2, *label3;;
4101 /* unsigned is easy */
4103 pct1 = pic16_popGetTempReg(1);
4104 pct2 = pic16_popGetTempReg(1);
4105 pct3 = pic16_popGetTempReg(1);
4107 label1 = newiTempLabel(NULL);
4108 label2 = newiTempLabel(NULL);
4109 label3 = newiTempLabel(NULL);
4111 /* the following algorithm is extracted from divuint.c */
4113 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
4114 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
4116 pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
4118 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
4120 pic16_emitpLabel(label1->key);
4123 pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
4127 pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
4131 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
4133 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
4134 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
4136 pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
4137 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
4138 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
4140 pic16_emitpLabel( label3->key );
4141 pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
4142 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
4146 pic16_emitpLabel(label2->key);
4147 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
4148 pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
4149 pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
4151 /* result is in wreg */
4152 if(AOP_TYPE(result) != AOP_ACC)
4153 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
4155 pic16_popReleaseTempReg( pct3, 1);
4156 pic16_popReleaseTempReg( pct2, 1);
4157 pic16_popReleaseTempReg( pct1, 1);
4162 /* signed is a little bit more difficult */
4164 /* save the signs of the operands */
4165 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4167 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4168 pic16_emitcode("push","acc"); /* save it on the stack */
4170 /* now sign adjust for both left & right */
4171 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4173 lbl = newiTempLabel(NULL);
4174 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4175 pic16_emitcode("cpl","a");
4176 pic16_emitcode("inc","a");
4177 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4178 pic16_emitcode("mov","b,a");
4180 /* sign adjust left side */
4181 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4184 lbl = newiTempLabel(NULL);
4185 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4186 pic16_emitcode("cpl","a");
4187 pic16_emitcode("inc","a");
4188 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4190 /* now the division */
4191 pic16_emitcode("div","ab");
4192 /* we are interested in the lower order
4194 pic16_emitcode("mov","b,a");
4195 lbl = newiTempLabel(NULL);
4196 pic16_emitcode("pop","acc");
4197 /* if there was an over flow we don't
4198 adjust the sign of the result */
4199 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4200 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4202 pic16_emitcode("clr","a");
4203 pic16_emitcode("subb","a,b");
4204 pic16_emitcode("mov","b,a");
4205 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4207 /* now we are done */
4208 pic16_aopPut(AOP(result),"b",0);
4210 pic16_emitcode("mov","c,b.7");
4211 pic16_emitcode("subb","a,acc");
4214 pic16_aopPut(AOP(result),"a",offset++);
4218 /*-----------------------------------------------------------------*/
4219 /* genDiv - generates code for division */
4220 /*-----------------------------------------------------------------*/
4221 static void genDiv (iCode *ic)
4223 operand *left = IC_LEFT(ic);
4224 operand *right = IC_RIGHT(ic);
4225 operand *result= IC_RESULT(ic);
4228 /* Division is a very lengthy algorithm, so it is better
4229 * to call support routines than inlining algorithm.
4230 * Division functions written here just in case someone
4231 * wants to inline and not use the support libraries -- VR */
4233 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4234 /* assign the amsops */
4235 pic16_aopOp (left,ic,FALSE);
4236 pic16_aopOp (right,ic,FALSE);
4237 pic16_aopOp (result,ic,TRUE);
4239 /* special cases first */
4241 if (AOP_TYPE(left) == AOP_CRY &&
4242 AOP_TYPE(right)== AOP_CRY) {
4243 genDivbits(left,right,result);
4247 /* if both are of size == 1 */
4248 if (AOP_SIZE(left) == 1 &&
4249 AOP_SIZE(right) == 1 ) {
4250 genDivOneByte(left,right,result);
4254 /* should have been converted to function call */
4257 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4258 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4259 pic16_freeAsmop(result,NULL,ic,TRUE);
4262 /*-----------------------------------------------------------------*/
4263 /* genModbits :- modulus of bits */
4264 /*-----------------------------------------------------------------*/
4265 static void genModbits (operand *left,
4272 /* the result must be bit */
4273 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4274 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4278 pic16_emitcode("div","ab");
4279 pic16_emitcode("mov","a,b");
4280 pic16_emitcode("rrc","a");
4281 pic16_aopPut(AOP(result),"c",0);
4284 /*-----------------------------------------------------------------*/
4285 /* genModOneByte : 8 bit modulus */
4286 /*-----------------------------------------------------------------*/
4287 static void genModOneByte (operand *left,
4291 sym_link *opetype = operandType(result);
4295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4296 /* signed or unsigned */
4297 if (SPEC_USIGN(opetype)) {
4298 /* unsigned is easy */
4299 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4300 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4302 pic16_emitcode("div","ab");
4303 pic16_aopPut(AOP(result),"b",0);
4307 /* signed is a little bit more difficult */
4309 /* save the signs of the operands */
4310 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4313 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4314 pic16_emitcode("push","acc"); /* save it on the stack */
4316 /* now sign adjust for both left & right */
4317 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4320 lbl = newiTempLabel(NULL);
4321 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4322 pic16_emitcode("cpl","a");
4323 pic16_emitcode("inc","a");
4324 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4325 pic16_emitcode("mov","b,a");
4327 /* sign adjust left side */
4328 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4331 lbl = newiTempLabel(NULL);
4332 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4333 pic16_emitcode("cpl","a");
4334 pic16_emitcode("inc","a");
4335 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4337 /* now the multiplication */
4338 pic16_emitcode("div","ab");
4339 /* we are interested in the lower order
4341 lbl = newiTempLabel(NULL);
4342 pic16_emitcode("pop","acc");
4343 /* if there was an over flow we don't
4344 adjust the sign of the result */
4345 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4346 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4348 pic16_emitcode("clr","a");
4349 pic16_emitcode("subb","a,b");
4350 pic16_emitcode("mov","b,a");
4351 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4353 /* now we are done */
4354 pic16_aopPut(AOP(result),"b",0);
4358 /*-----------------------------------------------------------------*/
4359 /* genMod - generates code for division */
4360 /*-----------------------------------------------------------------*/
4361 static void genMod (iCode *ic)
4363 operand *left = IC_LEFT(ic);
4364 operand *right = IC_RIGHT(ic);
4365 operand *result= IC_RESULT(ic);
4367 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4368 /* assign the amsops */
4369 pic16_aopOp (left,ic,FALSE);
4370 pic16_aopOp (right,ic,FALSE);
4371 pic16_aopOp (result,ic,TRUE);
4373 /* special cases first */
4375 if (AOP_TYPE(left) == AOP_CRY &&
4376 AOP_TYPE(right)== AOP_CRY) {
4377 genModbits(left,right,result);
4381 /* if both are of size == 1 */
4382 if (AOP_SIZE(left) == 1 &&
4383 AOP_SIZE(right) == 1 ) {
4384 genModOneByte(left,right,result);
4388 /* should have been converted to function call */
4392 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4393 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4394 pic16_freeAsmop(result,NULL,ic,TRUE);
4397 /*-----------------------------------------------------------------*/
4398 /* genIfxJump :- will create a jump depending on the ifx */
4399 /*-----------------------------------------------------------------*/
4401 note: May need to add parameter to indicate when a variable is in bit space.
4403 static void genIfxJump (iCode *ic, char *jval)
4406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4407 /* if true label then we jump if condition
4409 if ( IC_TRUE(ic) ) {
4411 if(strcmp(jval,"a") == 0)
4413 else if (strcmp(jval,"c") == 0)
4416 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4417 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4420 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4421 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
4425 /* false label is present */
4426 if(strcmp(jval,"a") == 0)
4428 else if (strcmp(jval,"c") == 0)
4431 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4432 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4435 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4436 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
4441 /* mark the icode as generated */
4448 /*-----------------------------------------------------------------*/
4450 /*-----------------------------------------------------------------*/
4451 static void genSkip(iCode *ifx,int status_bit)
4453 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4457 if ( IC_TRUE(ifx) ) {
4458 switch(status_bit) {
4473 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4474 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4478 switch(status_bit) {
4492 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4493 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4500 /*-----------------------------------------------------------------*/
4502 /*-----------------------------------------------------------------*/
4503 static void genSkipc(resolvedIfx *rifx)
4505 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4515 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4516 rifx->generated = 1;
4519 /*-----------------------------------------------------------------*/
4521 /*-----------------------------------------------------------------*/
4522 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4524 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4529 if( (rifx->condition ^ invert_condition) & 1)
4534 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4535 rifx->generated = 1;
4539 /*-----------------------------------------------------------------*/
4541 /*-----------------------------------------------------------------*/
4542 static void genSkipz(iCode *ifx, int condition)
4553 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4555 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4558 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4560 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4565 /*-----------------------------------------------------------------*/
4567 /*-----------------------------------------------------------------*/
4568 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4574 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4576 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4579 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4580 rifx->generated = 1;
4584 /*-----------------------------------------------------------------*/
4585 /* genChkZeroes :- greater or less than comparison */
4586 /* For each byte in a literal that is zero, inclusive or the */
4587 /* the corresponding byte in the operand with W */
4588 /* returns true if any of the bytes are zero */
4589 /*-----------------------------------------------------------------*/
4590 static int genChkZeroes(operand *op, int lit, int size)
4597 i = (lit >> (size*8)) & 0xff;
4601 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4603 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4612 /*-----------------------------------------------------------------*/
4613 /* genCmp :- greater or less than comparison */
4614 /*-----------------------------------------------------------------*/
4616 static void genCmp (operand *left,operand *right,
4617 operand *result, iCode *ifx, int sign)
4619 int size; //, offset = 0 ;
4620 unsigned long lit = 0L,i = 0;
4621 resolvedIfx rFalseIfx;
4622 // resolvedIfx rTrueIfx;
4624 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4627 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4628 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4632 resolveIfx(&rFalseIfx,ifx);
4633 truelbl = newiTempLabel(NULL);
4634 size = max(AOP_SIZE(left),AOP_SIZE(right));
4636 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4640 /* if literal is on the right then swap with left */
4641 if ((AOP_TYPE(right) == AOP_LIT)) {
4642 operand *tmp = right ;
4643 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4644 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4647 lit = (lit - 1) & mask;
4650 rFalseIfx.condition ^= 1;
4653 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4654 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4658 //if(IC_TRUE(ifx) == NULL)
4659 /* if left & right are bit variables */
4660 if (AOP_TYPE(left) == AOP_CRY &&
4661 AOP_TYPE(right) == AOP_CRY ) {
4662 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4663 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4665 /* subtract right from left if at the
4666 end the carry flag is set then we know that
4667 left is greater than right */
4669 symbol *lbl = newiTempLabel(NULL);
4672 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4673 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
4677 if(AOP_TYPE(right) == AOP_LIT) {
4679 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4681 DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
4688 genSkipCond(&rFalseIfx,left,size-1,7);
4690 /* no need to compare to 0...*/
4691 /* NOTE: this is a de-generate compare that most certainly
4692 * creates some dead code. */
4693 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4695 if(ifx) ifx->generated = 1;
4702 //i = (lit >> (size*8)) & 0xff;
4703 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4705 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4707 i = ((0-lit) & 0xff);
4710 /* lit is 0x7f, all signed chars are less than
4711 * this except for 0x7f itself */
4712 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4713 genSkipz2(&rFalseIfx,0);
4715 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4716 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4717 genSkipc(&rFalseIfx);
4722 genSkipz2(&rFalseIfx,1);
4724 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4725 genSkipc(&rFalseIfx);
4729 if(ifx) ifx->generated = 1;
4733 /* chars are out of the way. now do ints and longs */
4736 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4743 genSkipCond(&rFalseIfx,left,size,7);
4744 if(ifx) ifx->generated = 1;
4749 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4751 //rFalseIfx.condition ^= 1;
4752 //genSkipCond(&rFalseIfx,left,size,7);
4753 //rFalseIfx.condition ^= 1;
4755 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4756 if(rFalseIfx.condition)
4757 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4759 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4761 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4762 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4763 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4766 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4768 if(rFalseIfx.condition) {
4770 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4776 genSkipc(&rFalseIfx);
4777 pic16_emitpLabel(truelbl->key);
4778 if(ifx) ifx->generated = 1;
4785 if( (lit & 0xff) == 0) {
4786 /* lower byte is zero */
4787 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4788 i = ((lit >> 8) & 0xff) ^0x80;
4789 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4790 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4791 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4792 genSkipc(&rFalseIfx);
4795 if(ifx) ifx->generated = 1;
4800 /* Special cases for signed longs */
4801 if( (lit & 0xffffff) == 0) {
4802 /* lower byte is zero */
4803 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4804 i = ((lit >> 8*3) & 0xff) ^0x80;
4805 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4806 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4807 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4808 genSkipc(&rFalseIfx);
4811 if(ifx) ifx->generated = 1;
4819 if(lit & (0x80 << (size*8))) {
4820 /* lit is negative */
4821 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4823 //genSkipCond(&rFalseIfx,left,size,7);
4825 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4827 if(rFalseIfx.condition)
4828 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4830 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4834 /* lit is positive */
4835 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4836 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4837 if(rFalseIfx.condition)
4838 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4840 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4845 This works, but is only good for ints.
4846 It also requires a "known zero" register.
4847 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4848 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4849 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4850 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4851 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4852 genSkipc(&rFalseIfx);
4854 pic16_emitpLabel(truelbl->key);
4855 if(ifx) ifx->generated = 1;
4859 /* There are no more special cases, so perform a general compare */
4861 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4862 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4866 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4868 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4870 //rFalseIfx.condition ^= 1;
4871 genSkipc(&rFalseIfx);
4873 pic16_emitpLabel(truelbl->key);
4875 if(ifx) ifx->generated = 1;
4882 /* sign is out of the way. So now do an unsigned compare */
4883 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4886 /* General case - compare to an unsigned literal on the right.*/
4888 i = (lit >> (size*8)) & 0xff;
4889 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4890 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4892 i = (lit >> (size*8)) & 0xff;
4895 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4897 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4899 /* this byte of the lit is zero,
4900 *if it's not the last then OR in the variable */
4902 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4907 pic16_emitpLabel(lbl->key);
4908 // pic16_emitpLabel(truelbl->key);
4909 //if(emitFinalCheck)
4910 genSkipc(&rFalseIfx);
4912 pic16_emitpLabel(truelbl->key);
4914 if(ifx) ifx->generated = 1;
4921 if(AOP_TYPE(left) == AOP_LIT) {
4922 //symbol *lbl = newiTempLabel(NULL);
4924 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4927 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4930 if((lit == 0) && (sign == 0)){
4933 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4935 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4937 genSkipz2(&rFalseIfx,0);
4938 if(ifx) ifx->generated = 1;
4945 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4946 /* degenerate compare can never be true */
4947 if(rFalseIfx.condition == 0)
4948 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4950 if(ifx) ifx->generated = 1;
4955 /* signed comparisons to a literal byte */
4957 int lp1 = (lit+1) & 0xff;
4959 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4962 rFalseIfx.condition ^= 1;
4963 genSkipCond(&rFalseIfx,right,0,7);
4966 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4967 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4968 genSkipz2(&rFalseIfx,1);
4971 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4972 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4973 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4974 rFalseIfx.condition ^= 1;
4975 genSkipc(&rFalseIfx);
4979 /* unsigned comparisons to a literal byte */
4981 switch(lit & 0xff ) {
4983 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4984 genSkipz2(&rFalseIfx,0);
4987 rFalseIfx.condition ^= 1;
4988 genSkipCond(&rFalseIfx,right,0,7);
4992 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4993 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4994 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4995 rFalseIfx.condition ^= 1;
4996 if (AOP_TYPE(result) == AOP_CRY)
4997 genSkipc(&rFalseIfx);
4999 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5000 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5006 if(ifx) ifx->generated = 1;
5007 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5013 /* Size is greater than 1 */
5021 /* this means lit = 0xffffffff, or -1 */
5024 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5025 rFalseIfx.condition ^= 1;
5026 genSkipCond(&rFalseIfx,right,size,7);
5027 if(ifx) ifx->generated = 1;
5029 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5038 if(rFalseIfx.condition) {
5039 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5040 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5043 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5045 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5049 if(rFalseIfx.condition) {
5050 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5051 pic16_emitpLabel(truelbl->key);
5053 rFalseIfx.condition ^= 1;
5054 genSkipCond(&rFalseIfx,right,s,7);
5057 if(ifx) ifx->generated = 1;
5059 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5065 if((size == 1) && (0 == (lp1&0xff))) {
5066 /* lower byte of signed word is zero */
5067 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5068 i = ((lp1 >> 8) & 0xff) ^0x80;
5069 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5070 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5071 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5072 rFalseIfx.condition ^= 1;
5073 genSkipc(&rFalseIfx);
5076 if(ifx) ifx->generated = 1;
5078 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5084 if(lit & (0x80 << (size*8))) {
5085 /* Lit is less than zero */
5086 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5087 //rFalseIfx.condition ^= 1;
5088 //genSkipCond(&rFalseIfx,left,size,7);
5089 //rFalseIfx.condition ^= 1;
5090 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5091 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5093 if(rFalseIfx.condition)
5094 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5096 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5100 /* Lit is greater than or equal to zero */
5101 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5102 //rFalseIfx.condition ^= 1;
5103 //genSkipCond(&rFalseIfx,right,size,7);
5104 //rFalseIfx.condition ^= 1;
5106 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5107 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5109 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5110 if(rFalseIfx.condition)
5111 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5113 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5118 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5119 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5123 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5125 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5127 rFalseIfx.condition ^= 1;
5128 //rFalseIfx.condition = 1;
5129 genSkipc(&rFalseIfx);
5131 pic16_emitpLabel(truelbl->key);
5133 if(ifx) ifx->generated = 1;
5136 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5143 /* compare word or long to an unsigned literal on the right.*/
5148 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5151 break; /* handled above */
5154 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5156 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5157 genSkipz2(&rFalseIfx,0);
5161 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5163 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5166 if(rFalseIfx.condition)
5167 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5169 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5172 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5173 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5175 rFalseIfx.condition ^= 1;
5176 genSkipc(&rFalseIfx);
5179 pic16_emitpLabel(truelbl->key);
5181 if(ifx) ifx->generated = 1;
5183 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5191 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5192 i = (lit >> (size*8)) & 0xff;
5194 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5195 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5198 i = (lit >> (size*8)) & 0xff;
5201 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5203 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5205 /* this byte of the lit is zero,
5206 * if it's not the last then OR in the variable */
5208 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5213 pic16_emitpLabel(lbl->key);
5215 rFalseIfx.condition ^= 1;
5217 genSkipc(&rFalseIfx);
5221 pic16_emitpLabel(truelbl->key);
5222 if(ifx) ifx->generated = 1;
5224 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5230 /* Compare two variables */
5232 DEBUGpic16_emitcode(";sign","%d",sign);
5236 /* Sigh. thus sucks... */
5240 pctemp = pic16_popGetTempReg(1);
5241 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5242 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5243 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5244 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5245 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5246 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5247 pic16_popReleaseTempReg(pctemp, 1);
5249 /* Signed char comparison */
5250 /* Special thanks to Nikolai Golovchenko for this snippet */
5251 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5252 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5253 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5254 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5255 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5256 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5259 genSkipc(&rFalseIfx);
5261 if(ifx) ifx->generated = 1;
5263 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5271 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5272 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5276 /* The rest of the bytes of a multi-byte compare */
5280 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5283 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5284 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5289 pic16_emitpLabel(lbl->key);
5291 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5292 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5293 (AOP_TYPE(result) == AOP_REG)) {
5294 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5295 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5297 genSkipc(&rFalseIfx);
5299 //genSkipc(&rFalseIfx);
5300 if(ifx) ifx->generated = 1;
5303 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5311 if ((AOP_TYPE(result) != AOP_CRY)
5312 && AOP_SIZE(result)) {
5313 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5315 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5317 pic16_outBitC(result);
5319 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5320 /* if the result is used in the next
5321 ifx conditional branch then generate
5322 code a little differently */
5324 genIfxJump (ifx,"c");
5326 pic16_outBitC(result);
5327 /* leave the result in acc */
5332 #else /* old version of genCmp() */
5334 /* new version of genCmp -- VR 20041012 */
5335 static void genCmp (operand *left,operand *right,
5336 operand *result, iCode *ifx, int sign)
5338 int size; //, offset = 0 ;
5339 unsigned long lit = 0L,i = 0;
5340 resolvedIfx rFalseIfx;
5341 int willCheckCarry=0;
5342 // resolvedIfx rTrueIfx;
5344 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5348 * subtract right from left if at the end the carry flag is set then we
5349 * know that left is greater than right */
5351 resolveIfx(&rFalseIfx,ifx);
5352 truelbl = newiTempLabel(NULL);
5353 size = max(AOP_SIZE(left),AOP_SIZE(right));
5355 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5357 /* POC_CPFSGT compare f, wreg, skip if f greater than wreg
5358 * POC_CPFSLT compare f, wreg, skip if f less then wreg */
5361 /* if literal is on the right then swap with left */
5362 if ((AOP_TYPE(right) == AOP_LIT)) {
5363 operand *tmp = right ;
5364 unsigned long mask = (0x100 << (8*(size-1))) - 1;
5366 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5368 // lit = (lit - 1) & mask;
5371 rFalseIfx.condition ^= 1;
5373 if ((AOP_TYPE(left) == AOP_LIT)) {
5374 /* float compares are handled by support functions */
5375 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
5379 //if(IC_TRUE(ifx) == NULL)
5380 /* if left & right are bit variables */
5381 if (AOP_TYPE(left) == AOP_CRY &&
5382 AOP_TYPE(right) == AOP_CRY ) {
5383 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5384 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
5387 symbol *lbl = newiTempLabel(NULL);
5389 if(AOP_TYPE(left) == AOP_LIT) {
5390 DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
5392 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5394 else willCheckCarry = 0;
5397 if((lit == 0) && (sign == 0)){
5400 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5402 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
5404 genSkipz2(&rFalseIfx,0);
5405 if(ifx) ifx->generated = 1;
5412 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
5413 /* degenerate compare can never be true */
5414 if(rFalseIfx.condition == 0)
5415 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
5417 if(ifx) ifx->generated = 1;
5422 /* signed comparisons to a literal byte */
5424 int lp1 = (lit+1) & 0xff;
5426 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d",__LINE__,lit, rFalseIfx.condition);
5429 rFalseIfx.condition ^= 1;
5430 genSkipCond(&rFalseIfx,right,0,7);
5433 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5434 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5435 genSkipz2(&rFalseIfx,1);
5438 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
5440 if(rFalseIfx.condition)
5441 pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
5443 pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
5445 if(willCheckCarry) {
5446 if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
5447 else { emitSETC; emitCLRC; }
5450 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5453 /* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5454 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5455 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5456 rFalseIfx.condition ^= 1;
5457 genSkipc(&rFalseIfx);
5462 /* unsigned comparisons to a literal byte */
5464 switch(lit & 0xff ) {
5466 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5467 genSkipz2(&rFalseIfx,0);
5470 rFalseIfx.condition ^= 1;
5471 genSkipCond(&rFalseIfx,right,0,7);
5475 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5476 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5477 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5478 rFalseIfx.condition ^= 1;
5479 if (AOP_TYPE(result) == AOP_CRY)
5480 genSkipc(&rFalseIfx);
5482 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5483 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5489 if(ifx) ifx->generated = 1;
5490 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5496 /* Size is greater than 1 */
5504 /* this means lit = 0xffffffff, or -1 */
5507 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5508 rFalseIfx.condition ^= 1;
5509 genSkipCond(&rFalseIfx,right,size,7);
5510 if(ifx) ifx->generated = 1;
5517 if(rFalseIfx.condition) {
5518 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5519 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5522 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5524 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5528 if(rFalseIfx.condition) {
5529 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5530 pic16_emitpLabel(truelbl->key);
5532 rFalseIfx.condition ^= 1;
5533 genSkipCond(&rFalseIfx,right,s,7);
5536 if(ifx) ifx->generated = 1;
5540 if((size == 1) && (0 == (lp1&0xff))) {
5541 /* lower byte of signed word is zero */
5542 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5543 i = ((lp1 >> 8) & 0xff) ^0x80;
5544 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5545 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5546 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5547 rFalseIfx.condition ^= 1;
5548 genSkipc(&rFalseIfx);
5551 if(ifx) ifx->generated = 1;
5555 if(lit & (0x80 << (size*8))) {
5556 /* Lit is less than zero */
5557 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5558 //rFalseIfx.condition ^= 1;
5559 //genSkipCond(&rFalseIfx,left,size,7);
5560 //rFalseIfx.condition ^= 1;
5561 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5562 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5564 if(rFalseIfx.condition)
5565 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5567 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5571 /* Lit is greater than or equal to zero */
5572 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5573 //rFalseIfx.condition ^= 1;
5574 //genSkipCond(&rFalseIfx,right,size,7);
5575 //rFalseIfx.condition ^= 1;
5577 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5578 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5580 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5581 if(rFalseIfx.condition)
5582 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5584 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5589 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5590 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5594 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5596 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5598 rFalseIfx.condition ^= 1;
5599 //rFalseIfx.condition = 1;
5600 genSkipc(&rFalseIfx);
5602 pic16_emitpLabel(truelbl->key);
5604 if(ifx) ifx->generated = 1;
5609 /* compare word or long to an unsigned literal on the right.*/
5614 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5617 break; /* handled above */
5620 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5622 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5623 genSkipz2(&rFalseIfx,0);
5627 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5629 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5632 if(rFalseIfx.condition)
5633 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5635 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5638 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5639 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5641 rFalseIfx.condition ^= 1;
5642 genSkipc(&rFalseIfx);
5645 pic16_emitpLabel(truelbl->key);
5647 if(ifx) ifx->generated = 1;
5653 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5654 i = (lit >> (size*8)) & 0xff;
5656 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5657 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5660 i = (lit >> (size*8)) & 0xff;
5663 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5665 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5667 /* this byte of the lit is zero,
5668 * if it's not the last then OR in the variable */
5670 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5675 pic16_emitpLabel(lbl->key);
5677 rFalseIfx.condition ^= 1;
5679 genSkipc(&rFalseIfx);
5683 pic16_emitpLabel(truelbl->key);
5684 if(ifx) ifx->generated = 1;
5688 /* Compare two variables */
5690 DEBUGpic16_emitcode(";sign","%d",sign);
5694 /* Sigh. thus sucks... */
5698 pctemp = pic16_popGetTempReg(1);
5699 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5700 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5701 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5702 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5703 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5704 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5705 pic16_popReleaseTempReg(pctemp, 1);
5707 /* Signed char comparison */
5708 /* Special thanks to Nikolai Golovchenko for this snippet */
5709 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5710 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5711 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5712 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5713 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5714 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5716 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5717 genSkipc(&rFalseIfx);
5719 if(ifx) ifx->generated = 1;
5725 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5726 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5730 /* The rest of the bytes of a multi-byte compare */
5734 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5737 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5738 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5743 pic16_emitpLabel(lbl->key);
5745 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5746 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5747 (AOP_TYPE(result) == AOP_REG)) {
5748 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5749 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5751 genSkipc(&rFalseIfx);
5753 //genSkipc(&rFalseIfx);
5754 if(ifx) ifx->generated = 1;
5761 if ((AOP_TYPE(result) != AOP_CRY)
5762 && AOP_SIZE(result)) {
5763 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5765 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5767 pic16_outBitC(result);
5769 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5770 /* if the result is used in the next
5771 ifx conditional branch then generate
5772 code a little differently */
5774 genIfxJump (ifx,"c");
5776 pic16_outBitC(result);
5777 /* leave the result in acc */
5785 /*-----------------------------------------------------------------*/
5786 /* genCmpGt :- greater than comparison */
5787 /*-----------------------------------------------------------------*/
5788 static void genCmpGt (iCode *ic, iCode *ifx)
5790 operand *left, *right, *result;
5791 sym_link *letype , *retype;
5794 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5796 right= IC_RIGHT(ic);
5797 result = IC_RESULT(ic);
5799 letype = getSpec(operandType(left));
5800 retype =getSpec(operandType(right));
5801 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5802 /* assign the amsops */
5803 pic16_aopOp (left,ic,FALSE);
5804 pic16_aopOp (right,ic,FALSE);
5805 pic16_aopOp (result,ic,TRUE);
5807 genCmp(right, left, result, ifx, sign);
5809 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5810 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5811 pic16_freeAsmop(result,NULL,ic,TRUE);
5814 /*-----------------------------------------------------------------*/
5815 /* genCmpLt - less than comparisons */
5816 /*-----------------------------------------------------------------*/
5817 static void genCmpLt (iCode *ic, iCode *ifx)
5819 operand *left, *right, *result;
5820 sym_link *letype , *retype;
5823 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5825 right= IC_RIGHT(ic);
5826 result = IC_RESULT(ic);
5828 letype = getSpec(operandType(left));
5829 retype =getSpec(operandType(right));
5830 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5832 /* assign the amsops */
5833 pic16_aopOp (left,ic,FALSE);
5834 pic16_aopOp (right,ic,FALSE);
5835 pic16_aopOp (result,ic,TRUE);
5837 genCmp(left, right, result, ifx, sign);
5839 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5840 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5841 pic16_freeAsmop(result,NULL,ic,TRUE);
5846 // FIXME reenable literal optimisation when the pic16 port is stable
5848 /*-----------------------------------------------------------------*/
5849 /* genc16bit2lit - compare a 16 bit value to a literal */
5850 /*-----------------------------------------------------------------*/
5851 static void genc16bit2lit(operand *op, int lit, int offset)
5855 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5856 if( (lit&0xff) == 0)
5861 switch( BYTEofLONG(lit,i)) {
5863 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5866 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5869 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5872 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5873 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5878 switch( BYTEofLONG(lit,i)) {
5880 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5884 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5888 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5891 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5893 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5902 /*-----------------------------------------------------------------*/
5903 /* gencjneshort - compare and jump if not equal */
5904 /*-----------------------------------------------------------------*/
5905 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5907 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5909 int res_offset = 0; /* the result may be a different size then left or right */
5910 int res_size = AOP_SIZE(result);
5912 symbol *lbl, *lbl_done;
5914 unsigned long lit = 0L;
5915 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5917 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5918 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5920 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5921 resolveIfx(&rIfx,ifx);
5922 lbl = newiTempLabel(NULL);
5923 lbl_done = newiTempLabel(NULL);
5926 /* if the left side is a literal or
5927 if the right is in a pointer register and left
5929 if ((AOP_TYPE(left) == AOP_LIT) ||
5930 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5935 if(AOP_TYPE(right) == AOP_LIT)
5936 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5938 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5939 preserve_result = 1;
5941 if(result && !preserve_result)
5944 for(i = 0; i < AOP_SIZE(result); i++)
5945 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5949 /* if the right side is a literal then anything goes */
5950 if (AOP_TYPE(right) == AOP_LIT &&
5951 AOP_TYPE(left) != AOP_DIR ) {
5954 genc16bit2lit(left, lit, 0);
5956 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5959 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5962 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5963 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5965 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5969 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5971 if(res_offset < res_size-1)
5979 /* if the right side is in a register or in direct space or
5980 if the left is a pointer register & right is not */
5981 else if (AOP_TYPE(right) == AOP_REG ||
5982 AOP_TYPE(right) == AOP_DIR ||
5983 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5984 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5985 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5986 int lbl_key = lbl->key;
5989 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5990 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5992 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5993 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5994 __FUNCTION__,__LINE__);
5998 /* switch(size) { */
6000 /* genc16bit2lit(left, lit, 0); */
6002 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
6007 if((AOP_TYPE(left) == AOP_DIR) &&
6008 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
6010 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6011 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6013 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
6015 switch (lit & 0xff) {
6017 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6020 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6021 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6022 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6026 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6027 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6028 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6029 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6033 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6034 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6039 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6042 if(AOP_TYPE(result) == AOP_CRY) {
6043 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6048 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6050 /* fix me. probably need to check result size too */
6051 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
6056 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6057 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6064 if(res_offset < res_size-1)
6069 } else if(AOP_TYPE(right) == AOP_REG &&
6070 AOP_TYPE(left) != AOP_DIR){
6073 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6074 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6075 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6080 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6082 if(res_offset < res_size-1)
6087 /* right is a pointer reg need both a & b */
6089 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
6091 pic16_emitcode("mov","b,%s",l);
6092 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6093 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
6098 if(result && preserve_result)
6101 for(i = 0; i < AOP_SIZE(result); i++)
6102 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6105 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
6107 if(result && preserve_result)
6108 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
6111 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6113 pic16_emitpLabel(lbl->key);
6115 if(result && preserve_result)
6118 for(i = 0; i < AOP_SIZE(result); i++)
6119 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6121 pic16_emitpLabel(lbl_done->key);
6124 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6132 /*-----------------------------------------------------------------*/
6133 /* gencjne - compare and jump if not equal */
6134 /*-----------------------------------------------------------------*/
6135 static void gencjne(operand *left, operand *right, iCode *ifx)
6137 symbol *tlbl = newiTempLabel(NULL);
6139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6140 gencjneshort(left, right, lbl);
6142 pic16_emitcode("mov","a,%s",one);
6143 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
6144 pic16_emitcode("","%05d_DS_:",lbl->key+100);
6145 pic16_emitcode("clr","a");
6146 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6148 pic16_emitpLabel(lbl->key);
6149 pic16_emitpLabel(tlbl->key);
6155 /*-----------------------------------------------------------------*/
6156 /* is_LitOp - check if operand has to be treated as literal */
6157 /*-----------------------------------------------------------------*/
6158 static bool is_LitOp(operand *op)
6160 return (AOP_TYPE(op) == AOP_LIT)
6161 || ( (AOP_TYPE(op) == AOP_PCODE)
6162 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
6163 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
6166 /*-----------------------------------------------------------------*/
6167 /* is_LitAOp - check if operand has to be treated as literal */
6168 /*-----------------------------------------------------------------*/
6169 static bool is_LitAOp(asmop *aop)
6171 return (aop->type == AOP_LIT)
6172 || ( (aop->type == AOP_PCODE)
6173 && ( (aop->aopu.pcop->type == PO_LITERAL)
6174 || (aop->aopu.pcop->type == PO_IMMEDIATE) ));
6179 /*-----------------------------------------------------------------*/
6180 /* genCmpEq - generates code for equal to */
6181 /*-----------------------------------------------------------------*/
6182 static void genCmpEq (iCode *ic, iCode *ifx)
6184 operand *left, *right, *result;
6185 symbol *falselbl = newiTempLabel(NULL);
6186 symbol *donelbl = newiTempLabel(NULL);
6188 int preserve_result = 0;
6189 int generate_result = 0;
6192 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6193 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6194 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6199 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
6201 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6202 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
6206 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
6208 operand *tmp = right ;
6213 if ( regsInCommon(left, result) || regsInCommon(right, result) )
6214 preserve_result = 1;
6216 if(result && AOP_SIZE(result))
6217 generate_result = 1;
6219 if(generate_result && !preserve_result)
6221 for(i = 0; i < AOP_SIZE(result); i++)
6222 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6225 for(i=0; i < AOP_SIZE(left); i++)
6227 if(AOP_TYPE(left) != AOP_ACC)
6230 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
6232 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
6235 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
6237 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
6239 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
6244 if(generate_result && preserve_result)
6246 for(i = 0; i < AOP_SIZE(result); i++)
6247 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6251 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
6253 if(generate_result && preserve_result)
6254 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6256 if(ifx && IC_TRUE(ifx))
6257 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6259 if(ifx && IC_FALSE(ifx))
6260 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6262 pic16_emitpLabel(falselbl->key);
6266 if(ifx && IC_FALSE(ifx))
6267 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6269 if(generate_result && preserve_result)
6271 for(i = 0; i < AOP_SIZE(result); i++)
6272 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6275 pic16_emitpLabel(donelbl->key);
6281 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6282 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6283 pic16_freeAsmop(result,NULL,ic,TRUE);
6289 // old version kept for reference
6291 /*-----------------------------------------------------------------*/
6292 /* genCmpEq - generates code for equal to */
6293 /*-----------------------------------------------------------------*/
6294 static void genCmpEq (iCode *ic, iCode *ifx)
6296 operand *left, *right, *result;
6297 unsigned long lit = 0L;
6299 symbol *falselbl = newiTempLabel(NULL);
6302 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6305 DEBUGpic16_emitcode ("; ifx is non-null","");
6307 DEBUGpic16_emitcode ("; ifx is null","");
6309 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6310 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6311 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6313 size = max(AOP_SIZE(left),AOP_SIZE(right));
6315 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6317 /* if literal, literal on the right or
6318 if the right is in a pointer register and left
6320 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
6321 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
6322 operand *tmp = right ;
6328 if(ifx && !AOP_SIZE(result)){
6330 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
6331 /* if they are both bit variables */
6332 if (AOP_TYPE(left) == AOP_CRY &&
6333 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6334 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
6335 if(AOP_TYPE(right) == AOP_LIT){
6336 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6338 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6339 pic16_emitcode("cpl","c");
6340 } else if(lit == 1L) {
6341 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6343 pic16_emitcode("clr","c");
6345 /* AOP_TYPE(right) == AOP_CRY */
6347 symbol *lbl = newiTempLabel(NULL);
6348 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6349 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6350 pic16_emitcode("cpl","c");
6351 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6353 /* if true label then we jump if condition
6355 tlbl = newiTempLabel(NULL);
6356 if ( IC_TRUE(ifx) ) {
6357 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
6358 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
6360 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
6361 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
6363 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6366 /* left and right are both bit variables, result is carry */
6369 resolveIfx(&rIfx,ifx);
6371 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
6372 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
6373 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
6374 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
6379 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
6381 /* They're not both bit variables. Is the right a literal? */
6382 if(AOP_TYPE(right) == AOP_LIT) {
6383 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6388 switch(lit & 0xff) {
6390 if ( IC_TRUE(ifx) ) {
6391 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
6393 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6395 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6396 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6400 if ( IC_TRUE(ifx) ) {
6401 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
6403 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6405 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6406 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6410 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6412 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6417 /* end of size == 1 */
6421 genc16bit2lit(left,lit,offset);
6424 /* end of size == 2 */
6429 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6430 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
6431 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6432 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6435 /* search for patterns that can be optimized */
6437 genc16bit2lit(left,lit,0);
6441 emitSKPZ; // if hi word unequal
6443 emitSKPNZ; // if hi word equal
6445 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
6446 genc16bit2lit(left,lit,2);
6449 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6450 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6454 pic16_emitpLabel(falselbl->key);
6463 } else if(AOP_TYPE(right) == AOP_CRY ) {
6464 /* we know the left is not a bit, but that the right is */
6465 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6466 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
6467 pic16_popGet(AOP(right),offset));
6468 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
6470 /* if the two are equal, then W will be 0 and the Z bit is set
6471 * we could test Z now, or go ahead and check the high order bytes if
6472 * the variable we're comparing is larger than a byte. */
6475 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
6477 if ( IC_TRUE(ifx) ) {
6479 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6480 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6483 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6484 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6488 /* They're both variables that are larger than bits */
6491 tlbl = newiTempLabel(NULL);
6494 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6495 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6497 if ( IC_TRUE(ifx) ) {
6501 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
6503 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
6504 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
6508 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
6511 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6512 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6517 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
6519 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6520 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6524 if(s>1 && IC_TRUE(ifx)) {
6525 pic16_emitpLabel(tlbl->key);
6526 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6530 /* mark the icode as generated */
6535 /* if they are both bit variables */
6536 if (AOP_TYPE(left) == AOP_CRY &&
6537 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6538 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
6539 if(AOP_TYPE(right) == AOP_LIT){
6540 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6542 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6543 pic16_emitcode("cpl","c");
6544 } else if(lit == 1L) {
6545 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6547 pic16_emitcode("clr","c");
6549 /* AOP_TYPE(right) == AOP_CRY */
6551 symbol *lbl = newiTempLabel(NULL);
6552 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6553 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6554 pic16_emitcode("cpl","c");
6555 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6558 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
6559 pic16_outBitC(result);
6563 genIfxJump (ifx,"c");
6566 /* if the result is used in an arithmetic operation
6567 then put the result in place */
6568 pic16_outBitC(result);
6571 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
6572 gencjne(left,right,result,ifx);
6575 gencjne(left,right,newiTempLabel(NULL));
6577 if(IC_TRUE(ifx)->key)
6578 gencjne(left,right,IC_TRUE(ifx)->key);
6580 gencjne(left,right,IC_FALSE(ifx)->key);
6584 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
6585 pic16_aopPut(AOP(result),"a",0);
6590 genIfxJump (ifx,"a");
6594 /* if the result is used in an arithmetic operation
6595 then put the result in place */
6597 if (AOP_TYPE(result) != AOP_CRY)
6598 pic16_outAcc(result);
6600 /* leave the result in acc */
6604 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6605 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6606 pic16_freeAsmop(result,NULL,ic,TRUE);
6610 /*-----------------------------------------------------------------*/
6611 /* ifxForOp - returns the icode containing the ifx for operand */
6612 /*-----------------------------------------------------------------*/
6613 static iCode *ifxForOp ( operand *op, iCode *ic )
6615 /* if true symbol then needs to be assigned */
6616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6617 if (IS_TRUE_SYMOP(op))
6620 /* if this has register type condition and
6621 the next instruction is ifx with the same operand
6622 and live to of the operand is upto the ifx only then */
6624 && ic->next->op == IFX
6625 && IC_COND(ic->next)->key == op->key
6626 && OP_SYMBOL(op)->liveTo <= ic->next->seq
6628 DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
6633 ic->next->op == IFX &&
6634 IC_COND(ic->next)->key == op->key) {
6635 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6639 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6641 ic->next->op == IFX)
6642 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6645 ic->next->op == IFX &&
6646 IC_COND(ic->next)->key == op->key) {
6647 DEBUGpic16_emitcode ("; "," key is okay");
6648 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6649 OP_SYMBOL(op)->liveTo,
6654 /* the code below is completely untested
6655 * it just allows ulong2fs.c compile -- VR */
6658 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6659 __FILE__, __FUNCTION__, __LINE__);
6661 /* if this has register type condition and
6662 the next instruction is ifx with the same operand
6663 and live to of the operand is upto the ifx only then */
6665 ic->next->op == IFX &&
6666 IC_COND(ic->next)->key == op->key &&
6667 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6671 ic->next->op == IFX &&
6672 IC_COND(ic->next)->key == op->key) {
6673 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6677 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6678 __FILE__, __FUNCTION__, __LINE__);
6680 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6685 /*-----------------------------------------------------------------*/
6686 /* genAndOp - for && operation */
6687 /*-----------------------------------------------------------------*/
6688 static void genAndOp (iCode *ic)
6690 operand *left,*right, *result;
6693 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6694 /* note here that && operations that are in an
6695 if statement are taken away by backPatchLabels
6696 only those used in arthmetic operations remain */
6697 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6698 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6699 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6701 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6703 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6704 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6705 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6707 /* if both are bit variables */
6708 /* if (AOP_TYPE(left) == AOP_CRY && */
6709 /* AOP_TYPE(right) == AOP_CRY ) { */
6710 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6711 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6712 /* pic16_outBitC(result); */
6714 /* tlbl = newiTempLabel(NULL); */
6715 /* pic16_toBoolean(left); */
6716 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6717 /* pic16_toBoolean(right); */
6718 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6719 /* pic16_outBitAcc(result); */
6722 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6723 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6724 pic16_freeAsmop(result,NULL,ic,TRUE);
6728 /*-----------------------------------------------------------------*/
6729 /* genOrOp - for || operation */
6730 /*-----------------------------------------------------------------*/
6733 modified this code, but it doesn't appear to ever get called
6736 static void genOrOp (iCode *ic)
6738 operand *left,*right, *result;
6741 /* note here that || operations that are in an
6742 if statement are taken away by backPatchLabels
6743 only those used in arthmetic operations remain */
6744 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
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 /* if both are bit variables */
6752 if (AOP_TYPE(left) == AOP_CRY &&
6753 AOP_TYPE(right) == AOP_CRY ) {
6754 pic16_emitcode("clrc","");
6755 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6756 AOP(left)->aopu.aop_dir,
6757 AOP(left)->aopu.aop_dir);
6758 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6759 AOP(right)->aopu.aop_dir,
6760 AOP(right)->aopu.aop_dir);
6761 pic16_emitcode("setc","");
6764 tlbl = newiTempLabel(NULL);
6765 pic16_toBoolean(left);
6767 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
6768 pic16_toBoolean(right);
6769 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6771 pic16_outBitAcc(result);
6774 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6775 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6776 pic16_freeAsmop(result,NULL,ic,TRUE);
6779 /*-----------------------------------------------------------------*/
6780 /* isLiteralBit - test if lit == 2^n */
6781 /*-----------------------------------------------------------------*/
6782 static int isLiteralBit(unsigned long lit)
6784 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6785 0x100L,0x200L,0x400L,0x800L,
6786 0x1000L,0x2000L,0x4000L,0x8000L,
6787 0x10000L,0x20000L,0x40000L,0x80000L,
6788 0x100000L,0x200000L,0x400000L,0x800000L,
6789 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6790 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6793 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6794 for(idx = 0; idx < 32; idx++)
6800 /*-----------------------------------------------------------------*/
6801 /* continueIfTrue - */
6802 /*-----------------------------------------------------------------*/
6803 static void continueIfTrue (iCode *ic)
6805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6807 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6811 /*-----------------------------------------------------------------*/
6813 /*-----------------------------------------------------------------*/
6814 static void jumpIfTrue (iCode *ic)
6816 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6818 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6822 /*-----------------------------------------------------------------*/
6823 /* jmpTrueOrFalse - */
6824 /*-----------------------------------------------------------------*/
6825 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6827 // ugly but optimized by peephole
6828 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6830 symbol *nlbl = newiTempLabel(NULL);
6831 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6832 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6833 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6834 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6837 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6838 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6843 /*-----------------------------------------------------------------*/
6844 /* genAnd - code for and */
6845 /*-----------------------------------------------------------------*/
6846 static void genAnd (iCode *ic, iCode *ifx)
6848 operand *left, *right, *result;
6850 unsigned long lit = 0L;
6855 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6856 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6857 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6858 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6860 resolveIfx(&rIfx,ifx);
6862 /* if left is a literal & right is not then exchange them */
6863 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6864 AOP_NEEDSACC(left)) {
6865 operand *tmp = right ;
6870 /* if result = right then exchange them */
6871 if(pic16_sameRegs(AOP(result),AOP(right))){
6872 operand *tmp = right ;
6877 /* if right is bit then exchange them */
6878 if (AOP_TYPE(right) == AOP_CRY &&
6879 AOP_TYPE(left) != AOP_CRY){
6880 operand *tmp = right ;
6884 if(AOP_TYPE(right) == AOP_LIT)
6885 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6887 size = AOP_SIZE(result);
6889 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6892 // result = bit & yy;
6893 if (AOP_TYPE(left) == AOP_CRY){
6894 // c = bit & literal;
6895 if(AOP_TYPE(right) == AOP_LIT){
6897 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6900 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6903 if(size && (AOP_TYPE(result) == AOP_CRY)){
6904 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6907 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6911 pic16_emitcode("clr","c");
6914 if (AOP_TYPE(right) == AOP_CRY){
6916 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6917 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6920 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6922 pic16_emitcode("rrc","a");
6923 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6929 pic16_outBitC(result);
6931 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6932 genIfxJump(ifx, "c");
6936 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6937 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6938 if((AOP_TYPE(right) == AOP_LIT) &&
6939 (AOP_TYPE(result) == AOP_CRY) &&
6940 (AOP_TYPE(left) != AOP_CRY)){
6941 int posbit = isLiteralBit(lit);
6945 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6948 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6954 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6955 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6957 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6958 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6961 DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
6962 size = AOP_SIZE(left);
6965 int bp = posbit, ofs=0;
6972 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6973 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
6977 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6978 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6980 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6987 symbol *tlbl = newiTempLabel(NULL);
6988 int sizel = AOP_SIZE(left);
6994 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
6996 /* patch provided by Aaron Colwell */
6997 if((posbit = isLiteralBit(bytelit)) != 0) {
6998 pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
6999 pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
7000 (posbit-1),0, PO_GPR_REGISTER));
7002 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
7003 // pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7005 if (bytelit == 0xff) {
7006 /* Aaron had a MOVF instruction here, changed to MOVFW cause
7007 * a peephole could optimize it out -- VR */
7008 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7010 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7011 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
7014 pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
7015 pic16_popGetLabel(tlbl->key));
7019 /* old code, left here for reference -- VR 09/2004 */
7020 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7022 if((posbit = isLiteralBit(bytelit)) != 0)
7023 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
7025 if(bytelit != 0x0FFL)
7026 pic16_emitcode("anl","a,%s",
7027 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
7028 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7034 // bit = left & literal
7037 pic16_emitpLabel(tlbl->key);
7039 // if(left & literal)
7042 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7043 pic16_emitpLabel(tlbl->key);
7050 pic16_outBitC(result);
7054 /* if left is same as result */
7055 if(pic16_sameRegs(AOP(result),AOP(left))){
7057 for(;size--; offset++,lit>>=8) {
7058 if(AOP_TYPE(right) == AOP_LIT){
7059 switch(lit & 0xff) {
7061 /* and'ing with 0 has clears the result */
7062 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7063 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7066 /* and'ing with 0xff is a nop when the result and left are the same */
7071 int p = my_powof2( (~lit) & 0xff );
7073 /* only one bit is set in the literal, so use a bcf instruction */
7074 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
7075 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7078 pic16_emitcode("movlw","0x%x", (lit & 0xff));
7079 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7080 if(know_W != (lit&0xff))
7081 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7083 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7088 if (AOP_TYPE(left) == AOP_ACC) {
7089 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7091 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7092 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7099 // left & result in different registers
7100 if(AOP_TYPE(result) == AOP_CRY){
7102 // if(size), result in bit
7103 // if(!size && ifx), conditional oper: if(left & right)
7104 symbol *tlbl = newiTempLabel(NULL);
7105 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
7107 pic16_emitcode("setb","c");
7109 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7110 pic16_emitcode("anl","a,%s",
7111 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7112 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7117 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7118 pic16_outBitC(result);
7120 jmpTrueOrFalse(ifx, tlbl);
7122 for(;(size--);offset++) {
7124 // result = left & right
7125 if(AOP_TYPE(right) == AOP_LIT){
7126 int t = (lit >> (offset*8)) & 0x0FFL;
7129 pic16_emitcode("clrf","%s",
7130 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7131 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7134 pic16_emitcode("movf","%s,w",
7135 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7136 pic16_emitcode("movwf","%s",
7137 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7138 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7139 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7142 pic16_emitcode("movlw","0x%x",t);
7143 pic16_emitcode("andwf","%s,w",
7144 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7145 pic16_emitcode("movwf","%s",
7146 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7148 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7149 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7150 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7155 if (AOP_TYPE(left) == AOP_ACC) {
7156 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7157 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7159 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7160 pic16_emitcode("andwf","%s,w",
7161 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7162 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7163 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7165 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7166 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7172 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7173 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7174 pic16_freeAsmop(result,NULL,ic,TRUE);
7177 /*-----------------------------------------------------------------*/
7178 /* genOr - code for or */
7179 /*-----------------------------------------------------------------*/
7180 static void genOr (iCode *ic, iCode *ifx)
7182 operand *left, *right, *result;
7184 unsigned long lit = 0L;
7186 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7188 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7189 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7190 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7192 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7194 /* if left is a literal & right is not then exchange them */
7195 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7196 AOP_NEEDSACC(left)) {
7197 operand *tmp = right ;
7202 /* if result = right then exchange them */
7203 if(pic16_sameRegs(AOP(result),AOP(right))){
7204 operand *tmp = right ;
7209 /* if right is bit then exchange them */
7210 if (AOP_TYPE(right) == AOP_CRY &&
7211 AOP_TYPE(left) != AOP_CRY){
7212 operand *tmp = right ;
7217 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7219 if(AOP_TYPE(right) == AOP_LIT)
7220 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7222 size = AOP_SIZE(result);
7226 if (AOP_TYPE(left) == AOP_CRY){
7227 if(AOP_TYPE(right) == AOP_LIT){
7228 // c = bit & literal;
7230 // lit != 0 => result = 1
7231 if(AOP_TYPE(result) == AOP_CRY){
7233 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7234 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7235 // AOP(result)->aopu.aop_dir,
7236 // AOP(result)->aopu.aop_dir);
7238 continueIfTrue(ifx);
7242 // lit == 0 => result = left
7243 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7245 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
7248 if (AOP_TYPE(right) == AOP_CRY){
7249 if(pic16_sameRegs(AOP(result),AOP(left))){
7251 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7252 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
7253 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7255 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7256 AOP(result)->aopu.aop_dir,
7257 AOP(result)->aopu.aop_dir);
7258 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7259 AOP(right)->aopu.aop_dir,
7260 AOP(right)->aopu.aop_dir);
7261 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7262 AOP(result)->aopu.aop_dir,
7263 AOP(result)->aopu.aop_dir);
7265 if( AOP_TYPE(result) == AOP_ACC) {
7266 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7267 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7268 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7269 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
7273 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7274 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7275 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7276 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7278 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7279 AOP(result)->aopu.aop_dir,
7280 AOP(result)->aopu.aop_dir);
7281 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
7282 AOP(right)->aopu.aop_dir,
7283 AOP(right)->aopu.aop_dir);
7284 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7285 AOP(left)->aopu.aop_dir,
7286 AOP(left)->aopu.aop_dir);
7287 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7288 AOP(result)->aopu.aop_dir,
7289 AOP(result)->aopu.aop_dir);
7294 symbol *tlbl = newiTempLabel(NULL);
7295 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7298 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7299 if( AOP_TYPE(right) == AOP_ACC) {
7300 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
7302 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7303 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7308 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
7309 pic16_emitcode(";XXX setb","c");
7310 pic16_emitcode(";XXX jb","%s,%05d_DS_",
7311 AOP(left)->aopu.aop_dir,tlbl->key+100);
7312 pic16_toBoolean(right);
7313 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7314 if((AOP_TYPE(result) == AOP_CRY) && ifx){
7315 jmpTrueOrFalse(ifx, tlbl);
7319 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7326 pic16_outBitC(result);
7328 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7329 genIfxJump(ifx, "c");
7333 // if(val | 0xZZ) - size = 0, ifx != FALSE -
7334 // bit = val | 0xZZ - size = 1, ifx = FALSE -
7335 if((AOP_TYPE(right) == AOP_LIT) &&
7336 (AOP_TYPE(result) == AOP_CRY) &&
7337 (AOP_TYPE(left) != AOP_CRY)){
7339 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7342 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
7344 continueIfTrue(ifx);
7347 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7348 // lit = 0, result = boolean(left)
7350 pic16_emitcode(";XXX setb","c");
7351 pic16_toBoolean(right);
7353 symbol *tlbl = newiTempLabel(NULL);
7354 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7356 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7358 genIfxJump (ifx,"a");
7362 pic16_outBitC(result);
7366 /* if left is same as result */
7367 if(pic16_sameRegs(AOP(result),AOP(left))){
7369 for(;size--; offset++,lit>>=8) {
7370 if(AOP_TYPE(right) == AOP_LIT){
7371 if((lit & 0xff) == 0)
7372 /* or'ing with 0 has no effect */
7375 int p = my_powof2(lit & 0xff);
7377 /* only one bit is set in the literal, so use a bsf instruction */
7378 pic16_emitpcode(POC_BSF,
7379 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7381 if(know_W != (lit & 0xff))
7382 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7383 know_W = lit & 0xff;
7384 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7389 if (AOP_TYPE(left) == AOP_ACC) {
7390 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
7391 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7393 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7394 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7396 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7397 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7403 // left & result in different registers
7404 if(AOP_TYPE(result) == AOP_CRY){
7406 // if(size), result in bit
7407 // if(!size && ifx), conditional oper: if(left | right)
7408 symbol *tlbl = newiTempLabel(NULL);
7409 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7410 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7414 pic16_emitcode(";XXX setb","c");
7416 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7417 pic16_emitcode(";XXX orl","a,%s",
7418 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7419 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7424 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7425 pic16_outBitC(result);
7427 jmpTrueOrFalse(ifx, tlbl);
7428 } else for(;(size--);offset++){
7430 // result = left & right
7431 if(AOP_TYPE(right) == AOP_LIT){
7432 int t = (lit >> (offset*8)) & 0x0FFL;
7435 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7436 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7438 pic16_emitcode("movf","%s,w",
7439 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7440 pic16_emitcode("movwf","%s",
7441 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7444 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7445 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7446 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7448 pic16_emitcode("movlw","0x%x",t);
7449 pic16_emitcode("iorwf","%s,w",
7450 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7451 pic16_emitcode("movwf","%s",
7452 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7458 // faster than result <- left, anl result,right
7459 // and better if result is SFR
7460 if (AOP_TYPE(left) == AOP_ACC) {
7461 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
7462 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7464 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7465 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7467 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7468 pic16_emitcode("iorwf","%s,w",
7469 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7471 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7472 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7477 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7478 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7479 pic16_freeAsmop(result,NULL,ic,TRUE);
7482 /*-----------------------------------------------------------------*/
7483 /* genXor - code for xclusive or */
7484 /*-----------------------------------------------------------------*/
7485 static void genXor (iCode *ic, iCode *ifx)
7487 operand *left, *right, *result;
7489 unsigned long lit = 0L;
7491 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7493 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7494 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7495 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7497 /* if left is a literal & right is not ||
7498 if left needs acc & right does not */
7499 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7500 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
7501 operand *tmp = right ;
7506 /* if result = right then exchange them */
7507 if(pic16_sameRegs(AOP(result),AOP(right))){
7508 operand *tmp = right ;
7513 /* if right is bit then exchange them */
7514 if (AOP_TYPE(right) == AOP_CRY &&
7515 AOP_TYPE(left) != AOP_CRY){
7516 operand *tmp = right ;
7520 if(AOP_TYPE(right) == AOP_LIT)
7521 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7523 size = AOP_SIZE(result);
7527 if (AOP_TYPE(left) == AOP_CRY){
7528 if(AOP_TYPE(right) == AOP_LIT){
7529 // c = bit & literal;
7531 // lit>>1 != 0 => result = 1
7532 if(AOP_TYPE(result) == AOP_CRY){
7534 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
7535 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
7537 continueIfTrue(ifx);
7540 pic16_emitcode("setb","c");
7544 // lit == 0, result = left
7545 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7547 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7549 // lit == 1, result = not(left)
7550 if(size && pic16_sameRegs(AOP(result),AOP(left))){
7551 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
7552 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
7553 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
7556 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7557 pic16_emitcode("cpl","c");
7564 symbol *tlbl = newiTempLabel(NULL);
7565 if (AOP_TYPE(right) == AOP_CRY){
7567 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
7570 int sizer = AOP_SIZE(right);
7572 // if val>>1 != 0, result = 1
7573 pic16_emitcode("setb","c");
7575 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
7577 // test the msb of the lsb
7578 pic16_emitcode("anl","a,#0xfe");
7579 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7583 pic16_emitcode("rrc","a");
7585 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
7586 pic16_emitcode("cpl","c");
7587 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
7592 pic16_outBitC(result);
7594 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7595 genIfxJump(ifx, "c");
7599 if(pic16_sameRegs(AOP(result),AOP(left))){
7600 /* if left is same as result */
7601 for(;size--; offset++) {
7602 if(AOP_TYPE(right) == AOP_LIT){
7603 int t = (lit >> (offset*8)) & 0x0FFL;
7607 if (IS_AOP_PREG(left)) {
7608 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7609 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7610 pic16_aopPut(AOP(result),"a",offset);
7612 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7613 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7614 pic16_emitcode("xrl","%s,%s",
7615 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
7616 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7619 if (AOP_TYPE(left) == AOP_ACC)
7620 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7622 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7623 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7625 if (IS_AOP_PREG(left)) {
7626 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7627 pic16_aopPut(AOP(result),"a",offset);
7629 pic16_emitcode("xrl","%s,a",
7630 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7636 // left & result in different registers
7637 if(AOP_TYPE(result) == AOP_CRY){
7639 // if(size), result in bit
7640 // if(!size && ifx), conditional oper: if(left ^ right)
7641 symbol *tlbl = newiTempLabel(NULL);
7642 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7644 pic16_emitcode("setb","c");
7646 if((AOP_TYPE(right) == AOP_LIT) &&
7647 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
7648 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7650 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7651 pic16_emitcode("xrl","a,%s",
7652 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7654 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7659 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7660 pic16_outBitC(result);
7662 jmpTrueOrFalse(ifx, tlbl);
7663 } else for(;(size--);offset++){
7665 // result = left & right
7666 if(AOP_TYPE(right) == AOP_LIT){
7667 int t = (lit >> (offset*8)) & 0x0FFL;
7670 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7671 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7672 pic16_emitcode("movf","%s,w",
7673 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7674 pic16_emitcode("movwf","%s",
7675 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7678 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7679 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7680 pic16_emitcode("comf","%s,w",
7681 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7682 pic16_emitcode("movwf","%s",
7683 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7686 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7687 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7688 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7689 pic16_emitcode("movlw","0x%x",t);
7690 pic16_emitcode("xorwf","%s,w",
7691 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7692 pic16_emitcode("movwf","%s",
7693 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7699 // faster than result <- left, anl result,right
7700 // and better if result is SFR
7701 if (AOP_TYPE(left) == AOP_ACC) {
7702 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7703 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7705 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7706 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7707 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7708 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7710 if ( AOP_TYPE(result) != AOP_ACC){
7711 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7712 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7718 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7719 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7720 pic16_freeAsmop(result,NULL,ic,TRUE);
7723 /*-----------------------------------------------------------------*/
7724 /* genInline - write the inline code out */
7725 /*-----------------------------------------------------------------*/
7726 static void genInline (iCode *ic)
7728 char *buffer, *bp, *bp1;
7730 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7732 _G.inLine += (!options.asmpeep);
7734 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7735 strcpy(buffer,IC_INLINE(ic));
7737 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7739 /* emit each line as a code */
7745 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7753 /* print label, use this special format with NULL directive
7754 * to denote that the argument should not be indented with tab */
7755 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7762 if ((bp1 != bp) && *bp1)
7763 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7768 _G.inLine -= (!options.asmpeep);
7771 /*-----------------------------------------------------------------*/
7772 /* genRRC - rotate right with carry */
7773 /*-----------------------------------------------------------------*/
7774 static void genRRC (iCode *ic)
7776 operand *left , *result ;
7777 int size, offset = 0, same;
7779 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7781 /* rotate right with carry */
7783 result=IC_RESULT(ic);
7784 pic16_aopOp (left,ic,FALSE);
7785 pic16_aopOp (result,ic,FALSE);
7787 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7789 same = pic16_sameRegs(AOP(result),AOP(left));
7791 size = AOP_SIZE(result);
7793 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7795 /* get the lsb and put it into the carry */
7796 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7803 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7805 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7806 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7812 pic16_freeAsmop(left,NULL,ic,TRUE);
7813 pic16_freeAsmop(result,NULL,ic,TRUE);
7816 /*-----------------------------------------------------------------*/
7817 /* genRLC - generate code for rotate left with carry */
7818 /*-----------------------------------------------------------------*/
7819 static void genRLC (iCode *ic)
7821 operand *left , *result ;
7822 int size, offset = 0;
7825 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7826 /* rotate right with carry */
7828 result=IC_RESULT(ic);
7829 pic16_aopOp (left,ic,FALSE);
7830 pic16_aopOp (result,ic,FALSE);
7832 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7834 same = pic16_sameRegs(AOP(result),AOP(left));
7836 /* move it to the result */
7837 size = AOP_SIZE(result);
7839 /* get the msb and put it into the carry */
7840 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7847 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7849 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7850 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7857 pic16_freeAsmop(left,NULL,ic,TRUE);
7858 pic16_freeAsmop(result,NULL,ic,TRUE);
7862 /* gpasm can get the highest order bit with HIGH/UPPER
7863 * so the following probably is not needed -- VR */
7865 /*-----------------------------------------------------------------*/
7866 /* genGetHbit - generates code get highest order bit */
7867 /*-----------------------------------------------------------------*/
7868 static void genGetHbit (iCode *ic)
7870 operand *left, *result;
7872 result=IC_RESULT(ic);
7873 pic16_aopOp (left,ic,FALSE);
7874 pic16_aopOp (result,ic,FALSE);
7876 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7877 /* get the highest order byte into a */
7878 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7879 if(AOP_TYPE(result) == AOP_CRY){
7880 pic16_emitcode("rlc","a");
7881 pic16_outBitC(result);
7884 pic16_emitcode("rl","a");
7885 pic16_emitcode("anl","a,#0x01");
7886 pic16_outAcc(result);
7890 pic16_freeAsmop(left,NULL,ic,TRUE);
7891 pic16_freeAsmop(result,NULL,ic,TRUE);
7895 /*-----------------------------------------------------------------*/
7896 /* AccRol - rotate left accumulator by known count */
7897 /*-----------------------------------------------------------------*/
7898 static void AccRol (int shCount)
7900 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7901 shCount &= 0x0007; // shCount : 0..7
7906 pic16_emitcode("rl","a");
7909 pic16_emitcode("rl","a");
7910 pic16_emitcode("rl","a");
7913 pic16_emitcode("swap","a");
7914 pic16_emitcode("rr","a");
7917 pic16_emitcode("swap","a");
7920 pic16_emitcode("swap","a");
7921 pic16_emitcode("rl","a");
7924 pic16_emitcode("rr","a");
7925 pic16_emitcode("rr","a");
7928 pic16_emitcode("rr","a");
7934 /*-----------------------------------------------------------------*/
7935 /* AccLsh - left shift accumulator by known count */
7936 /*-----------------------------------------------------------------*/
7937 static void AccLsh (int shCount)
7939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7945 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7948 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7949 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7952 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7953 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7956 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7959 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7960 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7963 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7964 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7967 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7971 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7974 /*-----------------------------------------------------------------*/
7975 /* AccRsh - right shift accumulator by known count */
7976 /*-----------------------------------------------------------------*/
7977 static void AccRsh (int shCount, int andmask)
7979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7984 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7987 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7988 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7991 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7992 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7995 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7998 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7999 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8002 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8003 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8006 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8011 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
8013 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
8017 /*-----------------------------------------------------------------*/
8018 /* AccSRsh - signed right shift accumulator by known count */
8019 /*-----------------------------------------------------------------*/
8020 static void AccSRsh (int shCount)
8023 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8026 pic16_emitcode("mov","c,acc.7");
8027 pic16_emitcode("rrc","a");
8028 } else if(shCount == 2){
8029 pic16_emitcode("mov","c,acc.7");
8030 pic16_emitcode("rrc","a");
8031 pic16_emitcode("mov","c,acc.7");
8032 pic16_emitcode("rrc","a");
8034 tlbl = newiTempLabel(NULL);
8035 /* rotate right accumulator */
8036 AccRol(8 - shCount);
8037 /* and kill the higher order bits */
8038 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
8039 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
8040 pic16_emitcode("orl","a,#0x%02x",
8041 (unsigned char)~SRMask[shCount]);
8042 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8048 /*-----------------------------------------------------------------*/
8049 /* shiftR1Left2Result - shift right one byte from left to result */
8050 /*-----------------------------------------------------------------*/
8051 static void shiftR1Left2ResultSigned (operand *left, int offl,
8052 operand *result, int offr,
8057 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8059 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8063 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8065 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8067 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8068 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8074 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8076 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8078 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8079 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8081 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8082 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8088 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8090 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8091 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8094 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8095 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8096 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8098 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8099 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
8101 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8105 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8106 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8107 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8108 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
8109 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8113 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8115 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8118 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8119 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
8120 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8121 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
8122 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8127 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8128 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8129 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
8130 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8131 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
8132 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8134 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8135 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8136 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8137 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8138 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8144 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8145 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8146 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8147 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8149 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8150 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8151 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8159 /*-----------------------------------------------------------------*/
8160 /* shiftR1Left2Result - shift right one byte from left to result */
8161 /*-----------------------------------------------------------------*/
8162 static void shiftR1Left2Result (operand *left, int offl,
8163 operand *result, int offr,
8164 int shCount, int sign)
8168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8170 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8172 /* Copy the msb into the carry if signed. */
8174 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
8184 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8186 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8187 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8193 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8195 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8196 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8199 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8204 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8206 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8207 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8210 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8211 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8212 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8213 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8217 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8218 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8219 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8223 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8224 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0e));
8225 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8227 pic16_emitpcode(POC_RRNCF, pic16_popGet(AOP(result),offr));
8232 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left),offl));
8233 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x81));
8234 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8235 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8236 pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(result),offr));
8241 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8242 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8243 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8252 /*-----------------------------------------------------------------*/
8253 /* shiftL1Left2Result - shift left one byte from left to result */
8254 /*-----------------------------------------------------------------*/
8255 static void shiftL1Left2Result (operand *left, int offl,
8256 operand *result, int offr, int shCount)
8261 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8263 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
8264 DEBUGpic16_emitcode ("; ***","same = %d",same);
8265 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8267 /* shift left accumulator */
8268 //AccLsh(shCount); // don't comment out just yet...
8269 // pic16_aopPut(AOP(result),"a",offr);
8273 /* Shift left 1 bit position */
8274 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8276 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
8278 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
8279 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8283 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8284 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
8285 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8286 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8289 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8290 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
8291 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8292 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8293 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8296 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8297 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8298 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8301 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8302 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8303 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8304 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8307 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8308 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
8309 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8310 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8311 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8314 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8315 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8316 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8320 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
8325 /*-----------------------------------------------------------------*/
8326 /* movLeft2Result - move byte from left to result */
8327 /*-----------------------------------------------------------------*/
8328 static void movLeft2Result (operand *left, int offl,
8329 operand *result, int offr)
8332 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8333 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
8334 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8336 if (*l == '@' && (IS_AOP_PREG(result))) {
8337 pic16_emitcode("mov","a,%s",l);
8338 pic16_aopPut(AOP(result),"a",offr);
8340 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8341 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8346 /*-----------------------------------------------------------------*/
8347 /* shiftL2Left2Result - shift left two bytes from left to result */
8348 /*-----------------------------------------------------------------*/
8349 static void shiftL2Left2Result (operand *left, int offl,
8350 operand *result, int offr, int shCount)
8352 int same = pic16_sameRegs(AOP(result), AOP(left));
8355 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
8357 if (same && (offl != offr)) { // shift bytes
8360 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8361 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8363 } else { // just treat as different later on
8376 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
8377 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8378 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8382 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8383 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8389 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
8390 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
8391 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8392 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8393 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
8394 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8395 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8397 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8398 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8402 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8403 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8404 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8405 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8406 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8407 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8408 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8409 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8410 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8411 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8414 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8415 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8416 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8417 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8418 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8428 /* note, use a mov/add for the shift since the mov has a
8429 chance of getting optimized out */
8430 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8431 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8432 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8433 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8434 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8438 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8439 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8445 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8446 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
8447 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8448 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8449 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8450 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0F));
8451 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8452 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8456 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8457 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8461 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8462 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8463 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
8464 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8466 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8467 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8468 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8469 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8470 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8471 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8472 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8473 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8476 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8477 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8478 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8479 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8480 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8485 /*-----------------------------------------------------------------*/
8486 /* shiftR2Left2Result - shift right two bytes from left to result */
8487 /*-----------------------------------------------------------------*/
8488 static void shiftR2Left2Result (operand *left, int offl,
8489 operand *result, int offr,
8490 int shCount, int sign)
8492 int same = pic16_sameRegs(AOP(result), AOP(left));
8494 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
8496 if (same && (offl != offr)) { // shift right bytes
8499 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8500 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8502 } else { // just treat as different later on
8514 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8519 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8520 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8522 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8523 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8524 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8525 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8530 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8533 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8534 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8541 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
8542 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
8543 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8545 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8546 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
8547 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8548 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8550 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8551 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8552 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8554 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8555 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8556 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8557 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8558 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8562 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8563 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8567 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
8568 pic16_emitpcode(POC_BTFSC,
8569 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
8570 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8578 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8579 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8581 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8582 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8583 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8584 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8586 pic16_emitpcode(POC_BTFSC,
8587 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8588 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8590 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8591 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
8592 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8593 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8595 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8596 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8597 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8598 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8599 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8600 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8601 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
8602 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8604 pic16_emitpcode(POC_BTFSC,
8605 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8606 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8608 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8609 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8616 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8617 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8618 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8619 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
8622 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
8624 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8629 /*-----------------------------------------------------------------*/
8630 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
8631 /*-----------------------------------------------------------------*/
8632 static void shiftLLeftOrResult (operand *left, int offl,
8633 operand *result, int offr, int shCount)
8635 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8637 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8638 /* shift left accumulator */
8640 /* or with result */
8641 /* back to result */
8642 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8645 /*-----------------------------------------------------------------*/
8646 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
8647 /*-----------------------------------------------------------------*/
8648 static void shiftRLeftOrResult (operand *left, int offl,
8649 operand *result, int offr, int shCount)
8651 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8653 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8654 /* shift right accumulator */
8656 /* or with result */
8657 /* back to result */
8658 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8661 /*-----------------------------------------------------------------*/
8662 /* genlshOne - left shift a one byte quantity by known count */
8663 /*-----------------------------------------------------------------*/
8664 static void genlshOne (operand *result, operand *left, int shCount)
8666 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8667 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8670 /*-----------------------------------------------------------------*/
8671 /* genlshTwo - left shift two bytes by known amount != 0 */
8672 /*-----------------------------------------------------------------*/
8673 static void genlshTwo (operand *result,operand *left, int shCount)
8677 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8678 size = pic16_getDataSize(result);
8680 /* if shCount >= 8 */
8686 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8688 movLeft2Result(left, LSB, result, MSB16);
8690 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8693 /* 1 <= shCount <= 7 */
8696 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8698 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8702 /*-----------------------------------------------------------------*/
8703 /* shiftLLong - shift left one long from left to result */
8704 /* offr = LSB or MSB16 */
8705 /*-----------------------------------------------------------------*/
8706 static void shiftLLong (operand *left, operand *result, int offr )
8708 int size = AOP_SIZE(result);
8709 int same = pic16_sameRegs(AOP(left),AOP(result));
8712 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8714 if (same && (offr == MSB16)) { //shift one byte
8715 for(i=size-1;i>=MSB16;i--) {
8716 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8717 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8720 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8723 if (size > LSB+offr ){
8725 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8727 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8728 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8732 if(size > MSB16+offr){
8734 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8736 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8737 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8741 if(size > MSB24+offr){
8743 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8745 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8746 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8750 if(size > MSB32+offr){
8752 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8754 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8755 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8759 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8763 /*-----------------------------------------------------------------*/
8764 /* genlshFour - shift four byte by a known amount != 0 */
8765 /*-----------------------------------------------------------------*/
8766 static void genlshFour (operand *result, operand *left, int shCount)
8770 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8771 size = AOP_SIZE(result);
8773 /* if shifting more that 3 bytes */
8774 if (shCount >= 24 ) {
8777 /* lowest order of left goes to the highest
8778 order of the destination */
8779 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8781 movLeft2Result(left, LSB, result, MSB32);
8783 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8784 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8785 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8790 /* more than two bytes */
8791 else if ( shCount >= 16 ) {
8792 /* lower order two bytes goes to higher order two bytes */
8794 /* if some more remaining */
8796 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8798 movLeft2Result(left, MSB16, result, MSB32);
8799 movLeft2Result(left, LSB, result, MSB24);
8801 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8802 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8806 /* if more than 1 byte */
8807 else if ( shCount >= 8 ) {
8808 /* lower order three bytes goes to higher order three bytes */
8812 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8814 movLeft2Result(left, LSB, result, MSB16);
8816 else{ /* size = 4 */
8818 movLeft2Result(left, MSB24, result, MSB32);
8819 movLeft2Result(left, MSB16, result, MSB24);
8820 movLeft2Result(left, LSB, result, MSB16);
8821 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8823 else if(shCount == 1)
8824 shiftLLong(left, result, MSB16);
8826 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8827 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8828 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8829 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8834 /* 1 <= shCount <= 7 */
8835 else if(shCount <= 3)
8837 shiftLLong(left, result, LSB);
8838 while(--shCount >= 1)
8839 shiftLLong(result, result, LSB);
8841 /* 3 <= shCount <= 7, optimize */
8843 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8844 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8845 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8849 /*-----------------------------------------------------------------*/
8850 /* genLeftShiftLiteral - left shifting by known count */
8851 /*-----------------------------------------------------------------*/
8852 static void genLeftShiftLiteral (operand *left,
8857 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8860 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8861 pic16_freeAsmop(right,NULL,ic,TRUE);
8863 pic16_aopOp(left,ic,FALSE);
8864 pic16_aopOp(result,ic,FALSE);
8866 size = getSize(operandType(result));
8869 pic16_emitcode("; shift left ","result %d, left %d",size,
8873 /* I suppose that the left size >= result size */
8876 movLeft2Result(left, size, result, size);
8880 else if(shCount >= (size * 8))
8882 pic16_aopPut(AOP(result),zero,size);
8886 genlshOne (result,left,shCount);
8891 genlshTwo (result,left,shCount);
8895 genlshFour (result,left,shCount);
8899 pic16_freeAsmop(left,NULL,ic,TRUE);
8900 pic16_freeAsmop(result,NULL,ic,TRUE);
8903 /*-----------------------------------------------------------------*
8904 * genMultiAsm - repeat assembly instruction for size of register.
8905 * if endian == 1, then the high byte (i.e base address + size of
8906 * register) is used first else the low byte is used first;
8907 *-----------------------------------------------------------------*/
8908 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8913 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8926 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8931 /*-----------------------------------------------------------------*/
8932 /* genLeftShift - generates code for left shifting */
8933 /*-----------------------------------------------------------------*/
8934 static void genLeftShift (iCode *ic)
8936 operand *left,*right, *result;
8939 symbol *tlbl , *tlbl1;
8942 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8944 right = IC_RIGHT(ic);
8946 result = IC_RESULT(ic);
8948 pic16_aopOp(right,ic,FALSE);
8950 /* if the shift count is known then do it
8951 as efficiently as possible */
8952 if (AOP_TYPE(right) == AOP_LIT) {
8953 genLeftShiftLiteral (left,right,result,ic);
8957 /* shift count is unknown then we have to form
8958 * a loop. Get the loop count in WREG : Note: we take
8959 * only the lower order byte since shifting
8960 * more than 32 bits make no sense anyway, ( the
8961 * largest size of an object can be only 32 bits ) */
8963 pic16_aopOp(left,ic,FALSE);
8964 pic16_aopOp(result,ic,FALSE);
8966 /* now move the left to the result if they are not the
8967 * same, and if size > 1,
8968 * and if right is not same to result (!!!) -- VR */
8969 if (!pic16_sameRegs(AOP(left),AOP(result))
8970 && (AOP_SIZE(result) > 1)) {
8972 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8974 size = AOP_SIZE(result);
8979 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8980 if (*l == '@' && (IS_AOP_PREG(result))) {
8982 pic16_emitcode("mov","a,%s",l);
8983 pic16_aopPut(AOP(result),"a",offset);
8987 /* we don't know if left is a literal or a register, take care -- VR */
8988 mov2f(AOP(result), AOP(left), offset);
8994 size = AOP_SIZE(result);
8996 /* if it is only one byte then */
8998 if(optimized_for_speed) {
8999 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9000 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9001 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9002 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9003 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9004 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9005 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9006 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9007 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9008 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9009 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9010 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9013 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9015 tlbl = newiTempLabel(NULL);
9018 /* this is already done, why change it? */
9019 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9020 mov2f(AOP(result), AOP(left), 0);
9024 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9025 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9026 pic16_emitpLabel(tlbl->key);
9027 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9028 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9030 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9035 if (pic16_sameRegs(AOP(left),AOP(result))) {
9037 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9039 tlbl = newiTempLabel(NULL);
9040 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9041 genMultiAsm(POC_RRCF, result, size,1);
9042 pic16_emitpLabel(tlbl->key);
9043 genMultiAsm(POC_RLCF, result, size,0);
9044 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9046 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9050 //tlbl = newiTempLabel(NULL);
9052 //tlbl1 = newiTempLabel(NULL);
9054 //reAdjustPreg(AOP(result));
9056 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9057 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9058 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9060 //pic16_emitcode("add","a,acc");
9061 //pic16_aopPut(AOP(result),"a",offset++);
9063 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9065 // pic16_emitcode("rlc","a");
9066 // pic16_aopPut(AOP(result),"a",offset++);
9068 //reAdjustPreg(AOP(result));
9070 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9071 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9074 tlbl = newiTempLabel(NULL);
9075 tlbl1= newiTempLabel(NULL);
9077 size = AOP_SIZE(result);
9080 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9082 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9084 /* offset should be 0, 1 or 3 */
9086 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9088 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9090 pic16_emitpcode(POC_MOVWF, pctemp);
9093 pic16_emitpLabel(tlbl->key);
9096 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9098 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9100 pic16_emitpcode(POC_DECFSZ, pctemp);
9101 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9102 pic16_emitpLabel(tlbl1->key);
9104 pic16_popReleaseTempReg(pctemp,1);
9108 pic16_freeAsmop (right,NULL,ic,TRUE);
9109 pic16_freeAsmop(left,NULL,ic,TRUE);
9110 pic16_freeAsmop(result,NULL,ic,TRUE);
9116 #error old code (left here for reference)
9117 /*-----------------------------------------------------------------*/
9118 /* genLeftShift - generates code for left shifting */
9119 /*-----------------------------------------------------------------*/
9120 static void genLeftShift (iCode *ic)
9122 operand *left,*right, *result;
9125 symbol *tlbl , *tlbl1;
9128 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9130 right = IC_RIGHT(ic);
9132 result = IC_RESULT(ic);
9134 pic16_aopOp(right,ic,FALSE);
9136 /* if the shift count is known then do it
9137 as efficiently as possible */
9138 if (AOP_TYPE(right) == AOP_LIT) {
9139 genLeftShiftLiteral (left,right,result,ic);
9143 /* shift count is unknown then we have to form
9144 a loop get the loop count in B : Note: we take
9145 only the lower order byte since shifting
9146 more that 32 bits make no sense anyway, ( the
9147 largest size of an object can be only 32 bits ) */
9150 pic16_aopOp(left,ic,FALSE);
9151 pic16_aopOp(result,ic,FALSE);
9153 /* now move the left to the result if they are not the
9155 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9156 AOP_SIZE(result) > 1) {
9158 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9160 size = AOP_SIZE(result);
9163 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9164 if (*l == '@' && (IS_AOP_PREG(result))) {
9166 pic16_emitcode("mov","a,%s",l);
9167 pic16_aopPut(AOP(result),"a",offset);
9170 /* we don't know if left is a literal or a register, take care -- VR */
9171 mov2f(AOP(result), AOP(left), offset);
9177 size = AOP_SIZE(result);
9179 /* if it is only one byte then */
9181 if(optimized_for_speed) {
9182 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9183 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9184 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9185 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9186 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9187 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9188 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9189 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9190 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9191 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9192 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9193 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9198 tlbl = newiTempLabel(NULL);
9199 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9200 mov2f(AOP(result), AOP(left), 0);
9202 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9203 // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9206 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9207 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9208 pic16_emitpLabel(tlbl->key);
9209 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9210 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9212 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9217 if (pic16_sameRegs(AOP(left),AOP(result))) {
9219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9221 tlbl = newiTempLabel(NULL);
9222 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9223 genMultiAsm(POC_RRCF, result, size,1);
9224 pic16_emitpLabel(tlbl->key);
9225 genMultiAsm(POC_RLCF, result, size,0);
9226 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9228 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9232 //tlbl = newiTempLabel(NULL);
9234 //tlbl1 = newiTempLabel(NULL);
9236 //reAdjustPreg(AOP(result));
9238 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9239 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9240 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9242 //pic16_emitcode("add","a,acc");
9243 //pic16_aopPut(AOP(result),"a",offset++);
9245 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9247 // pic16_emitcode("rlc","a");
9248 // pic16_aopPut(AOP(result),"a",offset++);
9250 //reAdjustPreg(AOP(result));
9252 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9253 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9256 tlbl = newiTempLabel(NULL);
9257 tlbl1= newiTempLabel(NULL);
9259 size = AOP_SIZE(result);
9262 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9264 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9266 /* offset should be 0, 1 or 3 */
9268 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9270 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9272 pic16_emitpcode(POC_MOVWF, pctemp);
9275 pic16_emitpLabel(tlbl->key);
9278 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9280 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9282 pic16_emitpcode(POC_DECFSZ, pctemp);
9283 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9284 pic16_emitpLabel(tlbl1->key);
9286 pic16_popReleaseTempReg(pctemp,1);
9290 pic16_freeAsmop (right,NULL,ic,TRUE);
9291 pic16_freeAsmop(left,NULL,ic,TRUE);
9292 pic16_freeAsmop(result,NULL,ic,TRUE);
9296 /*-----------------------------------------------------------------*/
9297 /* genrshOne - right shift a one byte quantity by known count */
9298 /*-----------------------------------------------------------------*/
9299 static void genrshOne (operand *result, operand *left,
9300 int shCount, int sign)
9302 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9303 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
9306 /*-----------------------------------------------------------------*/
9307 /* genrshTwo - right shift two bytes by known amount != 0 */
9308 /*-----------------------------------------------------------------*/
9309 static void genrshTwo (operand *result,operand *left,
9310 int shCount, int sign)
9312 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
9313 /* if shCount >= 8 */
9317 shiftR1Left2Result(left, MSB16, result, LSB,
9320 movLeft2Result(left, MSB16, result, LSB);
9322 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
9325 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9326 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
9330 /* 1 <= shCount <= 7 */
9332 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
9335 /*-----------------------------------------------------------------*/
9336 /* shiftRLong - shift right one long from left to result */
9337 /* offl = LSB or MSB16 */
9338 /*-----------------------------------------------------------------*/
9339 static void shiftRLong (operand *left, int offl,
9340 operand *result, int sign)
9342 int size = AOP_SIZE(result);
9343 int same = pic16_sameRegs(AOP(left),AOP(result));
9345 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
9347 if (same && (offl == MSB16)) { //shift one byte right
9348 for(i=MSB16;i<size;i++) {
9349 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
9350 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
9355 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
9361 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
9363 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
9364 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
9368 /* add sign of "a" */
9369 pic16_addSign(result, MSB32, sign);
9373 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
9375 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
9376 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
9380 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
9382 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
9383 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
9387 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
9390 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
9391 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
9396 /*-----------------------------------------------------------------*/
9397 /* genrshFour - shift four byte by a known amount != 0 */
9398 /*-----------------------------------------------------------------*/
9399 static void genrshFour (operand *result, operand *left,
9400 int shCount, int sign)
9402 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9403 /* if shifting more that 3 bytes */
9404 if(shCount >= 24 ) {
9407 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
9409 movLeft2Result(left, MSB32, result, LSB);
9411 pic16_addSign(result, MSB16, sign);
9413 else if(shCount >= 16){
9416 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
9418 movLeft2Result(left, MSB24, result, LSB);
9419 movLeft2Result(left, MSB32, result, MSB16);
9421 pic16_addSign(result, MSB24, sign);
9423 else if(shCount >= 8){
9426 shiftRLong(left, MSB16, result, sign);
9427 else if(shCount == 0){
9428 movLeft2Result(left, MSB16, result, LSB);
9429 movLeft2Result(left, MSB24, result, MSB16);
9430 movLeft2Result(left, MSB32, result, MSB24);
9431 pic16_addSign(result, MSB32, sign);
9433 else{ //shcount >= 2
9434 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
9435 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
9436 /* the last shift is signed */
9437 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
9438 pic16_addSign(result, MSB32, sign);
9441 else{ /* 1 <= shCount <= 7 */
9443 shiftRLong(left, LSB, result, sign);
9445 shiftRLong(result, LSB, result, sign);
9448 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
9449 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
9450 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
9455 /*-----------------------------------------------------------------*/
9456 /* genRightShiftLiteral - right shifting by known count */
9457 /*-----------------------------------------------------------------*/
9458 static void genRightShiftLiteral (operand *left,
9464 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
9467 pic16_freeAsmop(right,NULL,ic,TRUE);
9469 pic16_aopOp(left,ic,FALSE);
9470 pic16_aopOp(result,ic,FALSE);
9472 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
9475 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
9479 lsize = pic16_getDataSize(left);
9480 res_size = pic16_getDataSize(result);
9481 /* test the LEFT size !!! */
9483 /* I suppose that the left size >= result size */
9486 movLeft2Result(left, lsize, result, res_size);
9489 else if(shCount >= (lsize * 8)){
9492 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
9494 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9495 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
9500 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
9501 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9502 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9504 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
9509 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
9516 genrshOne (result,left,shCount,sign);
9520 genrshTwo (result,left,shCount,sign);
9524 genrshFour (result,left,shCount,sign);
9532 pic16_freeAsmop(left,NULL,ic,TRUE);
9533 pic16_freeAsmop(result,NULL,ic,TRUE);
9536 /*-----------------------------------------------------------------*/
9537 /* genSignedRightShift - right shift of signed number */
9538 /*-----------------------------------------------------------------*/
9539 static void genSignedRightShift (iCode *ic)
9541 operand *right, *left, *result;
9544 symbol *tlbl, *tlbl1 ;
9547 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
9549 /* we do it the hard way put the shift count in b
9550 and loop thru preserving the sign */
9551 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9553 right = IC_RIGHT(ic);
9555 result = IC_RESULT(ic);
9557 pic16_aopOp(right,ic,FALSE);
9558 pic16_aopOp(left,ic,FALSE);
9559 pic16_aopOp(result,ic,FALSE);
9562 if ( AOP_TYPE(right) == AOP_LIT) {
9563 genRightShiftLiteral (left,right,result,ic,1);
9566 /* shift count is unknown then we have to form
9567 a loop get the loop count in B : Note: we take
9568 only the lower order byte since shifting
9569 more that 32 bits make no sense anyway, ( the
9570 largest size of an object can be only 32 bits ) */
9572 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9573 //pic16_emitcode("inc","b");
9574 //pic16_freeAsmop (right,NULL,ic,TRUE);
9575 //pic16_aopOp(left,ic,FALSE);
9576 //pic16_aopOp(result,ic,FALSE);
9578 /* now move the left to the result if they are not the
9580 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9581 AOP_SIZE(result) > 1) {
9583 size = AOP_SIZE(result);
9587 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9588 if (*l == '@' && IS_AOP_PREG(result)) {
9590 pic16_emitcode("mov","a,%s",l);
9591 pic16_aopPut(AOP(result),"a",offset);
9593 pic16_aopPut(AOP(result),l,offset);
9595 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
9596 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9602 /* mov the highest order bit to OVR */
9603 tlbl = newiTempLabel(NULL);
9604 tlbl1= newiTempLabel(NULL);
9606 size = AOP_SIZE(result);
9609 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9611 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9613 /* offset should be 0, 1 or 3 */
9614 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
9616 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9618 pic16_emitpcode(POC_MOVWF, pctemp);
9621 pic16_emitpLabel(tlbl->key);
9623 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
9624 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
9627 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
9630 pic16_emitpcode(POC_DECFSZ, pctemp);
9631 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9632 pic16_emitpLabel(tlbl1->key);
9634 pic16_popReleaseTempReg(pctemp,1);
9636 size = AOP_SIZE(result);
9638 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
9639 pic16_emitcode("rlc","a");
9640 pic16_emitcode("mov","ov,c");
9641 /* if it is only one byte then */
9643 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9645 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9646 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9647 pic16_emitcode("mov","c,ov");
9648 pic16_emitcode("rrc","a");
9649 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9650 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9651 pic16_aopPut(AOP(result),"a",0);
9655 reAdjustPreg(AOP(result));
9656 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9657 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9658 pic16_emitcode("mov","c,ov");
9660 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9662 pic16_emitcode("rrc","a");
9663 pic16_aopPut(AOP(result),"a",offset--);
9665 reAdjustPreg(AOP(result));
9666 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9667 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9672 pic16_freeAsmop(left,NULL,ic,TRUE);
9673 pic16_freeAsmop(result,NULL,ic,TRUE);
9674 pic16_freeAsmop(right,NULL,ic,TRUE);
9677 /*-----------------------------------------------------------------*/
9678 /* genRightShift - generate code for right shifting */
9679 /*-----------------------------------------------------------------*/
9680 static void genRightShift (iCode *ic)
9682 operand *right, *left, *result;
9686 symbol *tlbl, *tlbl1 ;
9688 /* if signed then we do it the hard way preserve the
9689 sign bit moving it inwards */
9690 letype = getSpec(operandType(IC_LEFT(ic)));
9691 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9693 if (!SPEC_USIGN(letype)) {
9694 genSignedRightShift (ic);
9698 /* signed & unsigned types are treated the same : i.e. the
9699 signed is NOT propagated inwards : quoting from the
9700 ANSI - standard : "for E1 >> E2, is equivalent to division
9701 by 2**E2 if unsigned or if it has a non-negative value,
9702 otherwise the result is implementation defined ", MY definition
9703 is that the sign does not get propagated */
9705 right = IC_RIGHT(ic);
9707 result = IC_RESULT(ic);
9709 pic16_aopOp(right,ic,FALSE);
9711 /* if the shift count is known then do it
9712 as efficiently as possible */
9713 if (AOP_TYPE(right) == AOP_LIT) {
9714 genRightShiftLiteral (left,right,result,ic, 0);
9718 /* shift count is unknown then we have to form
9719 a loop get the loop count in B : Note: we take
9720 only the lower order byte since shifting
9721 more that 32 bits make no sense anyway, ( the
9722 largest size of an object can be only 32 bits ) */
9724 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9725 pic16_emitcode("inc","b");
9726 pic16_aopOp(left,ic,FALSE);
9727 pic16_aopOp(result,ic,FALSE);
9729 /* now move the left to the result if they are not the
9731 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9732 AOP_SIZE(result) > 1) {
9734 size = AOP_SIZE(result);
9737 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9738 if (*l == '@' && IS_AOP_PREG(result)) {
9740 pic16_emitcode("mov","a,%s",l);
9741 pic16_aopPut(AOP(result),"a",offset);
9743 pic16_aopPut(AOP(result),l,offset);
9748 tlbl = newiTempLabel(NULL);
9749 tlbl1= newiTempLabel(NULL);
9750 size = AOP_SIZE(result);
9753 /* if it is only one byte then */
9756 tlbl = newiTempLabel(NULL);
9757 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9758 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9759 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9762 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9763 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9764 pic16_emitpLabel(tlbl->key);
9765 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9766 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9768 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9773 reAdjustPreg(AOP(result));
9774 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9775 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9778 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9780 pic16_emitcode("rrc","a");
9781 pic16_aopPut(AOP(result),"a",offset--);
9783 reAdjustPreg(AOP(result));
9785 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9786 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9789 pic16_freeAsmop(left,NULL,ic,TRUE);
9790 pic16_freeAsmop (right,NULL,ic,TRUE);
9791 pic16_freeAsmop(result,NULL,ic,TRUE);
9795 void pic16_loadFSR0(operand *op)
9797 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9800 /*-----------------------------------------------------------------*/
9801 /* genUnpackBits - generates code for unpacking bits */
9802 /*-----------------------------------------------------------------*/
9803 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
9810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9811 etype = getSpec(operandType(result));
9813 /* the following call to pic16_loadFSR0 is temporary until
9814 * optimization to handle single bit assignments is added
9815 * to the function. Until then use the old safe way! -- VR */
9816 pic16_loadFSR0( left );
9818 /* read the first byte */
9825 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9828 pic16_emitcode("clr","a");
9829 pic16_emitcode("movc","a","@a+dptr");
9834 /* if we have bitdisplacement then it fits */
9835 /* into this byte completely or if length is */
9836 /* less than a byte */
9837 if ((shCnt = SPEC_BSTR(etype)) ||
9838 (SPEC_BLEN(etype) <= 8)) {
9840 /* shift right acc */
9843 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9844 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
9846 /* VR -- normally I would use the following, but since we use the hack,
9847 * to avoid the masking from AccRsh, why not mask it right now? */
9850 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
9853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9859 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9860 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9863 /* bit field did not fit in a byte */
9864 rlen = SPEC_BLEN(etype) - 8;
9865 pic16_aopPut(AOP(result),"a",offset++);
9872 pic16_emitcode("inc","%s",rname);
9873 pic16_emitcode("mov","a,@%s",rname);
9877 pic16_emitcode("inc","%s",rname);
9878 pic16_emitcode("movx","a,@%s",rname);
9882 pic16_emitcode("inc","dptr");
9883 pic16_emitcode("movx","a,@dptr");
9887 pic16_emitcode("clr","a");
9888 pic16_emitcode("inc","dptr");
9889 pic16_emitcode("movc","a","@a+dptr");
9893 pic16_emitcode("inc","dptr");
9894 pic16_emitcode("lcall","__gptrget");
9899 /* if we are done */
9903 pic16_aopPut(AOP(result),"a",offset++);
9908 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9909 pic16_aopPut(AOP(result),"a",offset);
9916 static void genDataPointerGet(operand *left,
9920 int size, offset = 0, leoffset=0 ;
9922 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9923 pic16_aopOp(result, ic, FALSE);
9925 size = AOP_SIZE(result);
9926 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9930 /* The following tests may save a redudant movff instruction when
9931 * accessing unions */
9933 /* if they are the same */
9934 if (operandsEqu (left, result)) {
9935 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9941 /* if they are the same registers */
9942 if (pic16_sameRegs(AOP(left),AOP(result))) {
9943 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9949 if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
9950 pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
9951 DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
9958 if ( AOP_TYPE(left) == AOP_PCODE) {
9959 fprintf(stderr,"genDataPointerGet %s, %d\n",
9960 AOP(left)->aopu.pcop->name,
9961 (AOP(left)->aopu.pcop->type == PO_DIR)?
9962 PCOR(AOP(left)->aopu.pcop)->instance:
9963 PCOI(AOP(left)->aopu.pcop)->offset);
9967 if(AOP(left)->aopu.pcop->type == PO_DIR)
9968 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
9970 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9973 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
9975 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
9976 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
9977 mov2w(AOP(left), offset); // patch 8
9978 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
9980 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
9981 pic16_popGet(AOP(left), offset), //patch 8
9982 pic16_popGet(AOP(result), offset)));
9990 pic16_freeAsmop(result,NULL,ic,TRUE);
9995 /*-----------------------------------------------------------------*/
9996 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
9997 /*-----------------------------------------------------------------*/
9998 static void genNearPointerGet (operand *left,
10003 //regs *preg = NULL ;
10004 sym_link *rtype, *retype;
10005 sym_link *ltype = operandType(left);
10007 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10008 rtype = operandType(result);
10009 retype= getSpec(rtype);
10011 pic16_aopOp(left,ic,FALSE);
10013 // pic16_DumpOp("(left)",left);
10014 // pic16_DumpOp("(result)",result);
10016 /* if left is rematerialisable and
10017 * result is not bit variable type and
10018 * the left is pointer to data space i.e
10019 * lower 128 bytes of space */
10020 if (AOP_TYPE(left) == AOP_PCODE
10021 && !IS_BITFIELD(retype)
10022 && DCL_TYPE(ltype) == POINTER) {
10024 genDataPointerGet (left,result,ic);
10025 pic16_freeAsmop(left, NULL, ic, TRUE);
10029 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10031 /* if the value is already in a pointer register
10032 * then don't need anything more */
10033 if (!AOP_INPREG(AOP(left))) {
10034 /* otherwise get a free pointer register */
10035 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10037 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
10038 if( (AOP_TYPE(left) == AOP_PCODE)
10039 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10040 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
10042 if(!IS_BITFIELD(retype))
10043 pic16_loadFSR0( left ); // patch 10
10045 // set up FSR0 with address from left
10046 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10047 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10051 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10053 pic16_aopOp (result,ic,FALSE);
10055 /* if bitfield then unpack the bits */
10056 if (IS_BITFIELD(retype))
10057 genUnpackBits (result, left, NULL, POINTER);
10059 /* we have can just get the values */
10060 int size = AOP_SIZE(result);
10063 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10066 /* fsr0 is loaded already -- VR */
10067 // pic16_loadFSR0( left );
10069 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
10070 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
10074 pic16_emitpcode(POC_MOVFF,
10075 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
10076 pic16_popGet(AOP(result), offset++)));
10078 pic16_emitpcode(POC_MOVFF,
10079 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
10080 pic16_popGet(AOP(result), offset++)));
10084 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
10085 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
10087 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
10091 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
10093 pic16_emitcode("mov","a,@%s",rname);
10094 pic16_aopPut(AOP(result),"a",offset);
10096 sprintf(buffer,"@%s",rname);
10097 pic16_aopPut(AOP(result),buffer,offset);
10101 pic16_emitcode("inc","%s",rname);
10106 /* now some housekeeping stuff */
10108 /* we had to allocate for this iCode */
10109 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10110 pic16_freeAsmop(NULL,aop,ic,TRUE);
10112 /* we did not allocate which means left
10113 already in a pointer register, then
10114 if size > 0 && this could be used again
10115 we have to point it back to where it
10117 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10118 if (AOP_SIZE(result) > 1 &&
10119 !OP_SYMBOL(left)->remat &&
10120 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10122 // int size = AOP_SIZE(result) - 1;
10124 // pic16_emitcode("dec","%s",rname);
10129 pic16_freeAsmop(left,NULL,ic,TRUE);
10130 pic16_freeAsmop(result,NULL,ic,TRUE);
10134 /*-----------------------------------------------------------------*/
10135 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
10136 /*-----------------------------------------------------------------*/
10137 static void genPagedPointerGet (operand *left,
10142 regs *preg = NULL ;
10144 sym_link *rtype, *retype;
10146 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10148 rtype = operandType(result);
10149 retype= getSpec(rtype);
10151 pic16_aopOp(left,ic,FALSE);
10153 /* if the value is already in a pointer register
10154 then don't need anything more */
10155 if (!AOP_INPREG(AOP(left))) {
10156 /* otherwise get a free pointer register */
10158 preg = getFreePtr(ic,&aop,FALSE);
10159 pic16_emitcode("mov","%s,%s",
10161 pic16_aopGet(AOP(left),0,FALSE,TRUE));
10162 rname = preg->name ;
10164 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10166 pic16_freeAsmop(left,NULL,ic,TRUE);
10167 pic16_aopOp (result,ic,FALSE);
10169 /* if bitfield then unpack the bits */
10170 if (IS_BITFIELD(retype))
10171 genUnpackBits (result,left,rname,PPOINTER);
10173 /* we have can just get the values */
10174 int size = AOP_SIZE(result);
10179 pic16_emitcode("movx","a,@%s",rname);
10180 pic16_aopPut(AOP(result),"a",offset);
10185 pic16_emitcode("inc","%s",rname);
10189 /* now some housekeeping stuff */
10191 /* we had to allocate for this iCode */
10192 pic16_freeAsmop(NULL,aop,ic,TRUE);
10194 /* we did not allocate which means left
10195 already in a pointer register, then
10196 if size > 0 && this could be used again
10197 we have to point it back to where it
10199 if (AOP_SIZE(result) > 1 &&
10200 !OP_SYMBOL(left)->remat &&
10201 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10203 int size = AOP_SIZE(result) - 1;
10205 pic16_emitcode("dec","%s",rname);
10210 pic16_freeAsmop(result,NULL,ic,TRUE);
10215 /*-----------------------------------------------------------------*/
10216 /* genFarPointerGet - gget value from far space */
10217 /*-----------------------------------------------------------------*/
10218 static void genFarPointerGet (operand *left,
10219 operand *result, iCode *ic)
10222 sym_link *retype = getSpec(operandType(result));
10224 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10226 pic16_aopOp(left,ic,FALSE);
10228 /* if the operand is already in dptr
10229 then we do nothing else we move the value to dptr */
10230 if (AOP_TYPE(left) != AOP_STR) {
10231 /* if this is remateriazable */
10232 if (AOP_TYPE(left) == AOP_IMMD)
10233 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10234 else { /* we need to get it byte by byte */
10235 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10236 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10237 if (options.model == MODEL_FLAT24)
10239 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10243 /* so dptr know contains the address */
10244 pic16_freeAsmop(left,NULL,ic,TRUE);
10245 pic16_aopOp(result,ic,FALSE);
10247 /* if bit then unpack */
10248 if (IS_BITFIELD(retype))
10249 genUnpackBits(result,left,"dptr",FPOINTER);
10251 size = AOP_SIZE(result);
10255 pic16_emitcode("movx","a,@dptr");
10256 pic16_aopPut(AOP(result),"a",offset++);
10258 pic16_emitcode("inc","dptr");
10262 pic16_freeAsmop(result,NULL,ic,TRUE);
10265 /*-----------------------------------------------------------------*/
10266 /* genCodePointerGet - get value from code space */
10267 /*-----------------------------------------------------------------*/
10268 static void genCodePointerGet (operand *left,
10269 operand *result, iCode *ic)
10272 sym_link *retype = getSpec(operandType(result));
10274 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10276 pic16_aopOp(left,ic,FALSE);
10278 /* if the operand is already in dptr
10279 then we do nothing else we move the value to dptr */
10280 if (AOP_TYPE(left) != AOP_STR) {
10281 /* if this is remateriazable */
10282 if (AOP_TYPE(left) == AOP_IMMD)
10283 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10284 else { /* we need to get it byte by byte */
10285 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10286 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10287 if (options.model == MODEL_FLAT24)
10289 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10293 /* so dptr know contains the address */
10294 pic16_freeAsmop(left,NULL,ic,TRUE);
10295 pic16_aopOp(result,ic,FALSE);
10297 /* if bit then unpack */
10298 if (IS_BITFIELD(retype))
10299 genUnpackBits(result,left,"dptr",CPOINTER);
10301 size = AOP_SIZE(result);
10305 pic16_emitcode("clr","a");
10306 pic16_emitcode("movc","a,@a+dptr");
10307 pic16_aopPut(AOP(result),"a",offset++);
10309 pic16_emitcode("inc","dptr");
10313 pic16_freeAsmop(result,NULL,ic,TRUE);
10317 /*-----------------------------------------------------------------*/
10318 /* genGenPointerGet - gget value from generic pointer space */
10319 /*-----------------------------------------------------------------*/
10320 static void genGenPointerGet (operand *left,
10321 operand *result, iCode *ic)
10323 int size, offset, lit;
10324 sym_link *retype = getSpec(operandType(result));
10326 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10327 pic16_aopOp(left,ic,FALSE);
10328 pic16_aopOp(result,ic,FALSE);
10329 size = AOP_SIZE(result);
10331 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10333 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10335 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10336 // load FSR0 from immediate
10337 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10339 // pic16_loadFSR0( left );
10344 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10346 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10353 else { /* we need to get it byte by byte */
10354 // set up FSR0 with address from left
10355 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10356 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10362 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10364 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10371 /* if bit then unpack */
10372 if (IS_BITFIELD(retype))
10373 genUnpackBits(result,left,"BAD",GPOINTER);
10376 pic16_freeAsmop(left,NULL,ic,TRUE);
10377 pic16_freeAsmop(result,NULL,ic,TRUE);
10382 extern set *externs;
10384 /*-----------------------------------------------------------------*/
10385 /* genGenPointerGet - gget value from generic pointer space */
10386 /*-----------------------------------------------------------------*/
10387 static void genGenPointerGet (operand *left,
10388 operand *result, iCode *ic)
10390 int size, offset, lit;
10391 sym_link *retype = getSpec(operandType(result));
10394 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10395 pic16_aopOp(left,ic,FALSE);
10396 pic16_aopOp(result,ic,FALSE);
10397 size = AOP_SIZE(result);
10399 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10401 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10403 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10404 // load FSR0 from immediate
10405 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10407 werror(W_POSSBUG2, __FILE__, __LINE__);
10412 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10414 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10421 } else { /* we need to get it byte by byte */
10423 /* set up WREG:PRODL:FSR0L with address from left */
10424 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10425 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
10426 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
10429 case 1: strcpy(fgptrget, "__gptrget1"); break;
10430 case 2: strcpy(fgptrget, "__gptrget2"); break;
10431 case 3: strcpy(fgptrget, "__gptrget3"); break;
10432 case 4: strcpy(fgptrget, "__gptrget4"); break;
10434 werror(W_POSSBUG2, __FILE__, __LINE__);
10438 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget ));
10440 assignResultValue(result, 1);
10445 sym = newSymbol( fgptrget, 0 );
10446 strcpy(sym->rname, fgptrget);
10447 checkAddSym(&externs, sym);
10449 // fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
10455 /* if bit then unpack */
10456 if (IS_BITFIELD(retype))
10457 genUnpackBits(result,left,"BAD",GPOINTER);
10460 pic16_freeAsmop(left,NULL,ic,TRUE);
10461 pic16_freeAsmop(result,NULL,ic,TRUE);
10464 /*-----------------------------------------------------------------*/
10465 /* genConstPointerGet - get value from const generic pointer space */
10466 /*-----------------------------------------------------------------*/
10467 static void genConstPointerGet (operand *left,
10468 operand *result, iCode *ic)
10470 //sym_link *retype = getSpec(operandType(result));
10471 // symbol *albl = newiTempLabel(NULL); // patch 15
10472 // symbol *blbl = newiTempLabel(NULL); //
10473 // PIC_OPCODE poc; // patch 15
10477 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10478 pic16_aopOp(left,ic,FALSE);
10479 pic16_aopOp(result,ic,TRUE);
10480 size = AOP_SIZE(result);
10482 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10484 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
10486 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
10487 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
10488 pic16_emitpLabel(albl->key);
10490 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
10492 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
10493 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
10494 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
10495 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
10496 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
10498 pic16_emitpLabel(blbl->key);
10500 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
10504 // set up table pointer
10505 if( (AOP_TYPE(left) == AOP_PCODE)
10506 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10507 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
10509 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
10510 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
10511 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
10512 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
10513 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
10514 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
10518 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
10519 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
10520 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
10526 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
10527 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
10531 pic16_freeAsmop(left,NULL,ic,TRUE);
10532 pic16_freeAsmop(result,NULL,ic,TRUE);
10537 /*-----------------------------------------------------------------*/
10538 /* genPointerGet - generate code for pointer get */
10539 /*-----------------------------------------------------------------*/
10540 static void genPointerGet (iCode *ic)
10542 operand *left, *result ;
10543 sym_link *type, *etype;
10546 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10548 left = IC_LEFT(ic);
10549 result = IC_RESULT(ic) ;
10551 /* depending on the type of pointer we need to
10552 move it to the correct pointer register */
10553 type = operandType(left);
10554 etype = getSpec(type);
10557 if (IS_PTR_CONST(type))
10559 if (IS_CODEPTR(type))
10561 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
10563 /* if left is of type of pointer then it is simple */
10564 if (IS_PTR(type) && !IS_FUNC(type->next))
10565 p_type = DCL_TYPE(type);
10567 /* we have to go by the storage class */
10568 p_type = PTR_TYPE(SPEC_OCLS(etype));
10570 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
10572 if (SPEC_OCLS(etype)->codesp ) {
10573 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
10574 //p_type = CPOINTER ;
10577 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
10578 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
10579 /*p_type = FPOINTER ;*/
10581 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
10582 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
10583 /* p_type = PPOINTER; */
10585 if (SPEC_OCLS(etype) == idata )
10586 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
10587 /* p_type = IPOINTER; */
10589 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
10590 /* p_type = POINTER ; */
10593 /* now that we have the pointer type we assign
10594 the pointer values */
10599 genNearPointerGet (left,result,ic);
10603 genPagedPointerGet(left,result,ic);
10607 genFarPointerGet (left,result,ic);
10611 genConstPointerGet (left,result,ic);
10612 //pic16_emitcodePointerGet (left,result,ic);
10617 if (IS_PTR_CONST(type))
10618 genConstPointerGet (left,result,ic);
10621 genGenPointerGet (left,result,ic);
10625 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10626 "genPointerGet: illegal pointer type");
10632 /*-----------------------------------------------------------------*/
10633 /* genPackBits - generates code for packed bit storage */
10634 /*-----------------------------------------------------------------*/
10635 static void genPackBits (sym_link *etype , operand *result,
10637 char *rname, int p_type)
10645 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10646 blen = SPEC_BLEN(etype);
10647 bstr = SPEC_BSTR(etype);
10649 if(AOP_TYPE(right) == AOP_LIT) {
10650 if((blen == 1) && (bstr < 8)) {
10652 /* it is a single bit, so use the appropriate bit instructions */
10654 DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
10656 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10657 // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10658 if((p_type == POINTER) && (result)) {
10659 /* workaround to reduce the extra lfsr instruction */
10661 pic16_emitpcode(POC_BSF,
10662 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10664 pic16_emitpcode(POC_BCF,
10665 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10670 pic16_emitpcode(POC_BSF,
10671 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10673 pic16_emitpcode(POC_BCF,
10674 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10681 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
10684 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
10686 /* if the bit lenth is less than or */
10687 /* it exactly fits a byte then */
10688 if((shCnt=SPEC_BSTR(etype))
10689 || SPEC_BLEN(etype) <= 8 ) {
10691 /* shift left acc */
10694 /* using PRODL as a temporary register here */
10695 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
10701 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10702 // pic16_emitcode ("mov","b,a");
10703 // pic16_emitcode("mov","a,@%s",rname);
10707 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
10708 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
10709 (unsigned char)(0xff >> (8-bstr))) ));
10710 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
10711 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10718 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
10719 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
10724 if ( SPEC_BLEN(etype) <= 8 )
10727 pic16_emitcode("inc","%s",rname);
10728 rLen = SPEC_BLEN(etype) ;
10732 /* now generate for lengths greater than one byte */
10735 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
10745 pic16_emitcode("mov","@%s,a",rname);
10747 pic16_emitcode("mov","@%s,%s",rname,l);
10752 pic16_emitcode("movx","@dptr,a");
10757 DEBUGpic16_emitcode(";lcall","__gptrput");
10760 pic16_emitcode ("inc","%s",rname);
10765 /* last last was not complete */
10767 /* save the byte & read byte */
10770 pic16_emitcode ("mov","b,a");
10771 pic16_emitcode("mov","a,@%s",rname);
10775 pic16_emitcode ("mov","b,a");
10776 pic16_emitcode("movx","a,@dptr");
10780 pic16_emitcode ("push","b");
10781 pic16_emitcode ("push","acc");
10782 pic16_emitcode ("lcall","__gptrget");
10783 pic16_emitcode ("pop","b");
10787 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
10788 pic16_emitcode ("orl","a,b");
10791 if (p_type == GPOINTER)
10792 pic16_emitcode("pop","b");
10797 pic16_emitcode("mov","@%s,a",rname);
10801 pic16_emitcode("movx","@dptr,a");
10805 DEBUGpic16_emitcode(";lcall","__gptrput");
10809 /*-----------------------------------------------------------------*/
10810 /* genDataPointerSet - remat pointer to data space */
10811 /*-----------------------------------------------------------------*/
10812 static void genDataPointerSet(operand *right,
10816 int size, offset = 0, resoffset=0 ;
10818 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10819 pic16_aopOp(right,ic,FALSE);
10821 size = AOP_SIZE(right);
10823 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
10826 if ( AOP_TYPE(result) == AOP_PCODE) {
10827 fprintf(stderr,"genDataPointerSet %s, %d\n",
10828 AOP(result)->aopu.pcop->name,
10829 (AOP(result)->aopu.pcop->type == PO_DIR)?
10830 PCOR(AOP(result)->aopu.pcop)->instance:
10831 PCOI(AOP(result)->aopu.pcop)->offset);
10835 if(AOP(result)->aopu.pcop->type == PO_DIR)
10836 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
10839 if (AOP_TYPE(right) == AOP_LIT) {
10842 if(!IS_FLOAT(operandType( right )))
10843 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
10846 unsigned long lit_int;
10850 /* take care if literal is a float */
10851 info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
10852 lit = info.lit_int;
10855 lit = lit >> (8*offset);
10857 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
10858 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
10860 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
10863 mov2w(AOP(right), offset);
10864 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
10870 pic16_freeAsmop(right,NULL,ic,TRUE);
10875 /*-----------------------------------------------------------------*/
10876 /* genNearPointerSet - pic16_emitcode for near pointer put */
10877 /*-----------------------------------------------------------------*/
10878 static void genNearPointerSet (operand *right,
10885 sym_link *ptype = operandType(result);
10886 sym_link *resetype;
10888 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10889 retype= getSpec(operandType(right));
10890 resetype = getSpec(operandType(result));
10892 pic16_aopOp(result,ic,FALSE);
10894 /* if the result is rematerializable &
10895 * in data space & not a bit variable */
10897 /* and result is not a bit variable */
10898 if (AOP_TYPE(result) == AOP_PCODE
10899 // && AOP_TYPE(result) == AOP_IMMD
10900 && DCL_TYPE(ptype) == POINTER
10901 && !IS_BITFIELD(retype)
10902 && !IS_BITFIELD(resetype)) {
10904 genDataPointerSet (right,result,ic);
10905 pic16_freeAsmop(result,NULL,ic,TRUE);
10909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10910 pic16_aopOp(right,ic,FALSE);
10911 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10913 /* if the value is already in a pointer register
10914 * then don't need anything more */
10915 if (!AOP_INPREG(AOP(result))) {
10916 /* otherwise get a free pointer register */
10917 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10919 if( (AOP_TYPE(result) == AOP_PCODE)
10920 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
10921 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
10923 if(!IS_BITFIELD(resetype))
10924 pic16_loadFSR0( result ); // patch 10
10926 // set up FSR0 with address of result
10927 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10928 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10933 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10937 /* if bitfield then unpack the bits */
10938 if (IS_BITFIELD(resetype)) {
10939 genPackBits (resetype, result, right, NULL, POINTER);
10941 /* we have can just get the values */
10942 int size = AOP_SIZE(right);
10945 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10947 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10950 //pic16_emitcode("mov","@%s,a",rname);
10951 pic16_emitcode("movf","indf0,w ;1");
10954 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
10955 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
10957 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
10959 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
10961 } else { // no literal //
10963 pic16_emitpcode(POC_MOVFF, //
10964 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
10965 pic16_popCopyReg(&pic16_pc_postinc0))); //
10967 pic16_emitpcode(POC_MOVFF, //
10968 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
10969 pic16_popCopyReg(&pic16_pc_indf0))); //
10977 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10978 /* now some housekeeping stuff */
10980 /* we had to allocate for this iCode */
10981 pic16_freeAsmop(NULL,aop,ic,TRUE);
10983 /* we did not allocate which means left
10984 * already in a pointer register, then
10985 * if size > 0 && this could be used again
10986 * we have to point it back to where it
10988 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10989 if (AOP_SIZE(right) > 1
10990 && !OP_SYMBOL(result)->remat
10991 && ( OP_SYMBOL(result)->liveTo > ic->seq
10994 int size = AOP_SIZE(right) - 1;
10997 pic16_emitcode("decf","fsr0,f");
10998 //pic16_emitcode("dec","%s",rname);
11002 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11005 pic16_freeAsmop(right,NULL,ic,TRUE);
11006 pic16_freeAsmop(result,NULL,ic,TRUE);
11009 /*-----------------------------------------------------------------*/
11010 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
11011 /*-----------------------------------------------------------------*/
11012 static void genPagedPointerSet (operand *right,
11017 regs *preg = NULL ;
11021 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11023 retype= getSpec(operandType(right));
11025 pic16_aopOp(result,ic,FALSE);
11027 /* if the value is already in a pointer register
11028 then don't need anything more */
11029 if (!AOP_INPREG(AOP(result))) {
11030 /* otherwise get a free pointer register */
11032 preg = getFreePtr(ic,&aop,FALSE);
11033 pic16_emitcode("mov","%s,%s",
11035 pic16_aopGet(AOP(result),0,FALSE,TRUE));
11036 rname = preg->name ;
11038 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11040 pic16_freeAsmop(result,NULL,ic,TRUE);
11041 pic16_aopOp (right,ic,FALSE);
11043 /* if bitfield then unpack the bits */
11044 if (IS_BITFIELD(retype))
11045 genPackBits (retype,result,right,rname,PPOINTER);
11047 /* we have can just get the values */
11048 int size = AOP_SIZE(right);
11052 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
11055 pic16_emitcode("movx","@%s,a",rname);
11058 pic16_emitcode("inc","%s",rname);
11064 /* now some housekeeping stuff */
11066 /* we had to allocate for this iCode */
11067 pic16_freeAsmop(NULL,aop,ic,TRUE);
11069 /* we did not allocate which means left
11070 already in a pointer register, then
11071 if size > 0 && this could be used again
11072 we have to point it back to where it
11074 if (AOP_SIZE(right) > 1 &&
11075 !OP_SYMBOL(result)->remat &&
11076 ( OP_SYMBOL(result)->liveTo > ic->seq ||
11078 int size = AOP_SIZE(right) - 1;
11080 pic16_emitcode("dec","%s",rname);
11085 pic16_freeAsmop(right,NULL,ic,TRUE);
11090 /*-----------------------------------------------------------------*/
11091 /* genFarPointerSet - set value from far space */
11092 /*-----------------------------------------------------------------*/
11093 static void genFarPointerSet (operand *right,
11094 operand *result, iCode *ic)
11097 sym_link *retype = getSpec(operandType(right));
11099 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11100 pic16_aopOp(result,ic,FALSE);
11102 /* if the operand is already in dptr
11103 then we do nothing else we move the value to dptr */
11104 if (AOP_TYPE(result) != AOP_STR) {
11105 /* if this is remateriazable */
11106 if (AOP_TYPE(result) == AOP_IMMD)
11107 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
11108 else { /* we need to get it byte by byte */
11109 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
11110 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
11111 if (options.model == MODEL_FLAT24)
11113 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
11117 /* so dptr know contains the address */
11118 pic16_freeAsmop(result,NULL,ic,TRUE);
11119 pic16_aopOp(right,ic,FALSE);
11121 /* if bit then unpack */
11122 if (IS_BITFIELD(retype))
11123 genPackBits(retype,result,right,"dptr",FPOINTER);
11125 size = AOP_SIZE(right);
11129 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11131 pic16_emitcode("movx","@dptr,a");
11133 pic16_emitcode("inc","dptr");
11137 pic16_freeAsmop(right,NULL,ic,TRUE);
11140 /*-----------------------------------------------------------------*/
11141 /* genGenPointerSet - set value from generic pointer space */
11142 /*-----------------------------------------------------------------*/
11144 static void genGenPointerSet (operand *right,
11145 operand *result, iCode *ic)
11147 int i, size, offset, lit;
11148 sym_link *retype = getSpec(operandType(right));
11150 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11152 pic16_aopOp(result,ic,FALSE);
11153 pic16_aopOp(right,ic,FALSE);
11154 size = AOP_SIZE(right);
11157 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11159 /* if the operand is already in dptr
11160 then we do nothing else we move the value to dptr */
11161 if (AOP_TYPE(result) != AOP_STR) {
11162 /* if this is remateriazable */
11163 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11164 // WARNING: anythig until "else" is untested!
11165 if (AOP_TYPE(result) == AOP_IMMD) {
11166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11167 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
11168 // load FSR0 from immediate
11169 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11173 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11175 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11181 else { /* we need to get it byte by byte */
11182 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11183 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11185 // set up FSR0 with address of result
11186 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11187 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11189 /* hack hack! see if this the FSR. If so don't load W */
11190 if(AOP_TYPE(right) != AOP_ACC) {
11192 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11194 if(AOP_TYPE(right) == AOP_LIT)
11197 // note: pic16_popGet handles sign extension
11198 for(i=0;i<size;i++) {
11199 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
11201 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
11203 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
11208 for(i=0;i<size;i++) {
11210 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11211 pic16_popCopyReg(&pic16_pc_postinc0)));
11213 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11214 pic16_popCopyReg(&pic16_pc_indf0)));
11220 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11221 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11223 } // if (AOP_TYPE(result) != AOP_IMMD)
11225 } // if (AOP_TYPE(result) != AOP_STR)
11226 /* so dptr know contains the address */
11229 /* if bit then unpack */
11230 if (IS_BITFIELD(retype))
11231 genPackBits(retype,result,right,"dptr",GPOINTER);
11233 size = AOP_SIZE(right);
11236 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11238 // set up FSR0 with address of result
11239 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11240 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11243 if (AOP_TYPE(right) == AOP_LIT) {
11244 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11246 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
11248 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11250 } else { // no literal
11252 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11254 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11262 pic16_freeAsmop(right,NULL,ic,TRUE);
11263 pic16_freeAsmop(result,NULL,ic,TRUE);
11267 static void genGenPointerSet (operand *right,
11268 operand *result, iCode *ic)
11271 sym_link *retype = getSpec(operandType(right));
11274 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11276 pic16_aopOp(result,ic,FALSE);
11277 pic16_aopOp(right,ic,FALSE);
11278 size = AOP_SIZE(right);
11280 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11283 /* if bit then unpack */
11284 if (IS_BITFIELD(retype)) {
11285 // pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11286 genPackBits(retype,result,right,"dptr",GPOINTER);
11290 size = AOP_SIZE(right);
11292 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11296 /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
11298 /* value of right+0 is placed on stack, which will be retrieved
11299 * by the support function this restoring the stack. The important
11300 * thing is that there is no need to manually restore stack pointer
11302 mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
11303 if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
11304 if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
11305 if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
11307 /* load address to write to in WREG:FSR0H:FSR0L */
11308 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
11309 pic16_popCopyReg(&pic16_pc_fsr0l)));
11310 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
11311 pic16_popCopyReg(&pic16_pc_prodl)));
11312 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
11315 /* put code here */
11317 case 1: strcpy(fgptrput, "__gptrput1"); break;
11318 case 2: strcpy(fgptrput, "__gptrput2"); break;
11319 case 3: strcpy(fgptrput, "__gptrput3"); break;
11320 case 4: strcpy(fgptrput, "__gptrput4"); break;
11322 werror(W_POSSBUG2, __FILE__, __LINE__);
11326 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput ));
11331 sym = newSymbol( fgptrput, 0 );
11332 strcpy(sym->rname, fgptrput);
11333 checkAddSym(&externs, sym);
11337 pic16_freeAsmop(right,NULL,ic,TRUE);
11338 pic16_freeAsmop(result,NULL,ic,TRUE);
11341 /*-----------------------------------------------------------------*/
11342 /* genPointerSet - stores the value into a pointer location */
11343 /*-----------------------------------------------------------------*/
11344 static void genPointerSet (iCode *ic)
11346 operand *right, *result ;
11347 sym_link *type, *etype;
11350 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11352 right = IC_RIGHT(ic);
11353 result = IC_RESULT(ic) ;
11355 /* depending on the type of pointer we need to
11356 move it to the correct pointer register */
11357 type = operandType(result);
11358 etype = getSpec(type);
11359 /* if left is of type of pointer then it is simple */
11360 if (IS_PTR(type) && !IS_FUNC(type->next)) {
11361 p_type = DCL_TYPE(type);
11364 /* we have to go by the storage class */
11365 p_type = PTR_TYPE(SPEC_OCLS(etype));
11367 /* if (SPEC_OCLS(etype)->codesp ) { */
11368 /* p_type = CPOINTER ; */
11371 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
11372 /* p_type = FPOINTER ; */
11374 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
11375 /* p_type = PPOINTER ; */
11377 /* if (SPEC_OCLS(etype) == idata ) */
11378 /* p_type = IPOINTER ; */
11380 /* p_type = POINTER ; */
11383 /* now that we have the pointer type we assign
11384 the pointer values */
11389 genNearPointerSet (right,result,ic);
11393 genPagedPointerSet (right,result,ic);
11397 genFarPointerSet (right,result,ic);
11401 genGenPointerSet (right,result,ic);
11405 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
11406 "genPointerSet: illegal pointer type");
11410 /*-----------------------------------------------------------------*/
11411 /* genIfx - generate code for Ifx statement */
11412 /*-----------------------------------------------------------------*/
11413 static void genIfx (iCode *ic, iCode *popIc)
11415 operand *cond = IC_COND(ic);
11418 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11420 pic16_aopOp(cond,ic,FALSE);
11422 /* get the value into acc */
11423 if (AOP_TYPE(cond) != AOP_CRY)
11424 pic16_toBoolean(cond);
11427 /* the result is now in the accumulator */
11428 pic16_freeAsmop(cond,NULL,ic,TRUE);
11430 /* if there was something to be popped then do it */
11434 /* if the condition is a bit variable */
11435 if (isbit && IS_ITEMP(cond) &&
11437 genIfxJump(ic,SPIL_LOC(cond)->rname);
11438 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
11441 if (isbit && !IS_ITEMP(cond))
11442 genIfxJump(ic,OP_SYMBOL(cond)->rname);
11444 genIfxJump(ic,"a");
11450 /*-----------------------------------------------------------------*/
11451 /* genAddrOf - generates code for address of */
11452 /*-----------------------------------------------------------------*/
11453 static void genAddrOf (iCode *ic)
11455 operand *result, *left;
11457 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
11458 pCodeOp *pcop0, *pcop1, *pcop2;
11460 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11462 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
11464 sym = OP_SYMBOL( IC_LEFT(ic) );
11467 /* get address of symbol on stack */
11468 DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
11470 fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__,
11471 OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack);
11474 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
11475 pic16_popCopyReg(&pic16_pc_fsr2l),
11476 pic16_popGet(AOP(result), 0)));
11477 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
11478 pic16_popCopyReg(&pic16_pc_fsr2h),
11479 pic16_popGet(AOP(result), 1)));
11481 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( OP_SYMBOL( IC_LEFT(ic))->stack ) /*+ _G.stack_lat*/);
11482 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 0));
11484 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 1));
11489 // if(pic16_debug_verbose) {
11490 // fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
11491 // __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
11494 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
11495 size = AOP_SIZE(IC_RESULT(ic));
11498 /* Assume that what we want the address of is in data space
11499 * since there is no stack on the PIC, yet! -- VR */
11501 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11502 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11503 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11506 pic16_emitpcode(POC_MOVLW, pcop0);
11507 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
11508 pic16_emitpcode(POC_MOVLW, pcop1);
11509 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
11510 pic16_emitpcode(POC_MOVLW, pcop2);
11511 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
11514 pic16_emitpcode(POC_MOVLW, pcop0);
11515 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11516 pic16_emitpcode(POC_MOVLW, pcop1);
11517 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
11519 pic16_emitpcode(POC_MOVLW, pcop0);
11520 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11523 pic16_freeAsmop(left, NULL, ic, FALSE);
11525 pic16_freeAsmop(result,NULL,ic,TRUE);
11530 /*-----------------------------------------------------------------*/
11531 /* genFarFarAssign - assignment when both are in far space */
11532 /*-----------------------------------------------------------------*/
11533 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
11535 int size = AOP_SIZE(right);
11538 /* first push the right side on to the stack */
11540 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11542 pic16_emitcode ("push","acc");
11545 pic16_freeAsmop(right,NULL,ic,FALSE);
11546 /* now assign DPTR to result */
11547 pic16_aopOp(result,ic,FALSE);
11548 size = AOP_SIZE(result);
11550 pic16_emitcode ("pop","acc");
11551 pic16_aopPut(AOP(result),"a",--offset);
11553 pic16_freeAsmop(result,NULL,ic,FALSE);
11558 /*-----------------------------------------------------------------*/
11559 /* genAssign - generate code for assignment */
11560 /*-----------------------------------------------------------------*/
11561 static void genAssign (iCode *ic)
11563 operand *result, *right;
11564 int size, offset,know_W;
11565 unsigned long lit = 0L;
11567 result = IC_RESULT(ic);
11568 right = IC_RIGHT(ic) ;
11570 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11572 /* if they are the same */
11573 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
11576 /* reversed order operands are aopOp'ed so that result operand
11577 * is effective in case right is a stack symbol. This maneauver
11578 * allows to use the _G.resDirect flag later */
11579 pic16_aopOp(result,ic,TRUE);
11580 pic16_aopOp(right,ic,FALSE);
11582 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11584 /* if they are the same registers */
11585 if (pic16_sameRegs(AOP(right),AOP(result)))
11588 /* if the result is a bit */
11589 if (AOP_TYPE(result) == AOP_CRY) {
11590 /* if the right size is a literal then
11591 we know what the value is */
11592 if (AOP_TYPE(right) == AOP_LIT) {
11594 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
11595 pic16_popGet(AOP(result),0));
11597 if (((int) operandLitValue(right)))
11598 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11599 AOP(result)->aopu.aop_dir,
11600 AOP(result)->aopu.aop_dir);
11602 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11603 AOP(result)->aopu.aop_dir,
11604 AOP(result)->aopu.aop_dir);
11608 /* the right is also a bit variable */
11609 if (AOP_TYPE(right) == AOP_CRY) {
11610 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11611 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11612 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11614 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11615 AOP(result)->aopu.aop_dir,
11616 AOP(result)->aopu.aop_dir);
11617 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
11618 AOP(right)->aopu.aop_dir,
11619 AOP(right)->aopu.aop_dir);
11620 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11621 AOP(result)->aopu.aop_dir,
11622 AOP(result)->aopu.aop_dir);
11626 /* we need to or */
11627 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11628 pic16_toBoolean(right);
11630 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11631 //pic16_aopPut(AOP(result),"a",0);
11635 /* bit variables done */
11637 size = AOP_SIZE(result);
11640 if(AOP_TYPE(right) == AOP_LIT) {
11641 if(!IS_FLOAT(operandType( right )))
11642 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
11645 unsigned long lit_int;
11649 /* take care if literal is a float */
11650 info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
11651 lit = info.lit_int;
11655 // fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
11656 // sizeof(unsigned long int), sizeof(float));
11658 if(AOP_TYPE(right) != AOP_LIT
11659 && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
11660 && !IS_FUNC(OP_SYM_TYPE(right))
11662 DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
11663 // fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
11665 // set up table pointer
11666 if( (AOP_TYPE(right) == AOP_PCODE)
11667 && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
11668 // || (AOP(right)->aopu.pcop->type == PO_DIR)
11672 // fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
11673 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
11674 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
11675 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
11676 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
11677 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
11678 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
11680 // fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
11681 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
11682 pic16_popCopyReg(&pic16_pc_tblptrl)));
11683 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
11684 pic16_popCopyReg(&pic16_pc_tblptrh)));
11685 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
11686 pic16_popCopyReg(&pic16_pc_tblptru)));
11689 size = min(AOP_SIZE(right), AOP_SIZE(result));
11691 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
11692 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
11693 pic16_popGet(AOP(result),offset)));
11697 if(AOP_SIZE(result) > AOP_SIZE(right)) {
11698 size = AOP_SIZE(result) - AOP_SIZE(right);
11700 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
11710 /* VR - What is this?! */
11711 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
11712 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11713 if(aopIdx(AOP(result),0) == 4) {
11715 /* this is a workaround to save value of right into wreg too,
11716 * value of wreg is going to be used later */
11717 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11718 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11719 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11723 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
11729 DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
11730 if(AOP_TYPE(right) == AOP_LIT) {
11732 if(know_W != (lit&0xff))
11733 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
11735 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11737 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11741 } else if (AOP_TYPE(right) == AOP_CRY) {
11742 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11744 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
11745 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
11747 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
11748 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11749 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11751 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11753 if(!_G.resDirect) /* use this aopForSym feature */
11754 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
11761 pic16_freeAsmop (right,NULL,ic,FALSE);
11762 pic16_freeAsmop (result,NULL,ic,TRUE);
11765 /*-----------------------------------------------------------------*/
11766 /* genJumpTab - generates code for jump table */
11767 /*-----------------------------------------------------------------*/
11768 static void genJumpTab (iCode *ic)
11773 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11775 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
11776 /* get the condition into accumulator */
11777 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
11779 /* multiply by three */
11780 pic16_emitcode("add","a,acc");
11781 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
11783 jtab = newiTempLabel(NULL);
11784 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
11785 pic16_emitcode("jmp","@a+dptr");
11786 pic16_emitcode("","%05d_DS_:",jtab->key+100);
11788 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
11789 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
11791 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
11792 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
11793 pic16_emitpLabel(jtab->key);
11795 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
11797 /* now generate the jump labels */
11798 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
11799 jtab = setNextItem(IC_JTLABELS(ic))) {
11800 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
11801 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
11807 /*-----------------------------------------------------------------*/
11808 /* genMixedOperation - gen code for operators between mixed types */
11809 /*-----------------------------------------------------------------*/
11811 TSD - Written for the PIC port - but this unfortunately is buggy.
11812 This routine is good in that it is able to efficiently promote
11813 types to different (larger) sizes. Unfortunately, the temporary
11814 variables that are optimized out by this routine are sometimes
11815 used in other places. So until I know how to really parse the
11816 iCode tree, I'm going to not be using this routine :(.
11818 static int genMixedOperation (iCode *ic)
11821 operand *result = IC_RESULT(ic);
11822 sym_link *ctype = operandType(IC_LEFT(ic));
11823 operand *right = IC_RIGHT(ic);
11829 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
11831 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11837 nextright = IC_RIGHT(nextic);
11838 nextleft = IC_LEFT(nextic);
11839 nextresult = IC_RESULT(nextic);
11841 pic16_aopOp(right,ic,FALSE);
11842 pic16_aopOp(result,ic,FALSE);
11843 pic16_aopOp(nextright, nextic, FALSE);
11844 pic16_aopOp(nextleft, nextic, FALSE);
11845 pic16_aopOp(nextresult, nextic, FALSE);
11847 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
11849 operand *t = right;
11853 pic16_emitcode(";remove right +","");
11855 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
11857 operand *t = right;
11861 pic16_emitcode(";remove left +","");
11865 big = AOP_SIZE(nextleft);
11866 small = AOP_SIZE(nextright);
11868 switch(nextic->op) {
11871 pic16_emitcode(";optimize a +","");
11872 /* if unsigned or not an integral type */
11873 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
11874 pic16_emitcode(";add a bit to something","");
11877 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
11879 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
11880 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
11881 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
11883 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
11891 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11892 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11893 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11896 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11898 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
11899 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
11900 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
11901 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11902 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
11905 pic16_emitcode("rlf","known_zero,w");
11912 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11913 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11914 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11916 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11926 pic16_freeAsmop(right,NULL,ic,TRUE);
11927 pic16_freeAsmop(result,NULL,ic,TRUE);
11928 pic16_freeAsmop(nextright,NULL,ic,TRUE);
11929 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
11931 nextic->generated = 1;
11938 /*-----------------------------------------------------------------*/
11939 /* genCast - gen code for casting */
11940 /*-----------------------------------------------------------------*/
11941 static void genCast (iCode *ic)
11943 operand *result = IC_RESULT(ic);
11944 sym_link *ctype = operandType(IC_LEFT(ic));
11945 sym_link *rtype = operandType(IC_RIGHT(ic));
11946 operand *right = IC_RIGHT(ic);
11949 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11950 /* if they are equivalent then do nothing */
11951 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
11954 pic16_aopOp(right,ic,FALSE) ;
11955 pic16_aopOp(result,ic,FALSE);
11957 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11959 /* if the result is a bit */
11960 if (AOP_TYPE(result) == AOP_CRY) {
11962 /* if the right size is a literal then
11963 * we know what the value is */
11964 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11966 if (AOP_TYPE(right) == AOP_LIT) {
11967 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
11968 pic16_popGet(AOP(result),0));
11970 if (((int) operandLitValue(right)))
11971 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
11972 AOP(result)->aopu.aop_dir,
11973 AOP(result)->aopu.aop_dir);
11975 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
11976 AOP(result)->aopu.aop_dir,
11977 AOP(result)->aopu.aop_dir);
11981 /* the right is also a bit variable */
11982 if (AOP_TYPE(right) == AOP_CRY) {
11984 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11986 pic16_emitcode("clrc","");
11987 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
11988 AOP(right)->aopu.aop_dir,
11989 AOP(right)->aopu.aop_dir);
11990 pic16_aopPut(AOP(result),"c",0);
11994 /* we need to or */
11995 if (AOP_TYPE(right) == AOP_REG) {
11996 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11997 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
11998 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
12000 pic16_toBoolean(right);
12001 pic16_aopPut(AOP(result),"a",0);
12005 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
12008 size = AOP_SIZE(result);
12010 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12012 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
12013 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12014 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
12017 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12022 /* if they are the same size : or less */
12023 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
12025 /* if they are in the same place */
12026 if (pic16_sameRegs(AOP(right),AOP(result)))
12029 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12031 if (IS_PTR_CONST(rtype))
12033 if (IS_CODEPTR(rtype))
12035 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
12038 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
12040 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
12042 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
12045 if(AOP_TYPE(right) == AOP_IMMD) {
12046 pCodeOp *pcop0, *pcop1, *pcop2;
12047 symbol *sym = OP_SYMBOL( right );
12049 size = AOP_SIZE(result);
12051 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12053 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12055 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12058 pic16_emitpcode(POC_MOVLW, pcop0);
12059 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
12060 pic16_emitpcode(POC_MOVLW, pcop1);
12061 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
12062 pic16_emitpcode(POC_MOVLW, pcop2);
12063 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
12066 pic16_emitpcode(POC_MOVLW, pcop0);
12067 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12068 pic16_emitpcode(POC_MOVLW, pcop1);
12069 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12071 pic16_emitpcode(POC_MOVLW, pcop0);
12072 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12076 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12077 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
12078 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12079 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
12080 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12081 if(AOP_SIZE(result) <2)
12082 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
12084 /* if they in different places then copy */
12085 size = AOP_SIZE(result);
12088 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
12089 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12096 /* if the result is of type pointer */
12097 if (IS_PTR(ctype)) {
12099 sym_link *type = operandType(right);
12100 sym_link *etype = getSpec(type);
12102 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
12104 /* pointer to generic pointer */
12105 if (IS_GENPTR(ctype)) {
12109 p_type = DCL_TYPE(type);
12111 /* we have to go by the storage class */
12112 p_type = PTR_TYPE(SPEC_OCLS(etype));
12114 /* if (SPEC_OCLS(etype)->codesp ) */
12115 /* p_type = CPOINTER ; */
12117 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
12118 /* p_type = FPOINTER ; */
12120 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
12121 /* p_type = PPOINTER; */
12123 /* if (SPEC_OCLS(etype) == idata ) */
12124 /* p_type = IPOINTER ; */
12126 /* p_type = POINTER ; */
12129 /* the first two bytes are known */
12130 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
12131 size = GPTRSIZE - 1;
12134 if(offset < AOP_SIZE(right)) {
12135 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
12136 mov2f(AOP(result), AOP(right), offset);
12138 if ((AOP_TYPE(right) == AOP_PCODE) &&
12139 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12140 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
12141 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12144 pic16_aopPut(AOP(result),
12145 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12150 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
12153 /* the last byte depending on type */
12157 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
12158 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
12159 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
12163 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12167 pic16_emitcode(";BUG!? ","%d",__LINE__);
12171 pic16_emitcode(";BUG!? ","%d",__LINE__);
12176 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12180 /* this should never happen */
12181 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12182 "got unknown pointer type");
12185 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
12189 /* just copy the pointers */
12190 size = AOP_SIZE(result);
12193 pic16_aopPut(AOP(result),
12194 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12203 /* so we now know that the size of destination is greater
12204 than the size of the source.
12205 Now, if the next iCode is an operator then we might be
12206 able to optimize the operation without performing a cast.
12208 if(genMixedOperation(ic))
12211 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12213 /* we move to result for the size of source */
12214 size = AOP_SIZE(right);
12217 mov2f(AOP(result), AOP(right), offset);
12221 /* now depending on the sign of the destination */
12222 size = AOP_SIZE(result) - AOP_SIZE(right);
12223 /* if unsigned or not an integral type */
12224 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
12226 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12228 /* we need to extend the sign :( */
12231 /* Save one instruction of casting char to int */
12232 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
12233 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12234 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
12236 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
12239 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12241 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12243 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
12246 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
12251 pic16_freeAsmop(right,NULL,ic,TRUE);
12252 pic16_freeAsmop(result,NULL,ic,TRUE);
12256 /*-----------------------------------------------------------------*/
12257 /* genDjnz - generate decrement & jump if not zero instrucion */
12258 /*-----------------------------------------------------------------*/
12259 static int genDjnz (iCode *ic, iCode *ifx)
12261 symbol *lbl, *lbl1;
12262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12267 /* if the if condition has a false label
12268 then we cannot save */
12272 /* if the minus is not of the form
12274 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
12275 !IS_OP_LITERAL(IC_RIGHT(ic)))
12278 if (operandLitValue(IC_RIGHT(ic)) != 1)
12281 /* if the size of this greater than one then no
12283 if (getSize(operandType(IC_RESULT(ic))) > 1)
12286 /* otherwise we can save BIG */
12287 lbl = newiTempLabel(NULL);
12288 lbl1= newiTempLabel(NULL);
12290 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12292 if (IS_AOP_PREG(IC_RESULT(ic))) {
12293 pic16_emitcode("dec","%s",
12294 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12295 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12296 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
12300 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
12301 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
12303 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12304 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
12308 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12309 ifx->generated = 1;
12313 /*-----------------------------------------------------------------*/
12314 /* genReceive - generate code for a receive iCode */
12315 /*-----------------------------------------------------------------*/
12316 static void genReceive (iCode *ic)
12318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12321 fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__,
12322 OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack);
12324 // pic16_DumpOp(__FUNCTION__, IC_RESULT(ic));
12326 if (isOperandInFarSpace(IC_RESULT(ic))
12327 && ( OP_SYMBOL(IC_RESULT(ic))->isspilt
12328 || IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
12330 int size = getSize(operandType(IC_RESULT(ic)));
12331 int offset = pic16_fReturnSizePic - size;
12335 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
12336 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
12340 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
12342 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12343 size = AOP_SIZE(IC_RESULT(ic));
12346 pic16_emitcode ("pop","acc");
12347 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
12350 DEBUGpic16_emitcode ("; ***","2 %s %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
12353 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12355 assignResultValue(IC_RESULT(ic), 0);
12358 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12361 /*-----------------------------------------------------------------*/
12362 /* genDummyRead - generate code for dummy read of volatiles */
12363 /*-----------------------------------------------------------------*/
12365 genDummyRead (iCode * ic)
12367 pic16_emitcode ("; genDummyRead","");
12368 pic16_emitcode ("; not implemented","");
12373 /*-----------------------------------------------------------------*/
12374 /* genpic16Code - generate code for pic16 based controllers */
12375 /*-----------------------------------------------------------------*/
12377 * At this point, ralloc.c has gone through the iCode and attempted
12378 * to optimize in a way suitable for a PIC. Now we've got to generate
12379 * PIC instructions that correspond to the iCode.
12381 * Once the instructions are generated, we'll pass through both the
12382 * peep hole optimizer and the pCode optimizer.
12383 *-----------------------------------------------------------------*/
12385 void genpic16Code (iCode *lic)
12390 lineHead = lineCurr = NULL;
12392 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
12393 pic16_addpBlock(pb);
12396 /* if debug information required */
12397 if (options.debug && currFunc) {
12399 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
12404 for (ic = lic ; ic ; ic = ic->next ) {
12406 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
12407 if ( cln != ic->lineno ) {
12408 if ( options.debug ) {
12409 debugFile->writeCLine (ic);
12412 if(!options.noCcodeInAsm) {
12413 pic16_addpCode2pBlock(pb,
12414 pic16_newpCodeCSource(ic->lineno, ic->filename,
12415 printCLine(ic->filename, ic->lineno)));
12421 if(options.iCodeInAsm) {
12423 /* insert here code to print iCode as comment */
12424 l = Safe_strdup(printILine(ic));
12425 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
12428 /* if the result is marked as
12429 spilt and rematerializable or code for
12430 this has already been generated then
12432 if (resultRemat(ic) || ic->generated )
12435 /* depending on the operation */
12454 /* IPOP happens only when trying to restore a
12455 spilt live range, if there is an ifx statement
12456 following this pop then the if statement might
12457 be using some of the registers being popped which
12458 would destroy the contents of the register so
12459 we need to check for this condition and handle it */
12461 ic->next->op == IFX &&
12462 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
12463 genIfx (ic->next,ic);
12481 genEndFunction (ic);
12497 pic16_genPlus (ic) ;
12501 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
12502 pic16_genMinus (ic);
12518 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
12522 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
12529 /* note these two are xlated by algebraic equivalence
12530 during parsing SDCC.y */
12531 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12532 "got '>=' or '<=' shouldn't have come here");
12536 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
12548 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
12552 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
12556 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
12580 genRightShift (ic);
12583 case GET_VALUE_AT_ADDRESS:
12588 if (POINTER_SET(ic))
12615 addSet(&_G.sendSet,ic);
12616 /* create a reversed list of SEND iCodes */
12617 // addSetHead(&_G.sendSet, ic);
12620 case DUMMY_READ_VOLATILE:
12630 /* now we are ready to call the
12631 peep hole optimizer */
12632 if (!options.nopeep) {
12633 peepHole (&lineHead);
12635 /* now do the actual printing */
12636 printLine (lineHead, codeOutFile);
12639 DFPRINTF((stderr,"printing pBlock\n\n"));
12640 pic16_printpBlock(stdout,pb);