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;
77 /* max_key keeps track of the largest label number used in
78 a function. This is then used to adjust the label offset
79 for the next function.
82 static int GpsuedoStkPtr=0;
84 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
86 unsigned int pic16aopLiteral (value *val, int offset);
87 const char *pic16_AopType(short type);
88 static iCode *ifxForOp ( operand *op, iCode *ic );
90 void pic16_pushpCodeOp(pCodeOp *pcop);
91 void pic16_poppCodeOp(pCodeOp *pcop);
93 static bool is_LitOp(operand *op);
94 static bool is_LitAOp(asmop *aop);
97 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
99 /* set the following macro to 1 to enable passing the
100 * first byte of functions parameters via WREG */
101 #define USE_WREG_IN_FUNC_PARAMS 0
104 /* this is the down and dirty file with all kinds of
105 kludgy & hacky stuff. This is what it is all about
106 CODE GENERATION for a specific MCU . some of the
107 routines may be reusable, will have to see */
109 static char *zero = "#0x00";
110 static char *one = "#0x01";
111 //static char *spname = "sp";
115 * Function return value policy (MSB-->LSB):
117 * 16 bits -> PRODL:WREG
118 * 24 bits -> PRODH:PRODL:WREG
119 * 32 bits -> FSR0L:PRODH:PRODL:WREG
120 * >32 bits -> on stack, and FSR0 points to the beginning
125 char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
126 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
127 static char **fReturn = fReturnpic16;
129 static char *accUse[] = {"WREG"};
131 //static short rbank = -1;
147 int stack_lat; /* stack offset latency */
149 int useWreg; /* flag when WREG is used to pass function parameter */
152 /* Resolved ifx structure. This structure stores information
153 about an iCode ifx that makes it easier to generate code.
155 typedef struct resolvedIfx {
156 symbol *lbl; /* pointer to a label */
157 int condition; /* true or false ifx */
158 int generated; /* set true when the code associated with the ifx
162 extern int pic16_ptrRegReq ;
163 extern int pic16_nRegs;
164 extern FILE *codeOutFile;
165 //static void saverbank (int, iCode *,bool);
167 static lineNode *lineHead = NULL;
168 static lineNode *lineCurr = NULL;
170 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
171 0xE0, 0xC0, 0x80, 0x00};
172 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
173 0x07, 0x03, 0x01, 0x00};
177 /*-----------------------------------------------------------------*/
178 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
179 /* exponent of 2 is returned, otherwise -1 is */
181 /* note that this is similar to the function `powof2' in SDCCsymt */
185 /*-----------------------------------------------------------------*/
186 static int my_powof2 (unsigned long num)
189 if( (num & (num-1)) == 0) {
202 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
204 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
206 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
207 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
208 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
209 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
210 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
211 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
212 ((result) ? AOP_SIZE(result) : 0));
215 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
218 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
220 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
221 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
222 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
223 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
224 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
225 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
229 void pic16_emitpcomment (char *fmt, ...)
232 char lb[INITIAL_INLINEASM];
238 vsprintf(lb+1,fmt,ap);
240 while (isspace(*lbp)) lbp++;
243 lineCurr = (lineCurr ?
244 connectLine(lineCurr,newLineNode(lb)) :
245 (lineHead = newLineNode(lb)));
246 lineCurr->isInline = _G.inLine;
247 lineCurr->isDebug = _G.debugLine;
249 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
252 // fprintf(stderr, "%s\n", lb);
255 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
258 char lb[INITIAL_INLINEASM];
261 if(!pic16_debug_verbose)
268 sprintf(lb,"%s\t",inst);
270 sprintf(lb,"%s",inst);
271 vsprintf(lb+(strlen(lb)),fmt,ap);
275 while (isspace(*lbp)) lbp++;
278 lineCurr = (lineCurr ?
279 connectLine(lineCurr,newLineNode(lb)) :
280 (lineHead = newLineNode(lb)));
281 lineCurr->isInline = _G.inLine;
282 lineCurr->isDebug = _G.debugLine;
284 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
287 // fprintf(stderr, "%s\n", lb);
290 void pic16_emitpLabel(int key)
292 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset));
295 void pic16_emitpLabelFORCE(int key)
297 pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
300 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
304 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
306 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
309 void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop)
312 pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop));
314 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
317 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
320 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
326 #define pic16_emitcode DEBUGpic16_emitcode
328 /*-----------------------------------------------------------------*/
329 /* pic16_emitcode - writes the code into a file : for now it is simple */
330 /*-----------------------------------------------------------------*/
331 void pic16_emitcode (char *inst,char *fmt, ...)
334 char lb[INITIAL_INLINEASM];
341 sprintf(lb,"%s\t",inst);
343 sprintf(lb,"%s",inst);
344 vsprintf(lb+(strlen(lb)),fmt,ap);
348 while (isspace(*lbp)) lbp++;
351 lineCurr = (lineCurr ?
352 connectLine(lineCurr,newLineNode(lb)) :
353 (lineHead = newLineNode(lb)));
354 lineCurr->isInline = _G.inLine;
355 lineCurr->isDebug = _G.debugLine;
357 // VR fprintf(stderr, "lb = <%s>\n", lbp);
359 // if(pic16_debug_verbose)
360 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
367 /*-----------------------------------------------------------------*/
368 /* pic16_emitDebuggerSymbol - associate the current code location */
369 /* with a debugger symbol */
370 /*-----------------------------------------------------------------*/
372 pic16_emitDebuggerSymbol (char * debugSym)
375 pic16_emitcode (";", "%s ==.", debugSym);
380 /*-----------------------------------------------------------------*/
381 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
382 /*-----------------------------------------------------------------*/
383 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
385 // bool r0iu = FALSE , r1iu = FALSE;
386 // bool r0ou = FALSE , r1ou = FALSE;
387 bool fsr0iu = FALSE, fsr0ou;
388 bool fsr2iu = FALSE, fsr2ou;
390 fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
393 fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
394 fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
396 fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
397 fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
399 if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
400 fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
401 DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
404 if(!fsr0iu && !fsr0ou) {
405 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
406 (*aopp)->type = AOP_FSR0;
408 fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
410 return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
414 /* no usage of FSR2 */
415 if(!fsr2iu && !fsr2ou) {
416 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
417 (*aopp)->type = AOP_FSR2;
419 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
423 /* now we know they both have usage */
424 /* if fsr0 not used in this instruction */
426 if (!_G.fsr0Pushed) {
427 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
428 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
432 ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
433 (*aopp)->type = AOP_FSR0;
435 // fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__);
437 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
441 fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
446 /* the logic: if r0 & r1 used in the instruction
447 then we are in trouble otherwise */
449 /* first check if r0 & r1 are used by this
450 instruction, in which case we are in trouble */
451 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
452 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
457 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
458 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
460 /* if no usage of r0 then return it */
461 if (!r0iu && !r0ou) {
462 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
463 (*aopp)->type = AOP_R0;
465 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
468 /* if no usage of r1 then return it */
469 if (!r1iu && !r1ou) {
470 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
471 (*aopp)->type = AOP_R1;
473 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
476 /* now we know they both have usage */
477 /* if r0 not used in this instruction */
479 /* push it if not already pushed */
481 //pic16_emitcode ("push","%s",
482 // pic16_regWithIdx(R0_IDX)->dname);
486 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
487 (*aopp)->type = AOP_R0;
489 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
492 /* if r1 not used then */
495 /* push it if not already pushed */
497 //pic16_emitcode ("push","%s",
498 // pic16_regWithIdx(R1_IDX)->dname);
502 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
503 (*aopp)->type = AOP_R1;
504 return pic16_regWithIdx(R1_IDX);
508 /* I said end of world but not quite end of world yet */
509 /* if this is a result then we can push it on the stack*/
511 (*aopp)->type = AOP_STK;
515 /* other wise this is true end of the world */
516 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
517 "getFreePtr should never reach here");
522 /*-----------------------------------------------------------------*/
523 /* newAsmop - creates a new asmOp */
524 /*-----------------------------------------------------------------*/
525 static asmop *newAsmop (short type)
529 aop = Safe_calloc(1,sizeof(asmop));
534 static void genSetDPTR(int n)
538 pic16_emitcode(";", "Select standard DPTR");
539 pic16_emitcode("mov", "dps, #0x00");
543 pic16_emitcode(";", "Select alternate DPTR");
544 pic16_emitcode("mov", "dps, #0x01");
548 /*-----------------------------------------------------------------*/
549 /* resolveIfx - converts an iCode ifx into a form more useful for */
550 /* generating code */
551 /*-----------------------------------------------------------------*/
552 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
555 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
561 resIfx->condition = 1; /* assume that the ifx is true */
562 resIfx->generated = 0; /* indicate that the ifx has not been used */
565 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
568 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
569 __FUNCTION__,__LINE__,resIfx->lbl->key);
574 resIfx->lbl = IC_TRUE(ifx);
576 resIfx->lbl = IC_FALSE(ifx);
577 resIfx->condition = 0;
582 DEBUGpic16_emitcode("; ***","ifx true is non-null");
584 DEBUGpic16_emitcode("; ***","ifx false is non-null");
588 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset);
592 /*-----------------------------------------------------------------*/
593 /* pointerCode - returns the code for a pointer type */
594 /*-----------------------------------------------------------------*/
595 static int pointerCode (sym_link *etype)
598 return PTR_TYPE(SPEC_OCLS(etype));
603 /*-----------------------------------------------------------------*/
604 /* aopForSym - for a true symbol */
605 /*-----------------------------------------------------------------*/
606 static asmop *aopForSym (iCode *ic, operand *op, bool result)
608 symbol *sym=OP_SYMBOL(op);
610 memmap *space= SPEC_OCLS(sym->etype);
612 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
614 _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
616 // sym = OP_SYMBOL(op);
618 /* if already has one */
620 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
625 /* if symbol was initially placed onStack then we must re-place it
626 * to direct memory, since pic16 does not have a specific stack */
628 fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
633 /* assign depending on the storage class */
634 /* if it is on the stack or indirectly addressable */
635 /* space we need to assign either r0 or r1 to it */
636 if (sym->onStack || sym->iaccess) {
640 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
641 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
643 /* acquire a temporary register -- it is saved in function */
645 sym->aop = aop = newAsmop(AOP_STA);
646 aop->aopu.stk.stk = sym->stack;
647 aop->size = getSize(sym->type);
650 DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
651 pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
652 if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
653 && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
655 for(i=0;i<aop->size;i++)
656 aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
657 _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
659 for(i=0;i<aop->size;i++) {
660 aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
661 _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
665 // fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
668 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
671 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
674 for(i=0;i<aop->size;i++) {
676 /* initialise for stack access via frame pointer */
677 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack + i + _G.stack_lat));
679 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
680 pic16_popCopyReg(&pic16_pc_plusw2), pcop[i]));
684 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
691 /* now assign the address of the variable to
692 the pointer register */
693 if (aop->type != AOP_STK) {
697 pic16_emitcode("push","acc");
699 pic16_emitcode("mov","a,_bp");
700 pic16_emitcode("add","a,#0x%02x",
702 ((char)(sym->stack - _G.nRegsSaved )) :
703 ((char)sym->stack)) & 0xff);
704 pic16_emitcode("mov","%s,a",
705 aop->aopu.aop_ptr->name);
708 pic16_emitcode("pop","acc");
710 pic16_emitcode("mov","%s,#%s",
711 aop->aopu.aop_ptr->name,
713 aop->paged = space->paged;
715 aop->aopu.aop_stk = sym->stack;
723 if (sym->onStack && options.stack10bit)
725 /* It's on the 10 bit stack, which is located in
729 //DEBUGpic16_emitcode(";","%d",__LINE__);
732 pic16_emitcode("push","acc");
734 pic16_emitcode("mov","a,_bp");
735 pic16_emitcode("add","a,#0x%02x",
737 ((char)(sym->stack - _G.nRegsSaved )) :
738 ((char)sym->stack)) & 0xff);
741 pic16_emitcode ("mov","dpx1,#0x40");
742 pic16_emitcode ("mov","dph1,#0x00");
743 pic16_emitcode ("mov","dpl1, a");
747 pic16_emitcode("pop","acc");
749 sym->aop = aop = newAsmop(AOP_DPTR2);
750 aop->size = getSize(sym->type);
756 /* special case for a function */
757 if (IS_FUNC(sym->type)) {
758 sym->aop = aop = newAsmop(AOP_PCODE);
759 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
760 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
761 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
762 PCOI(aop->aopu.pcop)->index = 0;
763 aop->size = FPTRSIZE;
764 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
771 //DEBUGpic16_emitcode(";","%d",__LINE__);
772 /* if in bit space */
773 if (IN_BITSPACE(space)) {
774 sym->aop = aop = newAsmop (AOP_CRY);
775 aop->aopu.aop_dir = sym->rname ;
776 aop->size = getSize(sym->type);
777 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
780 /* if it is in direct space */
781 if (IN_DIRSPACE(space)) {
782 sym->aop = aop = newAsmop (AOP_DIR);
783 aop->aopu.aop_dir = sym->rname ;
784 aop->size = getSize(sym->type);
785 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
786 pic16_allocDirReg( IC_LEFT(ic) );
791 if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
792 sym->aop = aop = newAsmop (AOP_DIR);
793 aop->aopu.aop_dir = sym->rname ;
794 aop->size = getSize(sym->type);
795 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
796 pic16_allocDirReg( IC_LEFT(ic) );
801 /* only remaining is far space */
802 sym->aop = aop = newAsmop(AOP_PCODE);
804 /* change the next if to 1 to revert to good old immediate code */
805 if(IN_CODESPACE(space)) {
806 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
807 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
808 PCOI(aop->aopu.pcop)->index = 0;
810 /* try to allocate via direct register */
811 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
812 // aop->size = getSize( sym->type );
815 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
816 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
819 if(!pic16_allocDirReg (IC_LEFT(ic)))
823 if(IN_DIRSPACE( space ))
825 else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
826 aop->size = FPTRSIZE;
827 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
828 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
829 else if(sym->onStack) {
835 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
837 /* if it is in code space */
838 if (IN_CODESPACE(space))
844 /*-----------------------------------------------------------------*/
845 /* aopForRemat - rematerialzes an object */
846 /*-----------------------------------------------------------------*/
847 static asmop *aopForRemat (operand *op) // x symbol *sym)
849 symbol *sym = OP_SYMBOL(op);
851 iCode *ic = NULL, *oldic;
852 asmop *aop = newAsmop(AOP_PCODE);
858 ic = sym->rematiCode;
860 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
862 if(IS_OP_POINTER(op)) {
863 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
869 // pic16_emitpcomment("ic: %s\n", printILine(ic));
872 val += (int) operandLitValue(IC_RIGHT(ic));
873 } else if (ic->op == '-') {
874 val -= (int) operandLitValue(IC_RIGHT(ic));
878 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
881 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
884 if(!op->isaddr)viaimmd++; else viaimmd=0;
886 /* set the following if to 1 to revert to good old immediate code */
887 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
890 DEBUGpic16_emitcode(";", "%s:%d immediate", __FILE__, __LINE__);
892 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
895 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
897 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
900 PCOI(aop->aopu.pcop)->index = val;
902 DEBUGpic16_emitcode(";", "%s:%d dir", __FILE__, __LINE__);
904 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
905 getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
906 // aop->size = AOP_SIZE( IC_LEFT(ic) );
910 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
911 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
913 val, IS_PTR_CONST(operandType(op)));
915 val, IS_CODEPTR(operandType(op)));
918 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
920 pic16_allocDirReg (IC_LEFT(ic));
922 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
929 static int aopIdx (asmop *aop, int offset)
934 if(aop->type != AOP_REG)
937 return aop->aopu.aop_reg[offset]->rIdx;
942 /*-----------------------------------------------------------------*/
943 /* regsInCommon - two operands have some registers in common */
944 /*-----------------------------------------------------------------*/
945 static bool regsInCommon (operand *op1, operand *op2)
950 /* if they have registers in common */
951 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
954 sym1 = OP_SYMBOL(op1);
955 sym2 = OP_SYMBOL(op2);
957 if (sym1->nRegs == 0 || sym2->nRegs == 0)
960 for (i = 0 ; i < sym1->nRegs ; i++) {
965 for (j = 0 ; j < sym2->nRegs ;j++ ) {
969 if (sym2->regs[j] == sym1->regs[i])
977 /*-----------------------------------------------------------------*/
978 /* operandsEqu - equivalent */
979 /*-----------------------------------------------------------------*/
980 static bool operandsEqu ( operand *op1, operand *op2)
984 /* if they not symbols */
985 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
988 sym1 = OP_SYMBOL(op1);
989 sym2 = OP_SYMBOL(op2);
991 /* if both are itemps & one is spilt
992 and the other is not then false */
993 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
994 sym1->isspilt != sym2->isspilt )
997 /* if they are the same */
1001 if (sym1->rname[0] && sym2->rname[0]
1002 && strcmp (sym1->rname, sym2->rname) == 0)
1006 /* if left is a tmp & right is not */
1007 if (IS_ITEMP(op1) &&
1010 (sym1->usl.spillLoc == sym2))
1013 if (IS_ITEMP(op2) &&
1017 (sym2->usl.spillLoc == sym1))
1023 /*-----------------------------------------------------------------*/
1024 /* pic16_sameRegs - two asmops have the same registers */
1025 /*-----------------------------------------------------------------*/
1026 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
1033 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
1034 pic16_AopType(aop1->type), pic16_AopType(aop2->type));
1036 if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
1038 if (aop1->type != AOP_REG ||
1039 aop2->type != AOP_REG )
1042 if (aop1->size != aop2->size )
1045 for (i = 0 ; i < aop1->size ; i++ ) {
1046 // if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE;
1048 // if(aop1->aopu.aop_reg[i]->type == AOP_REG)
1049 if (strcmp(aop1->aopu.aop_reg[i]->name, aop2->aopu.aop_reg[i]->name ))
1056 bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
1058 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
1059 pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
1061 if(aop1 == aop2)return TRUE;
1062 if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
1064 if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
1070 /*-----------------------------------------------------------------*/
1071 /* pic16_aopOp - allocates an asmop for an operand : */
1072 /*-----------------------------------------------------------------*/
1073 void pic16_aopOp (operand *op, iCode *ic, bool result)
1082 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
1084 /* if this a literal */
1085 if (IS_OP_LITERAL(op)) {
1086 op->aop = aop = newAsmop(AOP_LIT);
1087 aop->aopu.aop_lit = op->operand.valOperand;
1088 aop->size = getSize(operandType(op));
1093 sym_link *type = operandType(op);
1095 if(IS_PTR_CONST(type))
1097 if(IS_CODEPTR(type))
1099 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1102 /* if already has a asmop then continue */
1106 /* if the underlying symbol has a aop */
1107 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
1108 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
1109 op->aop = OP_SYMBOL(op)->aop;
1113 /* if this is a true symbol */
1114 if (IS_TRUE_SYMOP(op)) {
1115 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
1116 op->aop = aopForSym(ic, op, result);
1120 /* this is a temporary : this has
1126 e) can be a return use only */
1128 sym = OP_SYMBOL(op);
1130 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
1131 /* if the type is a conditional */
1132 if (sym->regType == REG_CND) {
1133 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
1138 /* if it is spilt then two situations
1140 b) has a spill location */
1141 if (sym->isspilt || sym->nRegs == 0) {
1143 DEBUGpic16_emitcode(";","%d",__LINE__);
1144 /* rematerialize it NOW */
1147 sym->aop = op->aop = aop = aopForRemat (op);
1148 aop->size = getSize(sym->type);
1149 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
1156 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
1157 aop->size = getSize(sym->type);
1158 for ( i = 0 ; i < 1 ; i++ ) {
1159 aop->aopu.aop_str[i] = accUse[i];
1160 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
1162 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
1163 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
1171 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1172 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1173 //pic16_allocDirReg (IC_LEFT(ic));
1174 aop->size = getSize(sym->type);
1179 aop = op->aop = sym->aop = newAsmop(AOP_STR);
1180 aop->size = getSize(sym->type);
1181 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
1182 aop->aopu.aop_str[i] = fReturn[i];
1184 DEBUGpic16_emitcode(";","%d",__LINE__);
1188 /* else spill location */
1189 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
1190 /* force a new aop if sizes differ */
1191 sym->usl.spillLoc->aop = NULL;
1195 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1196 __FUNCTION__,__LINE__,
1197 sym->usl.spillLoc->rname,
1198 sym->rname, sym->usl.spillLoc->offset);
1201 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1202 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1203 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1205 sym->usl.spillLoc->offset, op);
1206 aop->size = getSize(sym->type);
1212 sym_link *type = operandType(op);
1214 if(IS_PTR_CONST(type))
1216 if(IS_CODEPTR(type))
1218 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1221 /* must be in a register */
1222 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1223 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1224 aop->size = sym->nRegs;
1225 for ( i = 0 ; i < sym->nRegs ;i++)
1226 aop->aopu.aop_reg[i] = sym->regs[i];
1229 /*-----------------------------------------------------------------*/
1230 /* pic16_freeAsmop - free up the asmop given to an operand */
1231 /*----------------------------------------------------------------*/
1232 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1249 /* depending on the asmop type only three cases need work AOP_RO
1250 , AOP_R1 && AOP_STK */
1252 switch (aop->type) {
1254 if (_G.fsr0Pushed ) {
1256 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
1257 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
1258 // pic16_emitcode ("pop","ar0");
1262 bitVectUnSetBit(ic->rUsed,IDX_FSR0);
1266 bitVectUnSetBit(ic->rUsed,IDX_FSR2);
1272 pic16_emitcode ("pop","ar0");
1276 bitVectUnSetBit(ic->rUsed,R0_IDX);
1282 pic16_emitcode ("pop","ar1");
1286 bitVectUnSetBit(ic->rUsed,R1_IDX);
1293 /* we must store the result on stack */
1294 if((op == IC_RESULT(ic)) && RESULTONSTA(ic)) {
1295 if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1296 for(i=0;i<aop->size;i++) {
1297 /* initialise for stack access via frame pointer */
1298 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(OP_SYMBOL(IC_RESULT(ic))->stack + i + _G.stack_lat));
1300 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1301 aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2)));
1304 if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1308 for(i=0;i<aop->size;i++)
1309 PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
1318 int stk = aop->aopu.aop_stk + aop->size;
1319 bitVectUnSetBit(ic->rUsed,R0_IDX);
1320 bitVectUnSetBit(ic->rUsed,R1_IDX);
1322 getFreePtr(ic,&aop,FALSE);
1324 if (options.stack10bit)
1326 /* I'm not sure what to do here yet... */
1329 "*** Warning: probably generating bad code for "
1330 "10 bit stack mode.\n");
1334 pic16_emitcode ("mov","a,_bp");
1335 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1336 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1338 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1342 pic16_emitcode("pop","acc");
1343 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1345 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1348 pic16_freeAsmop(op,NULL,ic,TRUE);
1350 pic16_emitcode("pop","ar0");
1355 pic16_emitcode("pop","ar1");
1365 /* all other cases just dealloc */
1369 OP_SYMBOL(op)->aop = NULL;
1370 /* if the symbol has a spill */
1372 SPIL_LOC(op)->aop = NULL;
1377 /*-----------------------------------------------------------------*/
1378 /* pic16_aopGet - for fetching value of the aop */
1379 /*-----------------------------------------------------------------*/
1380 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1385 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1387 /* offset is greater than size then zero */
1388 if (offset > (aop->size - 1) &&
1389 aop->type != AOP_LIT)
1392 /* depending on type */
1393 switch (aop->type) {
1397 sprintf(s, "%s", aop->aopu.aop_ptr->name);
1398 rs = Safe_calloc(1, strlen(s)+1);
1403 /* if we need to increment it */
1404 while (offset > aop->coff)
1406 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1410 while (offset < aop->coff)
1412 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1418 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
1419 return (dname ? "acc" : "a");
1421 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
1422 rs = Safe_calloc (1, strlen (s) + 1);
1430 sprintf (s,"%s",aop->aopu.aop_immd);
1433 sprintf(s,"(%s >> %d)",
1438 aop->aopu.aop_immd);
1439 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1440 rs = Safe_calloc(1,strlen(s)+1);
1446 sprintf(s,"(%s + %d)",
1449 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1451 sprintf(s,"%s",aop->aopu.aop_dir);
1452 rs = Safe_calloc(1,strlen(s)+1);
1458 // return aop->aopu.aop_reg[offset]->dname;
1460 return aop->aopu.aop_reg[offset]->name;
1463 //pic16_emitcode(";","%d",__LINE__);
1464 return aop->aopu.aop_dir;
1467 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
1468 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1470 // return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1471 rs = Safe_strdup("WREG");
1475 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1476 rs = Safe_calloc(1,strlen(s)+1);
1481 aop->coff = offset ;
1482 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1485 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1487 return aop->aopu.aop_str[offset];
1491 pCodeOp *pcop = aop->aopu.pcop;
1492 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1494 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1495 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1496 sprintf(s,"%s", pcop->name);
1498 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1501 rs = Safe_calloc(1,strlen(s)+1);
1506 rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
1510 // pCodeOp *pcop = aop->aop
1515 fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type));
1516 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1517 "aopget got unsupported aop->type");
1523 /* lock has the following meaning: When allocating temporary registers
1524 * for stack variables storage, the value of the temporary register is
1525 * saved on stack. Its value is restored at the end. This procedure is
1526 * done via calls to pic16_aopOp and pic16_freeAsmop functions. There is
1527 * a possibility that before a call to pic16_aopOp, a temporary register
1528 * is allocated for a while and it is freed after some time, this will
1529 * mess the stack and values will not be restored properly. So use lock=1
1530 * to allocate temporary registers used internally by the programmer, and
1531 * lock=0 to allocate registers for stack use. lock=1 will emit a warning
1532 * to inform the compiler developer about a possible bug. This is an internal
1533 * feature for developing the compiler -- VR */
1535 int _TempReg_lock = 0;
1536 /*-----------------------------------------------------------------*/
1537 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1538 /*-----------------------------------------------------------------*/
1539 pCodeOp *pic16_popGetTempReg(int lock)
1544 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1546 werror(W_POSSBUG2, __FILE__, __LINE__);
1549 _TempReg_lock += lock;
1554 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1555 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1556 PCOR(pcop)->r->wasUsed=1;
1557 PCOR(pcop)->r->isFree=0;
1559 /* push value on stack */
1560 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1568 /*-----------------------------------------------------------------*/
1569 /* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */
1570 /* don't save if inside v */
1571 /*-----------------------------------------------------------------*/
1572 pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
1577 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1580 werror(W_POSSBUG2, __FILE__, __LINE__);
1583 _TempReg_lock += lock;
1588 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1589 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1590 PCOR(pcop)->r->wasUsed=1;
1591 PCOR(pcop)->r->isFree=0;
1593 if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
1594 /* push value on stack */
1595 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1605 /*-----------------------------------------------------------------*/
1606 /* pic16_popReleaseTempReg - create a new temporary pCodeOp */
1607 /*-----------------------------------------------------------------*/
1608 void pic16_popReleaseTempReg(pCodeOp *pcop, int lock)
1610 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1612 _TempReg_lock -= lock;
1614 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1615 PCOR(pcop)->r->isFree = 1;
1616 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1619 /*-----------------------------------------------------------------*/
1620 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1621 /*-----------------------------------------------------------------*/
1622 pCodeOp *pic16_popGetLabel(unsigned int key)
1625 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
1630 return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset);
1633 /*-----------------------------------------------------------------*/
1634 /* pic16_popCopyReg - copy a pcode operator */
1635 /*-----------------------------------------------------------------*/
1636 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1640 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1641 pcor->pcop.type = pc->pcop.type;
1643 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1644 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1646 pcor->pcop.name = NULL;
1649 pcor->rIdx = pc->rIdx;
1652 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1657 /*-----------------------------------------------------------------*/
1658 /* pic16_popGetLit - asm operator to pcode operator conversion */
1659 /*-----------------------------------------------------------------*/
1660 pCodeOp *pic16_popGetLit(int lit)
1662 return pic16_newpCodeOpLit(lit);
1665 /*-----------------------------------------------------------------*/
1666 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1667 /*-----------------------------------------------------------------*/
1668 pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2)
1670 return pic16_newpCodeOpLit2(lit, arg2);
1674 /*-----------------------------------------------------------------*/
1675 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1676 /*-----------------------------------------------------------------*/
1677 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1679 return pic16_newpCodeOpImmd(name, offset,index, 0);
1683 /*-----------------------------------------------------------------*/
1684 /* pic16_popGet - asm operator to pcode operator conversion */
1685 /*-----------------------------------------------------------------*/
1686 pCodeOp *pic16_popGetWithString(char *str)
1692 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1696 pcop = pic16_newpCodeOp(str,PO_STR);
1701 /*-----------------------------------------------------------------*/
1702 /* pic16_popRegFromString - */
1703 /*-----------------------------------------------------------------*/
1704 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op)
1707 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1708 pcop->type = PO_DIR;
1710 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1711 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1716 pcop->name = Safe_calloc(1,strlen(str)+1);
1717 strcpy(pcop->name,str);
1719 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1721 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1723 /* make sure that register doesn't exist,
1724 * and operand isn't NULL
1725 * and symbol isn't in codespace (codespace symbols are handled elsewhere) */
1726 if((PCOR(pcop)->r == NULL)
1728 && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
1729 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1730 // __FUNCTION__, __LINE__, str, size, offset);
1732 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
1733 fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
1736 PCOR(pcop)->instance = offset;
1741 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1745 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1747 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1748 PCOR(pcop)->rIdx = rIdx;
1749 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1751 PCOR(pcop)->r->isFree = 0;
1752 PCOR(pcop)->r->wasUsed = 1;
1754 pcop->type = PCOR(pcop)->r->pc_type;
1759 /*---------------------------------------------------------------------------------*/
1760 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1762 /*---------------------------------------------------------------------------------*/
1763 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1768 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1770 /* comment the following check, so errors to throw up */
1771 // if(!pcop2)return NULL;
1773 temp = pic16_popGet(aop_dst, offset);
1774 pcop2->pcop2 = temp;
1781 /*--------------------------------------------------------------------------------.-*/
1782 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1783 /* VR 030601 , adapted by Hans Dorn */
1784 /*--------------------------------------------------------------------------------.-*/
1785 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1789 pcop2 = (pCodeOpReg2 *)src;
1797 /*---------------------------------------------------------------------------------*/
1798 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1799 /* movff instruction */
1800 /*---------------------------------------------------------------------------------*/
1801 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1806 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1807 pcop2->pcop2 = pic16_popCopyReg(dst);
1809 /* the pCodeOp may be already allocated */
1810 pcop2 = (pCodeOpReg2 *)(src);
1811 pcop2->pcop2 = (pCodeOp *)(dst);
1818 /*-----------------------------------------------------------------*/
1819 /* pic16_popGet - asm operator to pcode operator conversion */
1820 /*-----------------------------------------------------------------*/
1821 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1823 //char *s = buffer ;
1827 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1828 /* offset is greater than
1831 // if (offset > (aop->size - 1) &&
1832 // aop->type != AOP_LIT)
1833 // return NULL; //zero;
1835 /* depending on type */
1836 switch (aop->type) {
1842 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1843 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1850 pcop = Safe_calloc(1, sizeof(pCodeOpReg));
1851 PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
1852 PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
1853 PCOR(pcop)->r->wasUsed = 1;
1854 PCOR(pcop)->r->isFree = 0;
1856 PCOR(pcop)->instance = offset;
1857 pcop->type = PCOR(pcop)->r->pc_type;
1861 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1862 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1865 /* pCodeOp is already allocated from aopForSym */
1866 DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
1867 pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
1873 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1875 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1877 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1879 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1880 PCOR(pcop)->rIdx = rIdx;
1881 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1882 PCOR(pcop)->r->wasUsed=1;
1883 PCOR(pcop)->r->isFree=0;
1885 PCOR(pcop)->instance = offset;
1886 pcop->type = PCOR(pcop)->r->pc_type;
1887 // rs = aop->aopu.aop_reg[offset]->name;
1888 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1892 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1893 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1899 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1900 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
1904 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1906 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1908 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1909 // pcop->type = PO_GPR_REGISTER;
1910 PCOR(pcop)->rIdx = rIdx;
1911 PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
1912 PCOR(pcop)->r->wasUsed=1;
1913 PCOR(pcop)->r->isFree=0;
1915 PCOR(pcop)->instance = offset;
1916 pcop->type = PCOR(pcop)->r->pc_type;
1917 rs = aop->aopu.aop_reg[offset]->name;
1918 DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs);
1923 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1925 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
1926 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1927 //if(PCOR(pcop)->r == NULL)
1928 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1932 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1933 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1936 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1937 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1940 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1941 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1942 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1943 pcop->type = PCOR(pcop)->r->pc_type;
1944 pcop->name = PCOR(pcop)->r->name;
1950 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1952 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1953 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1955 switch( aop->aopu.pcop->type ) {
1956 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1957 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1959 assert( 0 ); /* should never reach here */;
1962 PCOI(pcop)->offset = offset;
1967 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1968 "pic16_popGet got unsupported aop->type");
1971 /*-----------------------------------------------------------------*/
1972 /* pic16_aopPut - puts a string for a aop */
1973 /*-----------------------------------------------------------------*/
1974 void pic16_aopPut (asmop *aop, char *s, int offset)
1981 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1983 if (aop->size && offset > ( aop->size - 1)) {
1984 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1985 "pic16_aopPut got offset > aop->size");
1989 /* will assign value to value */
1990 /* depending on where it is ofcourse */
1991 switch (aop->type) {
1994 sprintf(d,"(%s + %d)",
1995 aop->aopu.aop_dir,offset);
1996 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1999 sprintf(d,"%s",aop->aopu.aop_dir);
2002 DEBUGpic16_emitcode(";","%d",__LINE__);
2004 pic16_emitcode("movf","%s,w",s);
2005 pic16_emitcode("movwf","%s",d);
2008 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
2009 if(offset >= aop->size) {
2010 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2013 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
2016 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2023 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
2024 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
2027 strcmp(s,"r0") == 0 ||
2028 strcmp(s,"r1") == 0 ||
2029 strcmp(s,"r2") == 0 ||
2030 strcmp(s,"r3") == 0 ||
2031 strcmp(s,"r4") == 0 ||
2032 strcmp(s,"r5") == 0 ||
2033 strcmp(s,"r6") == 0 ||
2034 strcmp(s,"r7") == 0 )
2035 pic16_emitcode("mov","%s,%s ; %d",
2036 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
2040 if(strcmp(s,"W")==0 )
2041 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
2043 pic16_emitcode("movwf","%s",
2044 aop->aopu.aop_reg[offset]->name);
2046 if(strcmp(s,zero)==0) {
2047 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2049 } else if(strcmp(s,"W")==0) {
2050 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
2051 pcop->type = PO_GPR_REGISTER;
2053 PCOR(pcop)->rIdx = -1;
2054 PCOR(pcop)->r = NULL;
2056 DEBUGpic16_emitcode(";","%d",__LINE__);
2057 pcop->name = Safe_strdup(s);
2058 pic16_emitpcode(POC_MOVFW,pcop);
2059 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2060 } else if(strcmp(s,one)==0) {
2061 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2062 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
2064 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2072 if (aop->type == AOP_DPTR2)
2078 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2079 "pic16_aopPut writting to code space");
2083 while (offset > aop->coff) {
2085 pic16_emitcode ("inc","dptr");
2088 while (offset < aop->coff) {
2090 pic16_emitcode("lcall","__decdptr");
2095 /* if not in accumulater */
2098 pic16_emitcode ("movx","@dptr,a");
2100 if (aop->type == AOP_DPTR2)
2108 while (offset > aop->coff) {
2110 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
2112 while (offset < aop->coff) {
2114 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
2120 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
2125 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
2127 if (strcmp(s,"r0") == 0 ||
2128 strcmp(s,"r1") == 0 ||
2129 strcmp(s,"r2") == 0 ||
2130 strcmp(s,"r3") == 0 ||
2131 strcmp(s,"r4") == 0 ||
2132 strcmp(s,"r5") == 0 ||
2133 strcmp(s,"r6") == 0 ||
2134 strcmp(s,"r7") == 0 ) {
2136 sprintf(buffer,"a%s",s);
2137 pic16_emitcode("mov","@%s,%s",
2138 aop->aopu.aop_ptr->name,buffer);
2140 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
2145 if (strcmp(s,"a") == 0)
2146 pic16_emitcode("push","acc");
2148 pic16_emitcode("push","%s",s);
2153 /* if bit variable */
2154 if (!aop->aopu.aop_dir) {
2155 pic16_emitcode("clr","a");
2156 pic16_emitcode("rlc","a");
2159 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
2162 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
2165 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2167 lbl = newiTempLabel(NULL);
2169 if (strcmp(s,"a")) {
2172 pic16_emitcode("clr","c");
2173 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
2174 pic16_emitcode("cpl","c");
2175 pic16_emitcode("","%05d_DS_:",lbl->key+100);
2176 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2183 if (strcmp(aop->aopu.aop_str[offset],s))
2184 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
2189 if (!offset && (strcmp(s,"acc") == 0))
2192 if (strcmp(aop->aopu.aop_str[offset],s))
2193 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
2197 fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type);
2198 // werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2199 // "pic16_aopPut got unsupported aop->type");
2205 /*-----------------------------------------------------------------*/
2206 /* mov2w - generate either a MOVLW or MOVFW based operand type */
2207 /*-----------------------------------------------------------------*/
2208 static void mov2w (asmop *aop, int offset)
2210 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
2213 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
2215 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
2218 static void mov2f(asmop *dst, asmop *src, int offset)
2220 if(is_LitAOp(src)) {
2221 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2222 pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
2224 if(pic16_sameRegsOfs(src, dst, offset))return;
2225 pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset),
2226 pic16_popGet(dst, offset)));
2230 static void mov2fp(pCodeOp *dst, asmop *src, int offset)
2232 if(is_LitAOp(src)) {
2233 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2234 pic16_emitpcode(POC_MOVWF, dst);
2236 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(src, offset), dst));
2240 void pic16_testStackOverflow(void)
2242 #define GSTACK_TEST_NAME "__gstack_test"
2244 pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME ));
2249 sym = newSymbol( GSTACK_TEST_NAME , 0 );
2250 strcpy(sym->rname, GSTACK_TEST_NAME);
2251 checkAddSym(&externs, sym);
2256 /* push pcop into stack */
2257 void pic16_pushpCodeOp(pCodeOp *pcop)
2259 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2260 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
2261 if(pic16_options.gstack)
2262 pic16_testStackOverflow();
2266 /* pop pcop from stack */
2267 void pic16_poppCodeOp(pCodeOp *pcop)
2269 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
2270 if(pic16_options.gstack)
2271 pic16_testStackOverflow();
2275 /*-----------------------------------------------------------------*/
2276 /* pushw - pushes wreg to stack */
2277 /*-----------------------------------------------------------------*/
2280 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2281 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2282 if(pic16_options.gstack)
2283 pic16_testStackOverflow();
2287 /*-----------------------------------------------------------------*/
2288 /* pushaop - pushes aop to stack */
2289 /*-----------------------------------------------------------------*/
2290 void pushaop(asmop *aop, int offset)
2292 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2294 if(is_LitAOp(aop)) {
2295 pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
2296 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2298 pic16_emitpcode(POC_MOVFF,
2299 pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg(&pic16_pc_postdec1)));
2302 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
2303 if(pic16_options.gstack)
2304 pic16_testStackOverflow();
2307 /*-----------------------------------------------------------------*/
2308 /* popaop - pops aop from stack */
2309 /*-----------------------------------------------------------------*/
2310 void popaop(asmop *aop, int offset)
2312 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
2313 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
2314 if(pic16_options.gstack)
2315 pic16_testStackOverflow();
2318 void popaopidx(asmop *aop, int offset, int index)
2322 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2324 if(STACK_MODEL_LARGE)ofs++;
2326 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
2327 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
2328 if(pic16_options.gstack)
2329 pic16_testStackOverflow();
2332 /*-----------------------------------------------------------------*/
2333 /* reAdjustPreg - points a register back to where it should */
2334 /*-----------------------------------------------------------------*/
2335 static void reAdjustPreg (asmop *aop)
2339 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2341 if ((size = aop->size) <= 1)
2344 switch (aop->type) {
2348 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
2352 if (aop->type == AOP_DPTR2)
2358 pic16_emitcode("lcall","__decdptr");
2361 if (aop->type == AOP_DPTR2)
2373 /*-----------------------------------------------------------------*/
2374 /* opIsGptr: returns non-zero if the passed operand is */
2375 /* a generic pointer type. */
2376 /*-----------------------------------------------------------------*/
2377 static int opIsGptr(operand *op)
2379 sym_link *type = operandType(op);
2381 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2382 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2390 /*-----------------------------------------------------------------*/
2391 /* pic16_getDataSize - get the operand data size */
2392 /*-----------------------------------------------------------------*/
2393 int pic16_getDataSize(operand *op)
2395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2398 return AOP_SIZE(op);
2400 // tsd- in the pic port, the genptr size is 1, so this code here
2401 // fails. ( in the 8051 port, the size was 4).
2404 size = AOP_SIZE(op);
2405 if (size == GPTRSIZE)
2407 sym_link *type = operandType(op);
2408 if (IS_GENPTR(type))
2410 /* generic pointer; arithmetic operations
2411 * should ignore the high byte (pointer type).
2414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2421 /*-----------------------------------------------------------------*/
2422 /* pic16_outAcc - output Acc */
2423 /*-----------------------------------------------------------------*/
2424 void pic16_outAcc(operand *result)
2427 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2428 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2431 size = pic16_getDataSize(result);
2433 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2436 /* unsigned or positive */
2438 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2443 /*-----------------------------------------------------------------*/
2444 /* pic16_outBitC - output a bit C */
2445 /* Move to result the value of Carry flag -- VR */
2446 /*-----------------------------------------------------------------*/
2447 void pic16_outBitC(operand *result)
2451 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2452 /* if the result is bit */
2453 if (AOP_TYPE(result) == AOP_CRY) {
2454 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2455 pic16_aopPut(AOP(result),"c",0);
2458 i = AOP_SIZE(result);
2460 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2462 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2465 pic16_emitcode("clr","a ; %d", __LINE__);
2466 pic16_emitcode("rlc","a");
2467 pic16_outAcc(result);
2472 /*-----------------------------------------------------------------*/
2473 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2474 /*-----------------------------------------------------------------*/
2475 void pic16_toBoolean(operand *oper)
2477 int size = AOP_SIZE(oper) - 1;
2480 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2482 if ( AOP_TYPE(oper) != AOP_ACC) {
2483 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2486 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2491 #if !defined(GEN_Not)
2492 /*-----------------------------------------------------------------*/
2493 /* genNot - generate code for ! operation */
2494 /*-----------------------------------------------------------------*/
2495 static void pic16_genNot (iCode *ic)
2500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2501 /* assign asmOps to operand & result */
2502 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2503 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2505 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2506 /* if in bit space then a special case */
2507 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2508 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2509 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2510 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2512 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2513 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2514 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2519 size = AOP_SIZE(IC_LEFT(ic));
2521 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2522 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2523 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2526 pic16_toBoolean(IC_LEFT(ic));
2528 tlbl = newiTempLabel(NULL);
2529 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2530 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2531 pic16_outBitC(IC_RESULT(ic));
2534 /* release the aops */
2535 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2536 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2541 #if !defined(GEN_Cpl)
2542 /*-----------------------------------------------------------------*/
2543 /* genCpl - generate code for complement */
2544 /*-----------------------------------------------------------------*/
2545 static void pic16_genCpl (iCode *ic)
2551 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2552 /* assign asmOps to operand & result */
2553 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2554 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2556 /* if both are in bit space then
2558 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2559 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2561 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2562 pic16_emitcode("cpl","c");
2563 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2567 size = AOP_SIZE(IC_RESULT(ic));
2570 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2572 pic16_emitcode("cpl","a");
2573 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2575 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2576 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2578 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2579 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2587 /* release the aops */
2588 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2589 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2593 /*-----------------------------------------------------------------*/
2594 /* genUminusFloat - unary minus for floating points */
2595 /*-----------------------------------------------------------------*/
2596 static void genUminusFloat(operand *op,operand *result)
2598 int size ,offset =0 ;
2601 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2602 /* for this we just need to flip the
2603 first it then copy the rest in place */
2604 size = AOP_SIZE(op) - 1;
2605 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2609 pic16_emitcode("cpl","acc.7");
2610 pic16_aopPut(AOP(result),"a",3);
2613 pic16_aopPut(AOP(result),
2614 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2620 /*-----------------------------------------------------------------*/
2621 /* genUminus - unary minus code generation */
2622 /*-----------------------------------------------------------------*/
2623 static void genUminus (iCode *ic)
2626 sym_link *optype, *rtype;
2628 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2631 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2632 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2634 /* if both in bit space then special case */
2635 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
2636 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2638 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2639 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2640 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2645 optype = operandType(IC_LEFT(ic));
2646 rtype = operandType(IC_RESULT(ic));
2648 /* if float then do float stuff */
2649 if (IS_FLOAT(optype)) {
2650 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2654 /* otherwise subtract from zero by taking the 2's complement */
2655 size = AOP_SIZE(IC_LEFT(ic));
2657 for(i=0; i<size; i++) {
2658 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2659 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2661 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2662 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2666 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2667 for(i=1; i<size; i++) {
2669 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2673 /* release the aops */
2674 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2675 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2679 /*-----------------------------------------------------------------*/
2680 /* saveRegisters - will look for a call and save the registers */
2681 /*-----------------------------------------------------------------*/
2682 static void saveRegisters(iCode *lic)
2689 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2691 for (ic = lic ; ic ; ic = ic->next)
2692 if (ic->op == CALL || ic->op == PCALL)
2696 fprintf(stderr,"found parameter push with no function call\n");
2700 /* if the registers have been saved already then
2702 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2705 /* find the registers in use at this time
2706 and push them away to safety */
2707 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2711 if (options.useXstack) {
2712 if (bitVectBitValue(rsave,R0_IDX))
2713 pic16_emitcode("mov","b,r0");
2714 pic16_emitcode("mov","r0,%s",spname);
2715 for (i = 0 ; i < pic16_nRegs ; i++) {
2716 if (bitVectBitValue(rsave,i)) {
2718 pic16_emitcode("mov","a,b");
2720 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2721 pic16_emitcode("movx","@r0,a");
2722 pic16_emitcode("inc","r0");
2725 pic16_emitcode("mov","%s,r0",spname);
2726 if (bitVectBitValue(rsave,R0_IDX))
2727 pic16_emitcode("mov","r0,b");
2729 //for (i = 0 ; i < pic16_nRegs ; i++) {
2730 // if (bitVectBitValue(rsave,i))
2731 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2734 dtype = operandType(IC_LEFT(ic));
2735 if (currFunc && dtype &&
2736 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2737 IFFUNC_ISISR(currFunc->type) &&
2740 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2743 /*-----------------------------------------------------------------*/
2744 /* unsaveRegisters - pop the pushed registers */
2745 /*-----------------------------------------------------------------*/
2746 static void unsaveRegisters (iCode *ic)
2751 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2752 /* find the registers in use at this time
2753 and push them away to safety */
2754 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2757 if (options.useXstack) {
2758 pic16_emitcode("mov","r0,%s",spname);
2759 for (i = pic16_nRegs ; i >= 0 ; i--) {
2760 if (bitVectBitValue(rsave,i)) {
2761 pic16_emitcode("dec","r0");
2762 pic16_emitcode("movx","a,@r0");
2764 pic16_emitcode("mov","b,a");
2766 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2770 pic16_emitcode("mov","%s,r0",spname);
2771 if (bitVectBitValue(rsave,R0_IDX))
2772 pic16_emitcode("mov","r0,b");
2774 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2775 // if (bitVectBitValue(rsave,i))
2776 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2783 /*-----------------------------------------------------------------*/
2785 /*-----------------------------------------------------------------*/
2786 static void pushSide(operand * oper, int size)
2789 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2791 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2792 if (AOP_TYPE(oper) != AOP_REG &&
2793 AOP_TYPE(oper) != AOP_DIR &&
2795 pic16_emitcode("mov","a,%s",l);
2796 pic16_emitcode("push","acc");
2798 pic16_emitcode("push","%s",l);
2803 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2805 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2806 pic16_emitpcode(POC_MOVFW, src);
2807 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2809 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2810 src, pic16_popGet(AOP(op), offset)));
2815 /*-----------------------------------------------------------------*/
2816 /* assignResultValue - assign results to oper, rescall==1 is */
2817 /* called from genCall() or genPcall() */
2818 /*-----------------------------------------------------------------*/
2819 static void assignResultValue(operand * oper, int rescall)
2821 int size = AOP_SIZE(oper);
2824 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2825 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2828 /* assign result from a call/pcall function() */
2830 /* function results are stored in a special order,
2831 * see top of file with Function return policy, or manual */
2834 /* 8-bits, result in WREG */
2835 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2838 /* 16-bits, result in PRODL:WREG */
2839 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2843 /* 24-bits, result in PRODH:PRODL:WREG */
2844 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2848 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2849 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2853 /* >32-bits, result on stack, and FSR0 points to beginning.
2854 * Fix stack when done */
2856 // debugf("WARNING: Possible bug when returning more than 4-bytes\n");
2858 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2859 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2861 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2866 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2867 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2868 if(STACK_MODEL_LARGE) {
2870 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2874 int areg = 0; /* matching argument register */
2876 // debugf("_G.useWreg = %d\tGpsuedoStkPtr = %d\n", _G.useWreg, GpsuedoStkPtr);
2877 areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
2880 /* its called from genReceive (probably) -- VR */
2881 if(!GpsuedoStkPtr && _G.useWreg) {
2882 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2884 /* The last byte in the assignment is in W */
2885 if(areg <= GpsuedoStkPtr) {
2887 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
2889 // debugf("receive from WREG\n", 0);
2893 _G.stack_lat = AOP_SIZE(oper)-1;
2898 popaopidx(AOP(oper), offset, GpsuedoStkPtr);
2899 // debugf("receive from STACK\n", 0);
2906 /*-----------------------------------------------------------------*/
2907 /* genIpush - generate code for pushing this gets a little complex */
2908 /*-----------------------------------------------------------------*/
2909 static void genIpush (iCode *ic)
2911 // int size, offset=0;
2913 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2916 pic16_aopOp(IC_LEFT(ic), ic, FALSE );
2918 /* send to stack as normal */
2919 addSet(&_G.sendSet,ic);
2920 // addSetHead(&_G.sendSet,ic);
2921 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2926 int size, offset = 0 ;
2930 /* if this is not a parm push : ie. it is spill push
2931 and spill push is always done on the local stack */
2932 if (!ic->parmPush) {
2934 /* and the item is spilt then do nothing */
2935 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2938 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2939 size = AOP_SIZE(IC_LEFT(ic));
2940 /* push it on the stack */
2942 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2947 pic16_emitcode("push","%s",l);
2952 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2956 /*-----------------------------------------------------------------*/
2957 /* genIpop - recover the registers: can happen only for spilling */
2958 /*-----------------------------------------------------------------*/
2959 static void genIpop (iCode *ic)
2961 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2966 /* if the temp was not pushed then */
2967 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2970 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2971 size = AOP_SIZE(IC_LEFT(ic));
2974 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2977 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2982 /*-----------------------------------------------------------------*/
2983 /* unsaverbank - restores the resgister bank from stack */
2984 /*-----------------------------------------------------------------*/
2985 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2987 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2993 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2995 if (options.useXstack) {
2997 r = getFreePtr(ic,&aop,FALSE);
3000 pic16_emitcode("mov","%s,_spx",r->name);
3001 pic16_emitcode("movx","a,@%s",r->name);
3002 pic16_emitcode("mov","psw,a");
3003 pic16_emitcode("dec","%s",r->name);
3006 pic16_emitcode ("pop","psw");
3009 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
3010 if (options.useXstack) {
3011 pic16_emitcode("movx","a,@%s",r->name);
3012 //pic16_emitcode("mov","(%s+%d),a",
3013 // regspic16[i].base,8*bank+regspic16[i].offset);
3014 pic16_emitcode("dec","%s",r->name);
3017 pic16_emitcode("pop",""); //"(%s+%d)",
3018 //regspic16[i].base,8*bank); //+regspic16[i].offset);
3021 if (options.useXstack) {
3023 pic16_emitcode("mov","_spx,%s",r->name);
3024 pic16_freeAsmop(NULL,aop,ic,TRUE);
3030 /*-----------------------------------------------------------------*/
3031 /* saverbank - saves an entire register bank on the stack */
3032 /*-----------------------------------------------------------------*/
3033 static void saverbank (int bank, iCode *ic, bool pushPsw)
3035 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3042 if (options.useXstack) {
3045 r = getFreePtr(ic,&aop,FALSE);
3046 pic16_emitcode("mov","%s,_spx",r->name);
3050 for (i = 0 ; i < pic16_nRegs ;i++) {
3051 if (options.useXstack) {
3052 pic16_emitcode("inc","%s",r->name);
3053 //pic16_emitcode("mov","a,(%s+%d)",
3054 // regspic16[i].base,8*bank+regspic16[i].offset);
3055 pic16_emitcode("movx","@%s,a",r->name);
3057 pic16_emitcode("push","");// "(%s+%d)",
3058 //regspic16[i].base,8*bank+regspic16[i].offset);
3062 if (options.useXstack) {
3063 pic16_emitcode("mov","a,psw");
3064 pic16_emitcode("movx","@%s,a",r->name);
3065 pic16_emitcode("inc","%s",r->name);
3066 pic16_emitcode("mov","_spx,%s",r->name);
3067 pic16_freeAsmop (NULL,aop,ic,TRUE);
3070 pic16_emitcode("push","psw");
3072 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
3080 static int wparamCmp(void *p1, void *p2)
3082 return (!strcmp((char *)p1, (char *)p2));
3085 int inWparamList(char *s)
3087 return isinSetWith(wparamList, s, wparamCmp);
3091 /*-----------------------------------------------------------------*/
3092 /* genCall - generates a call statement */
3093 /*-----------------------------------------------------------------*/
3094 static void genCall (iCode *ic)
3102 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3104 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3105 /* if caller saves & we have not saved then */
3106 // if (!ic->regsSaved)
3107 // saveRegisters(ic);
3109 /* initialise stackParms for IPUSH pushes */
3110 // stackParms = psuedoStkPtr;
3111 // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
3112 fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
3113 inwparam = inWparamList(OP_SYMBOL(IC_LEFT(ic))->name);
3116 gpsimDebug_StackDump(__FILE__, __LINE__, fname );
3119 /* if send set is not empty the assign */
3122 int psuedoStkPtr=-1;
3123 int firstTimeThruLoop = 1;
3126 /* reverse sendSet if function is not reentrant */
3127 if(!IFFUNC_ISREENT(ftype))
3128 _G.sendSet = reverseSet(_G.sendSet);
3130 /* First figure how many parameters are getting passed */
3134 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3138 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3139 size = AOP_SIZE(IC_LEFT(sic));
3143 /* pass the last byte through WREG */
3147 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3148 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3149 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3151 if(!firstTimeThruLoop) {
3152 /* If this is not the first time we've been through the loop
3153 * then we need to save the parameter in a temporary
3154 * register. The last byte of the last parameter is
3158 // --psuedoStkPtr; // sanity check
3162 firstTimeThruLoop=0;
3164 mov2w (AOP(IC_LEFT(sic)), size);
3169 /* all arguments are passed via stack */
3173 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3174 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3175 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3177 // pushaop(AOP(IC_LEFT(sic)), size);
3178 mov2w (AOP(IC_LEFT(sic)), size);
3183 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3187 if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype)) {
3188 pushw(); /* save last parameter to stack if functions has varargs */
3192 } else use_wreg = 0;
3194 _G.stackRegSet = _G.sendSet;
3199 pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
3203 /* if we need to assign a result value */
3204 if ((IS_ITEMP(IC_RESULT(ic))
3205 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3206 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3207 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3210 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3213 assignResultValue(IC_RESULT(ic), 1);
3215 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3216 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3218 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3221 if(!stackParms && ic->parmBytes) {
3222 stackParms = ic->parmBytes;
3225 stackParms -= use_wreg;
3228 if(stackParms == 1) {
3229 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
3231 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3232 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3234 if(STACK_MODEL_LARGE) {
3236 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3241 gpsimDebug_StackDump(__FILE__, __LINE__, fname);
3244 /* adjust the stack for parameters if required */
3245 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3248 /* if register bank was saved then pop them */
3250 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3252 /* if we hade saved some registers then unsave them */
3253 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3254 unsaveRegisters (ic);
3260 /*-----------------------------------------------------------------*/
3261 /* genPcall - generates a call by pointer statement */
3262 /* new version, created from genCall - HJD */
3263 /*-----------------------------------------------------------------*/
3264 static void genPcall (iCode *ic)
3266 sym_link *ftype, *fntype;
3268 symbol *retlbl = newiTempLabel(NULL);
3269 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
3271 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3273 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3274 fntype = operandType( IC_LEFT(ic) )->next;
3276 /* if send set is not empty the assign */
3279 int psuedoStkPtr=-1;
3281 /* reverse sendSet if function is not reentrant */
3282 if(!IFFUNC_ISREENT(fntype))
3283 _G.sendSet = reverseSet(_G.sendSet);
3287 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3290 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3291 size = AOP_SIZE(IC_LEFT(sic));
3294 /* all parameters are passed via stack, since WREG is clobbered
3295 * by the calling sequence */
3297 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3298 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3299 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3301 mov2w (AOP(IC_LEFT(sic)), size);
3305 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3308 _G.stackRegSet = _G.sendSet;
3312 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3314 // push return address
3315 // push $ on return stack, then replace with retlbl
3317 pic16_emitpcodeNULLop(POC_PUSH);
3319 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
3320 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
3321 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
3322 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
3323 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
3324 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
3326 /* make the call by writing the pointer into pc */
3327 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
3328 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
3330 // note: MOVFF to PCL not allowed
3331 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
3332 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
3335 /* return address is here: (X) */
3336 pic16_emitpLabelFORCE(retlbl->key);
3338 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3341 /* if we need assign a result value */
3342 if ((IS_ITEMP(IC_RESULT(ic))
3343 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3344 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3345 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3348 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3351 assignResultValue(IC_RESULT(ic), 1);
3353 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3354 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3356 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3359 // stackParms -= use_wreg;
3362 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3363 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3364 if(STACK_MODEL_LARGE) {
3365 /* this implies that stackParms < 256 !!! -- VR */
3367 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3372 /*-----------------------------------------------------------------*/
3373 /* resultRemat - result is rematerializable */
3374 /*-----------------------------------------------------------------*/
3375 static int resultRemat (iCode *ic)
3377 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3378 if (SKIP_IC(ic) || ic->op == IFX)
3381 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3382 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3383 if (sym->remat && !POINTER_SET(ic))
3390 #if defined(__BORLANDC__) || defined(_MSC_VER)
3391 #define STRCASECMP stricmp
3393 #define STRCASECMP strcasecmp
3397 /*-----------------------------------------------------------------*/
3398 /* inExcludeList - return 1 if the string is in exclude Reg list */
3399 /*-----------------------------------------------------------------*/
3400 static bool inExcludeList(char *s)
3402 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3406 if (options.excludeRegs[i] &&
3407 STRCASECMP(options.excludeRegs[i],"none") == 0)
3410 for ( i = 0 ; options.excludeRegs[i]; i++) {
3411 if (options.excludeRegs[i] &&
3412 STRCASECMP(s,options.excludeRegs[i]) == 0)
3419 /*-----------------------------------------------------------------*/
3420 /* genFunction - generated code for function entry */
3421 /*-----------------------------------------------------------------*/
3422 static void genFunction (iCode *ic)
3427 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
3429 pic16_labelOffset += (max_key+4);
3434 ftype = operandType(IC_LEFT(ic));
3435 sym = OP_SYMBOL(IC_LEFT(ic));
3437 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3438 /* create an absolute section at the interrupt vector:
3439 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3447 sym = OP_SYMBOL( IC_LEFT(ic));
3449 if(interrupts[i]->name
3450 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3457 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3458 __FILE__, __LINE__, sym->name);
3461 _G.interruptvector = found;
3464 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3465 asym = newSymbol(asymname, 0);
3467 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3468 pic16_addpBlock( apb );
3470 pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
3471 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3472 pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3474 /* mark the end of this tiny function */
3475 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3480 abSym = Safe_calloc(1, sizeof(absSym));
3481 strcpy(abSym->name, asymname);
3483 switch( _G.interruptvector ) {
3484 case 0: abSym->address = 0x000000; break;
3485 case 1: abSym->address = 0x000008; break;
3486 case 2: abSym->address = 0x000018; break;
3489 /* relocate interrupt vectors if needed */
3490 abSym->address += pic16_options.ivt_loc;
3492 addSet(&absSymSet, abSym);
3496 /* create the function header */
3497 pic16_emitcode(";","-----------------------------------------");
3498 pic16_emitcode(";"," function %s",sym->name);
3499 pic16_emitcode(";","-----------------------------------------");
3501 pic16_emitcode("","%s:",sym->rname);
3502 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3508 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) {
3509 if(!strcmp(ab->name, sym->rname)) {
3510 pic16_pBlockConvert2Absolute(pb);
3517 if(IFFUNC_ISNAKED(ftype)) {
3518 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3522 /* if critical function then turn interrupts off */
3523 if (IFFUNC_ISCRITICAL(ftype)) {
3524 //pic16_emitcode("clr","ea");
3527 _G.fregsUsed = sym->regsUsed;
3529 /* if this is an interrupt service routine then
3530 * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
3531 if (IFFUNC_ISISR(sym->type)) {
3532 _G.usefastretfie = 1; /* use shadow registers by default */
3534 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3535 if(!(_G.interruptvector == 1)) {
3536 /* do not save WREG,STATUS,BSR for high priority interrupts
3537 * because they are stored in the hardware shadow registers already */
3538 _G.usefastretfie = 0;
3539 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3540 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3541 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3544 /* these should really be optimized somehow, because not all
3545 * interrupt handlers modify them */
3546 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3547 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3548 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3549 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3551 // pic16_pBlockConvert2ISR(pb);
3555 /* emit code to setup stack frame if user enabled,
3556 * and function is not main() */
3558 //fprintf(stderr, "function name: %s\n", sym->name);
3559 if(strcmp(sym->name, "main")) {
3560 if(1 /*!options.ommitFramePtr || sym->regsUsed*/) {
3561 /* setup the stack frame */
3562 if(STACK_MODEL_LARGE)
3563 pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2h));
3564 pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2l));
3565 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3566 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3567 if(STACK_MODEL_LARGE)
3568 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3572 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3575 if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
3577 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3578 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3580 pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
3583 if(inWparamList(sym->name)) {
3584 if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
3591 /* if callee-save to be used for this function
3592 * then save the registers being used in this function */
3593 // if (IFFUNC_CALLEESAVES(sym->type))
3597 /* if any registers used */
3598 if (sym->regsUsed) {
3599 /* save the registers used */
3600 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3601 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
3602 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3603 if (bitVectBitValue(sym->regsUsed,i)) {
3604 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3607 if(!pic16_regWithIdx(i)->wasUsed) {
3608 fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
3609 __FILE__, __LINE__, pic16_regWithIdx(i)->name);
3610 pic16_regWithIdx(i)->wasUsed = 1;
3614 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
3618 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3619 // fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
3622 /*-----------------------------------------------------------------*/
3623 /* genEndFunction - generates epilogue for functions */
3624 /*-----------------------------------------------------------------*/
3625 static void genEndFunction (iCode *ic)
3627 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3629 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3631 if(IFFUNC_ISNAKED(sym->type)) {
3632 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3638 /* add code for ISCRITICAL */
3639 if(IFFUNC_ISCRITICAL(sym->type)) {
3640 /* if critical function, turn on interrupts */
3642 /* TODO: add code here -- VR */
3645 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3647 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3648 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3650 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
3653 /* now we need to restore the registers */
3654 /* if any registers used */
3655 if (sym->regsUsed) {
3658 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
3659 /* restore registers used */
3660 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3661 for ( i = sym->regsUsed->size; i >= 0; i--) {
3662 if (bitVectBitValue(sym->regsUsed,i)) {
3663 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3667 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
3671 if(strcmp(sym->name, "main")) {
3672 if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
3673 /* restore stack frame */
3674 if(STACK_MODEL_LARGE)
3675 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2h ));
3676 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3677 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2l ));
3678 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3684 if (IFFUNC_ISISR(sym->type)) {
3685 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3686 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3687 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3688 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3690 if(!(_G.interruptvector == 1)) {
3691 /* do not restore interrupt vector for WREG,STATUS,BSR
3692 * for high priority interrupt, see genFunction */
3693 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3694 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3695 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3697 _G.interruptvector = 0; /* sanity check */
3700 /* if debug then send end of function */
3701 /* if (options.debug && currFunc) */
3703 debugFile->writeEndFunction (currFunc, ic, 1);
3706 if(_G.usefastretfie)
3707 pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
3709 pic16_emitpcodeNULLop(POC_RETFIE);
3711 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3713 _G.usefastretfie = 0;
3717 if (IFFUNC_ISCRITICAL(sym->type)) {
3718 pic16_emitcode("setb","ea");
3721 /* if debug then send end of function */
3723 debugFile->writeEndFunction (currFunc, ic, 1);
3726 /* insert code to restore stack frame, if user enabled it
3727 * and function is not main() */
3730 pic16_emitpcodeNULLop(POC_RETURN);
3732 /* Mark the end of a function */
3733 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3737 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3740 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
3741 if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
3743 if(dest->type == PO_WREG && (offset == 0)) {
3744 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3747 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
3751 /*-----------------------------------------------------------------*/
3752 /* genRet - generate code for return statement */
3753 /*-----------------------------------------------------------------*/
3754 static void genRet (iCode *ic)
3759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3760 /* if we have no return value then
3761 * just generate the "ret" */
3766 /* we have something to return then
3767 * move the return value into place */
3768 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3769 size = AOP_SIZE(IC_LEFT(ic));
3773 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3774 // pic16_emitpcode(POC_MOVFF,
3775 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3778 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3779 // pic16_emitpcode(POC_MOVFF,
3780 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3783 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3784 // pic16_emitpcode(POC_MOVFF,
3785 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3788 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3790 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3791 // pic16_emitpcode(POC_MOVFF,
3792 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3795 /* >32-bits, setup stack and FSR0 */
3797 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3798 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3800 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3802 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3807 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3808 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3810 if(STACK_MODEL_LARGE) {
3811 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3812 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3814 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3819 /* old code, left here for reference -- VR */
3823 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3825 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3826 pic16_emitpcomment("push %s",l);
3829 DEBUGpic16_emitcode(";", "%d", __LINE__);
3830 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3831 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3833 if (strcmp(fReturn[offset],l)) {
3834 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3835 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3836 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3838 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3842 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3852 if (strcmp(fReturn[pushed],"a"))
3853 pic16_emitcode("pop",fReturn[pushed]);
3855 pic16_emitcode("pop","acc");
3861 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3864 /* generate a jump to the return label
3865 * if the next is not the return statement */
3866 if (!(ic->next && ic->next->op == LABEL
3867 && IC_LABEL(ic->next) == returnLabel)) {
3869 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3870 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
3874 /*-----------------------------------------------------------------*/
3875 /* genLabel - generates a label */
3876 /*-----------------------------------------------------------------*/
3877 static void genLabel (iCode *ic)
3881 /* special case never generate */
3882 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3883 if (IC_LABEL(ic) == entryLabel)
3886 pic16_emitpLabel(IC_LABEL(ic)->key);
3887 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset));
3890 /*-----------------------------------------------------------------*/
3891 /* genGoto - generates a goto */
3892 /*-----------------------------------------------------------------*/
3894 static void genGoto (iCode *ic)
3896 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3897 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset);
3901 /*-----------------------------------------------------------------*/
3902 /* genMultbits :- multiplication of bits */
3903 /*-----------------------------------------------------------------*/
3904 static void genMultbits (operand *left,
3908 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3910 if(!pic16_sameRegs(AOP(result),AOP(right)))
3911 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3913 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3914 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3915 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3920 /*-----------------------------------------------------------------*/
3921 /* genMultOneByte : 8 bit multiplication & division */
3922 /*-----------------------------------------------------------------*/
3923 static void genMultOneByte (operand *left,
3928 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3929 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3930 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3932 /* (if two literals, the value is computed before) */
3933 /* if one literal, literal on the right */
3934 if (AOP_TYPE(left) == AOP_LIT){
3940 /* size is already checked in genMult == 1 */
3941 // size = AOP_SIZE(result);
3943 if (AOP_TYPE(right) == AOP_LIT){
3944 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3945 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3946 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3947 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3949 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3950 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3951 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3952 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3955 pic16_genMult8X8_8 (left, right,result);
3958 /*-----------------------------------------------------------------*/
3959 /* genMultOneWord : 16 bit multiplication */
3960 /*-----------------------------------------------------------------*/
3961 static void genMultOneWord (operand *left,
3966 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3967 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3968 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3970 /* (if two literals, the value is computed before)
3971 * if one literal, literal on the right */
3972 if (AOP_TYPE(left) == AOP_LIT){
3978 /* size is checked already == 2 */
3979 // size = AOP_SIZE(result);
3981 if (AOP_TYPE(right) == AOP_LIT) {
3982 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3983 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3984 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3985 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3987 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3988 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3989 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3990 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3993 pic16_genMult16X16_16(left, right,result);
3996 /*-----------------------------------------------------------------*/
3997 /* genMultOneLong : 32 bit multiplication */
3998 /*-----------------------------------------------------------------*/
3999 static void genMultOneLong (operand *left,
4004 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4005 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4006 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4008 /* (if two literals, the value is computed before)
4009 * if one literal, literal on the right */
4010 if (AOP_TYPE(left) == AOP_LIT){
4016 /* size is checked already == 4 */
4017 // size = AOP_SIZE(result);
4019 if (AOP_TYPE(right) == AOP_LIT) {
4020 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4021 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4022 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4023 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4025 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4026 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4027 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4028 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4031 pic16_genMult32X32_32(left, right,result);
4036 /*-----------------------------------------------------------------*/
4037 /* genMult - generates code for multiplication */
4038 /*-----------------------------------------------------------------*/
4039 static void genMult (iCode *ic)
4041 operand *left = IC_LEFT(ic);
4042 operand *right = IC_RIGHT(ic);
4043 operand *result= IC_RESULT(ic);
4045 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4046 /* assign the amsops */
4047 pic16_aopOp (left,ic,FALSE);
4048 pic16_aopOp (right,ic,FALSE);
4049 pic16_aopOp (result,ic,TRUE);
4051 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4053 /* special cases first *
4055 if (AOP_TYPE(left) == AOP_CRY
4056 && AOP_TYPE(right)== AOP_CRY) {
4057 genMultbits(left,right,result);
4061 /* if both are of size == 1 */
4062 if(AOP_SIZE(left) == 1
4063 && AOP_SIZE(right) == 1) {
4064 genMultOneByte(left,right,result);
4068 /* if both are of size == 2 */
4069 if(AOP_SIZE(left) == 2
4070 && AOP_SIZE(right) == 2) {
4071 genMultOneWord(left, right, result);
4075 /* if both are of size == 4 */
4076 if(AOP_SIZE(left) == 4
4077 && AOP_SIZE(right) == 4) {
4078 genMultOneLong(left, right, result);
4082 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
4085 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
4086 /* should have been converted to function call */
4090 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4091 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4092 pic16_freeAsmop(result,NULL,ic,TRUE);
4095 /*-----------------------------------------------------------------*/
4096 /* genDivbits :- division of bits */
4097 /*-----------------------------------------------------------------*/
4098 static void genDivbits (operand *left,
4105 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4106 /* the result must be bit */
4107 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4108 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4112 pic16_emitcode("div","ab");
4113 pic16_emitcode("rrc","a");
4114 pic16_aopPut(AOP(result),"c",0);
4117 /*-----------------------------------------------------------------*/
4118 /* genDivOneByte : 8 bit division */
4119 /*-----------------------------------------------------------------*/
4120 static void genDivOneByte (operand *left,
4124 sym_link *opetype = operandType(result);
4129 /* result = divident / divisor
4130 * - divident may be a register or a literal,
4131 * - divisor may be a register or a literal,
4132 * so there are 3 cases (literal / literal is optimized
4133 * by the front-end) to handle.
4134 * In addition we must handle signed and unsigned, which
4135 * result in 6 final different cases -- VR */
4137 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4138 size = AOP_SIZE(result) - 1;
4140 /* signed or unsigned */
4141 if (SPEC_USIGN(opetype)) {
4142 pCodeOp *pct1, /* count */
4145 symbol *label1, *label2, *label3;;
4148 /* unsigned is easy */
4150 pct1 = pic16_popGetTempReg(1);
4151 pct2 = pic16_popGetTempReg(1);
4152 pct3 = pic16_popGetTempReg(1);
4154 label1 = newiTempLabel(NULL);
4155 label2 = newiTempLabel(NULL);
4156 label3 = newiTempLabel(NULL);
4158 /* the following algorithm is extracted from divuint.c */
4160 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
4161 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
4163 pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
4165 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
4167 pic16_emitpLabel(label1->key);
4170 pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
4174 pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
4178 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
4180 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
4181 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
4183 pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
4184 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
4185 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
4187 pic16_emitpLabel( label3->key );
4188 pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
4189 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
4193 pic16_emitpLabel(label2->key);
4194 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
4195 pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
4196 pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
4198 /* result is in wreg */
4199 if(AOP_TYPE(result) != AOP_ACC)
4200 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
4202 pic16_popReleaseTempReg( pct3, 1);
4203 pic16_popReleaseTempReg( pct2, 1);
4204 pic16_popReleaseTempReg( pct1, 1);
4209 /* signed is a little bit more difficult */
4211 /* save the signs of the operands */
4212 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4214 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4215 pic16_emitcode("push","acc"); /* save it on the stack */
4217 /* now sign adjust for both left & right */
4218 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4220 lbl = newiTempLabel(NULL);
4221 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4222 pic16_emitcode("cpl","a");
4223 pic16_emitcode("inc","a");
4224 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4225 pic16_emitcode("mov","b,a");
4227 /* sign adjust left side */
4228 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4231 lbl = newiTempLabel(NULL);
4232 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4233 pic16_emitcode("cpl","a");
4234 pic16_emitcode("inc","a");
4235 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4237 /* now the division */
4238 pic16_emitcode("div","ab");
4239 /* we are interested in the lower order
4241 pic16_emitcode("mov","b,a");
4242 lbl = newiTempLabel(NULL);
4243 pic16_emitcode("pop","acc");
4244 /* if there was an over flow we don't
4245 adjust the sign of the result */
4246 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4247 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4249 pic16_emitcode("clr","a");
4250 pic16_emitcode("subb","a,b");
4251 pic16_emitcode("mov","b,a");
4252 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4254 /* now we are done */
4255 pic16_aopPut(AOP(result),"b",0);
4257 pic16_emitcode("mov","c,b.7");
4258 pic16_emitcode("subb","a,acc");
4261 pic16_aopPut(AOP(result),"a",offset++);
4265 /*-----------------------------------------------------------------*/
4266 /* genDiv - generates code for division */
4267 /*-----------------------------------------------------------------*/
4268 static void genDiv (iCode *ic)
4270 operand *left = IC_LEFT(ic);
4271 operand *right = IC_RIGHT(ic);
4272 operand *result= IC_RESULT(ic);
4275 /* Division is a very lengthy algorithm, so it is better
4276 * to call support routines than inlining algorithm.
4277 * Division functions written here just in case someone
4278 * wants to inline and not use the support libraries -- VR */
4280 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4281 /* assign the amsops */
4282 pic16_aopOp (left,ic,FALSE);
4283 pic16_aopOp (right,ic,FALSE);
4284 pic16_aopOp (result,ic,TRUE);
4286 /* special cases first */
4288 if (AOP_TYPE(left) == AOP_CRY &&
4289 AOP_TYPE(right)== AOP_CRY) {
4290 genDivbits(left,right,result);
4294 /* if both are of size == 1 */
4295 if (AOP_SIZE(left) == 1 &&
4296 AOP_SIZE(right) == 1 ) {
4297 genDivOneByte(left,right,result);
4301 /* should have been converted to function call */
4304 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4305 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4306 pic16_freeAsmop(result,NULL,ic,TRUE);
4309 /*-----------------------------------------------------------------*/
4310 /* genModbits :- modulus of bits */
4311 /*-----------------------------------------------------------------*/
4312 static void genModbits (operand *left,
4319 /* the result must be bit */
4320 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4321 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4325 pic16_emitcode("div","ab");
4326 pic16_emitcode("mov","a,b");
4327 pic16_emitcode("rrc","a");
4328 pic16_aopPut(AOP(result),"c",0);
4331 /*-----------------------------------------------------------------*/
4332 /* genModOneByte : 8 bit modulus */
4333 /*-----------------------------------------------------------------*/
4334 static void genModOneByte (operand *left,
4338 sym_link *opetype = operandType(result);
4342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4343 /* signed or unsigned */
4344 if (SPEC_USIGN(opetype)) {
4345 /* unsigned is easy */
4346 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4347 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4349 pic16_emitcode("div","ab");
4350 pic16_aopPut(AOP(result),"b",0);
4354 /* signed is a little bit more difficult */
4356 /* save the signs of the operands */
4357 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4360 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4361 pic16_emitcode("push","acc"); /* save it on the stack */
4363 /* now sign adjust for both left & right */
4364 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4367 lbl = newiTempLabel(NULL);
4368 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4369 pic16_emitcode("cpl","a");
4370 pic16_emitcode("inc","a");
4371 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4372 pic16_emitcode("mov","b,a");
4374 /* sign adjust left side */
4375 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4378 lbl = newiTempLabel(NULL);
4379 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4380 pic16_emitcode("cpl","a");
4381 pic16_emitcode("inc","a");
4382 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4384 /* now the multiplication */
4385 pic16_emitcode("div","ab");
4386 /* we are interested in the lower order
4388 lbl = newiTempLabel(NULL);
4389 pic16_emitcode("pop","acc");
4390 /* if there was an over flow we don't
4391 adjust the sign of the result */
4392 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4393 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4395 pic16_emitcode("clr","a");
4396 pic16_emitcode("subb","a,b");
4397 pic16_emitcode("mov","b,a");
4398 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4400 /* now we are done */
4401 pic16_aopPut(AOP(result),"b",0);
4405 /*-----------------------------------------------------------------*/
4406 /* genMod - generates code for division */
4407 /*-----------------------------------------------------------------*/
4408 static void genMod (iCode *ic)
4410 operand *left = IC_LEFT(ic);
4411 operand *right = IC_RIGHT(ic);
4412 operand *result= IC_RESULT(ic);
4414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4415 /* assign the amsops */
4416 pic16_aopOp (left,ic,FALSE);
4417 pic16_aopOp (right,ic,FALSE);
4418 pic16_aopOp (result,ic,TRUE);
4420 /* special cases first */
4422 if (AOP_TYPE(left) == AOP_CRY &&
4423 AOP_TYPE(right)== AOP_CRY) {
4424 genModbits(left,right,result);
4428 /* if both are of size == 1 */
4429 if (AOP_SIZE(left) == 1 &&
4430 AOP_SIZE(right) == 1 ) {
4431 genModOneByte(left,right,result);
4435 /* should have been converted to function call */
4439 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 pic16_freeAsmop(result,NULL,ic,TRUE);
4444 /*-----------------------------------------------------------------*/
4445 /* genIfxJump :- will create a jump depending on the ifx */
4446 /*-----------------------------------------------------------------*/
4448 note: May need to add parameter to indicate when a variable is in bit space.
4450 static void genIfxJump (iCode *ic, char *jval)
4453 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4454 /* if true label then we jump if condition
4456 if ( IC_TRUE(ic) ) {
4458 if(strcmp(jval,"a") == 0)
4460 else if (strcmp(jval,"c") == 0)
4463 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4464 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4467 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4468 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
4472 /* false label is present */
4473 if(strcmp(jval,"a") == 0)
4475 else if (strcmp(jval,"c") == 0)
4478 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4479 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4482 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4483 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
4488 /* mark the icode as generated */
4495 /*-----------------------------------------------------------------*/
4497 /*-----------------------------------------------------------------*/
4498 static void genSkip(iCode *ifx,int status_bit)
4500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4504 if ( IC_TRUE(ifx) ) {
4505 switch(status_bit) {
4520 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4521 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4525 switch(status_bit) {
4539 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4540 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4547 /*-----------------------------------------------------------------*/
4549 /*-----------------------------------------------------------------*/
4550 static void genSkipc(resolvedIfx *rifx)
4552 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4562 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4563 rifx->generated = 1;
4566 /*-----------------------------------------------------------------*/
4568 /*-----------------------------------------------------------------*/
4569 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4571 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4576 if( (rifx->condition ^ invert_condition) & 1)
4581 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4582 rifx->generated = 1;
4586 /*-----------------------------------------------------------------*/
4588 /*-----------------------------------------------------------------*/
4589 static void genSkipz(iCode *ifx, int condition)
4600 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4602 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4605 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4607 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4612 /*-----------------------------------------------------------------*/
4614 /*-----------------------------------------------------------------*/
4615 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4621 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4623 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4626 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4627 rifx->generated = 1;
4631 /*-----------------------------------------------------------------*/
4632 /* genChkZeroes :- greater or less than comparison */
4633 /* For each byte in a literal that is zero, inclusive or the */
4634 /* the corresponding byte in the operand with W */
4635 /* returns true if any of the bytes are zero */
4636 /*-----------------------------------------------------------------*/
4637 static int genChkZeroes(operand *op, int lit, int size)
4644 i = (lit >> (size*8)) & 0xff;
4648 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4650 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4659 /*-----------------------------------------------------------------*/
4660 /* genCmp :- greater or less than comparison */
4661 /*-----------------------------------------------------------------*/
4663 static void genCmp (operand *left,operand *right,
4664 operand *result, iCode *ifx, int sign)
4666 int size; //, offset = 0 ;
4667 unsigned long lit = 0L,i = 0;
4668 resolvedIfx rFalseIfx;
4669 // resolvedIfx rTrueIfx;
4671 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4674 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4675 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4679 resolveIfx(&rFalseIfx,ifx);
4680 truelbl = newiTempLabel(NULL);
4681 size = max(AOP_SIZE(left),AOP_SIZE(right));
4683 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4687 /* if literal is on the right then swap with left */
4688 if ((AOP_TYPE(right) == AOP_LIT)) {
4689 operand *tmp = right ;
4690 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4691 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4694 lit = (lit - 1) & mask;
4697 rFalseIfx.condition ^= 1;
4700 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4701 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4705 //if(IC_TRUE(ifx) == NULL)
4706 /* if left & right are bit variables */
4707 if (AOP_TYPE(left) == AOP_CRY &&
4708 AOP_TYPE(right) == AOP_CRY ) {
4709 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4710 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4712 /* subtract right from left if at the
4713 end the carry flag is set then we know that
4714 left is greater than right */
4716 symbol *lbl = newiTempLabel(NULL);
4719 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4720 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
4724 if(AOP_TYPE(right) == AOP_LIT) {
4726 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4728 DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
4735 genSkipCond(&rFalseIfx,left,size-1,7);
4737 /* no need to compare to 0...*/
4738 /* NOTE: this is a de-generate compare that most certainly
4739 * creates some dead code. */
4740 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4742 if(ifx) ifx->generated = 1;
4749 //i = (lit >> (size*8)) & 0xff;
4750 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4752 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4754 i = ((0-lit) & 0xff);
4757 /* lit is 0x7f, all signed chars are less than
4758 * this except for 0x7f itself */
4759 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4760 genSkipz2(&rFalseIfx,0);
4762 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4763 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4764 genSkipc(&rFalseIfx);
4769 genSkipz2(&rFalseIfx,1);
4771 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4772 genSkipc(&rFalseIfx);
4776 if(ifx) ifx->generated = 1;
4780 /* chars are out of the way. now do ints and longs */
4783 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4790 genSkipCond(&rFalseIfx,left,size,7);
4791 if(ifx) ifx->generated = 1;
4796 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4798 //rFalseIfx.condition ^= 1;
4799 //genSkipCond(&rFalseIfx,left,size,7);
4800 //rFalseIfx.condition ^= 1;
4802 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4803 if(rFalseIfx.condition)
4804 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4806 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4808 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4809 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4810 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4813 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4815 if(rFalseIfx.condition) {
4817 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4823 genSkipc(&rFalseIfx);
4824 pic16_emitpLabel(truelbl->key);
4825 if(ifx) ifx->generated = 1;
4832 if( (lit & 0xff) == 0) {
4833 /* lower byte is zero */
4834 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4835 i = ((lit >> 8) & 0xff) ^0x80;
4836 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4837 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4838 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4839 genSkipc(&rFalseIfx);
4842 if(ifx) ifx->generated = 1;
4847 /* Special cases for signed longs */
4848 if( (lit & 0xffffff) == 0) {
4849 /* lower byte is zero */
4850 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4851 i = ((lit >> 8*3) & 0xff) ^0x80;
4852 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4853 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4854 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4855 genSkipc(&rFalseIfx);
4858 if(ifx) ifx->generated = 1;
4866 if(lit & (0x80 << (size*8))) {
4867 /* lit is negative */
4868 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4870 //genSkipCond(&rFalseIfx,left,size,7);
4872 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4874 if(rFalseIfx.condition)
4875 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4877 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4881 /* lit is positive */
4882 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4883 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4884 if(rFalseIfx.condition)
4885 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4887 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4892 This works, but is only good for ints.
4893 It also requires a "known zero" register.
4894 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4895 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4896 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4897 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4898 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4899 genSkipc(&rFalseIfx);
4901 pic16_emitpLabel(truelbl->key);
4902 if(ifx) ifx->generated = 1;
4906 /* There are no more special cases, so perform a general compare */
4908 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4909 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4913 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4915 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4917 //rFalseIfx.condition ^= 1;
4918 genSkipc(&rFalseIfx);
4920 pic16_emitpLabel(truelbl->key);
4922 if(ifx) ifx->generated = 1;
4929 /* sign is out of the way. So now do an unsigned compare */
4930 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4933 /* General case - compare to an unsigned literal on the right.*/
4935 i = (lit >> (size*8)) & 0xff;
4936 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4937 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4939 i = (lit >> (size*8)) & 0xff;
4942 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4944 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4946 /* this byte of the lit is zero,
4947 *if it's not the last then OR in the variable */
4949 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4954 pic16_emitpLabel(lbl->key);
4955 // pic16_emitpLabel(truelbl->key);
4956 //if(emitFinalCheck)
4957 genSkipc(&rFalseIfx);
4959 pic16_emitpLabel(truelbl->key);
4961 if(ifx) ifx->generated = 1;
4968 if(AOP_TYPE(left) == AOP_LIT) {
4969 //symbol *lbl = newiTempLabel(NULL);
4971 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4974 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4977 if((lit == 0) && (sign == 0)){
4980 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4982 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4984 genSkipz2(&rFalseIfx,0);
4985 if(ifx) ifx->generated = 1;
4992 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4993 /* degenerate compare can never be true */
4994 if(rFalseIfx.condition == 0)
4995 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4997 if(ifx) ifx->generated = 1;
5002 /* signed comparisons to a literal byte */
5004 int lp1 = (lit+1) & 0xff;
5006 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
5009 rFalseIfx.condition ^= 1;
5010 genSkipCond(&rFalseIfx,right,0,7);
5013 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5014 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5015 genSkipz2(&rFalseIfx,1);
5018 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5019 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5020 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5021 rFalseIfx.condition ^= 1;
5022 genSkipc(&rFalseIfx);
5026 /* unsigned comparisons to a literal byte */
5028 switch(lit & 0xff ) {
5030 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5031 genSkipz2(&rFalseIfx,0);
5034 rFalseIfx.condition ^= 1;
5035 genSkipCond(&rFalseIfx,right,0,7);
5039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5040 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5042 rFalseIfx.condition ^= 1;
5043 if (AOP_TYPE(result) == AOP_CRY)
5044 genSkipc(&rFalseIfx);
5046 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5047 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5053 if(ifx) ifx->generated = 1;
5054 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5060 /* Size is greater than 1 */
5068 /* this means lit = 0xffffffff, or -1 */
5071 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5072 rFalseIfx.condition ^= 1;
5073 genSkipCond(&rFalseIfx,right,size,7);
5074 if(ifx) ifx->generated = 1;
5076 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5085 if(rFalseIfx.condition) {
5086 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5087 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5090 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5092 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5096 if(rFalseIfx.condition) {
5097 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5098 pic16_emitpLabel(truelbl->key);
5100 rFalseIfx.condition ^= 1;
5101 genSkipCond(&rFalseIfx,right,s,7);
5104 if(ifx) ifx->generated = 1;
5106 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5112 if((size == 1) && (0 == (lp1&0xff))) {
5113 /* lower byte of signed word is zero */
5114 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5115 i = ((lp1 >> 8) & 0xff) ^0x80;
5116 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5117 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5118 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5119 rFalseIfx.condition ^= 1;
5120 genSkipc(&rFalseIfx);
5123 if(ifx) ifx->generated = 1;
5125 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5131 if(lit & (0x80 << (size*8))) {
5132 /* Lit is less than zero */
5133 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5134 //rFalseIfx.condition ^= 1;
5135 //genSkipCond(&rFalseIfx,left,size,7);
5136 //rFalseIfx.condition ^= 1;
5137 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5138 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5140 if(rFalseIfx.condition)
5141 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5143 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5147 /* Lit is greater than or equal to zero */
5148 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5149 //rFalseIfx.condition ^= 1;
5150 //genSkipCond(&rFalseIfx,right,size,7);
5151 //rFalseIfx.condition ^= 1;
5153 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5154 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5156 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5157 if(rFalseIfx.condition)
5158 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5160 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5165 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5166 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5170 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5172 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5174 rFalseIfx.condition ^= 1;
5175 //rFalseIfx.condition = 1;
5176 genSkipc(&rFalseIfx);
5178 pic16_emitpLabel(truelbl->key);
5180 if(ifx) ifx->generated = 1;
5183 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5190 /* compare word or long to an unsigned literal on the right.*/
5195 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5198 break; /* handled above */
5201 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5203 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5204 genSkipz2(&rFalseIfx,0);
5208 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5210 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5213 if(rFalseIfx.condition)
5214 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5216 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5219 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5220 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5222 rFalseIfx.condition ^= 1;
5223 genSkipc(&rFalseIfx);
5226 pic16_emitpLabel(truelbl->key);
5228 if(ifx) ifx->generated = 1;
5230 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5238 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5239 i = (lit >> (size*8)) & 0xff;
5241 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5242 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5245 i = (lit >> (size*8)) & 0xff;
5248 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5250 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5252 /* this byte of the lit is zero,
5253 * if it's not the last then OR in the variable */
5255 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5260 pic16_emitpLabel(lbl->key);
5262 rFalseIfx.condition ^= 1;
5264 genSkipc(&rFalseIfx);
5268 pic16_emitpLabel(truelbl->key);
5269 if(ifx) ifx->generated = 1;
5271 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5277 /* Compare two variables */
5279 DEBUGpic16_emitcode(";sign","%d",sign);
5283 /* Sigh. thus sucks... */
5287 pctemp = pic16_popGetTempReg(1);
5288 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5289 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5290 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5291 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5292 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5293 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5294 pic16_popReleaseTempReg(pctemp, 1);
5296 /* Signed char comparison */
5297 /* Special thanks to Nikolai Golovchenko for this snippet */
5298 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5299 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5300 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5301 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5302 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5303 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5305 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5306 genSkipc(&rFalseIfx);
5308 if(ifx) ifx->generated = 1;
5310 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5318 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5319 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5323 /* The rest of the bytes of a multi-byte compare */
5327 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5330 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5331 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5336 pic16_emitpLabel(lbl->key);
5338 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5339 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5340 (AOP_TYPE(result) == AOP_REG)) {
5341 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5342 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5344 genSkipc(&rFalseIfx);
5346 //genSkipc(&rFalseIfx);
5347 if(ifx) ifx->generated = 1;
5350 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5358 if ((AOP_TYPE(result) != AOP_CRY)
5359 && AOP_SIZE(result)) {
5360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5362 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5364 pic16_outBitC(result);
5366 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5367 /* if the result is used in the next
5368 ifx conditional branch then generate
5369 code a little differently */
5371 genIfxJump (ifx,"c");
5373 pic16_outBitC(result);
5374 /* leave the result in acc */
5379 #else /* old version of genCmp() */
5381 /* new version of genCmp -- VR 20041012 */
5382 static void genCmp (operand *left,operand *right,
5383 operand *result, iCode *ifx, int sign)
5385 int size; //, offset = 0 ;
5386 unsigned long lit = 0L,i = 0;
5387 resolvedIfx rFalseIfx;
5388 int willCheckCarry=0;
5389 // resolvedIfx rTrueIfx;
5391 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5395 * subtract right from left if at the end the carry flag is set then we
5396 * know that left is greater than right */
5398 resolveIfx(&rFalseIfx,ifx);
5399 truelbl = newiTempLabel(NULL);
5400 size = max(AOP_SIZE(left),AOP_SIZE(right));
5402 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5404 /* POC_CPFSGT compare f, wreg, skip if f greater than wreg
5405 * POC_CPFSLT compare f, wreg, skip if f less then wreg */
5408 /* if literal is on the right then swap with left */
5409 if ((AOP_TYPE(right) == AOP_LIT)) {
5410 operand *tmp = right ;
5411 unsigned long mask = (0x100 << (8*(size-1))) - 1;
5413 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5415 // lit = (lit - 1) & mask;
5418 rFalseIfx.condition ^= 1;
5420 if ((AOP_TYPE(left) == AOP_LIT)) {
5421 /* float compares are handled by support functions */
5422 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
5426 //if(IC_TRUE(ifx) == NULL)
5427 /* if left & right are bit variables */
5428 if (AOP_TYPE(left) == AOP_CRY &&
5429 AOP_TYPE(right) == AOP_CRY ) {
5430 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5431 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
5434 symbol *lbl = newiTempLabel(NULL);
5436 if(AOP_TYPE(left) == AOP_LIT) {
5437 DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
5439 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5441 else willCheckCarry = 0;
5444 if((lit == 0) && (sign == 0)){
5447 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5449 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
5451 genSkipz2(&rFalseIfx,0);
5452 if(ifx) ifx->generated = 1;
5459 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
5460 /* degenerate compare can never be true */
5461 if(rFalseIfx.condition == 0)
5462 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
5464 if(ifx) ifx->generated = 1;
5469 /* signed comparisons to a literal byte */
5471 int lp1 = (lit+1) & 0xff;
5473 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d",__LINE__,lit, rFalseIfx.condition);
5476 rFalseIfx.condition ^= 1;
5477 genSkipCond(&rFalseIfx,right,0,7);
5480 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5481 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5482 genSkipz2(&rFalseIfx,1);
5485 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
5487 if(rFalseIfx.condition)
5488 pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
5490 pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
5492 if(willCheckCarry) {
5493 if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
5494 else { emitSETC; emitCLRC; }
5497 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5500 /* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5501 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5502 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5503 rFalseIfx.condition ^= 1;
5504 genSkipc(&rFalseIfx);
5509 /* unsigned comparisons to a literal byte */
5511 switch(lit & 0xff ) {
5513 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5514 genSkipz2(&rFalseIfx,0);
5517 rFalseIfx.condition ^= 1;
5518 genSkipCond(&rFalseIfx,right,0,7);
5522 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5523 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5524 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5525 rFalseIfx.condition ^= 1;
5526 if (AOP_TYPE(result) == AOP_CRY)
5527 genSkipc(&rFalseIfx);
5529 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5530 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5536 if(ifx) ifx->generated = 1;
5537 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5543 /* Size is greater than 1 */
5551 /* this means lit = 0xffffffff, or -1 */
5554 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5555 rFalseIfx.condition ^= 1;
5556 genSkipCond(&rFalseIfx,right,size,7);
5557 if(ifx) ifx->generated = 1;
5564 if(rFalseIfx.condition) {
5565 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5566 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5569 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5571 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5575 if(rFalseIfx.condition) {
5576 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5577 pic16_emitpLabel(truelbl->key);
5579 rFalseIfx.condition ^= 1;
5580 genSkipCond(&rFalseIfx,right,s,7);
5583 if(ifx) ifx->generated = 1;
5587 if((size == 1) && (0 == (lp1&0xff))) {
5588 /* lower byte of signed word is zero */
5589 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5590 i = ((lp1 >> 8) & 0xff) ^0x80;
5591 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5592 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5593 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5594 rFalseIfx.condition ^= 1;
5595 genSkipc(&rFalseIfx);
5598 if(ifx) ifx->generated = 1;
5602 if(lit & (0x80 << (size*8))) {
5603 /* Lit is less than zero */
5604 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5605 //rFalseIfx.condition ^= 1;
5606 //genSkipCond(&rFalseIfx,left,size,7);
5607 //rFalseIfx.condition ^= 1;
5608 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5609 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5611 if(rFalseIfx.condition)
5612 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5614 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5618 /* Lit is greater than or equal to zero */
5619 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5620 //rFalseIfx.condition ^= 1;
5621 //genSkipCond(&rFalseIfx,right,size,7);
5622 //rFalseIfx.condition ^= 1;
5624 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5625 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5627 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5628 if(rFalseIfx.condition)
5629 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5631 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5636 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5637 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5641 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5643 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5645 rFalseIfx.condition ^= 1;
5646 //rFalseIfx.condition = 1;
5647 genSkipc(&rFalseIfx);
5649 pic16_emitpLabel(truelbl->key);
5651 if(ifx) ifx->generated = 1;
5656 /* compare word or long to an unsigned literal on the right.*/
5661 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5664 break; /* handled above */
5667 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5669 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5670 genSkipz2(&rFalseIfx,0);
5674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5676 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5679 if(rFalseIfx.condition)
5680 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5682 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5685 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5686 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5688 rFalseIfx.condition ^= 1;
5689 genSkipc(&rFalseIfx);
5692 pic16_emitpLabel(truelbl->key);
5694 if(ifx) ifx->generated = 1;
5700 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5701 i = (lit >> (size*8)) & 0xff;
5703 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5704 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5707 i = (lit >> (size*8)) & 0xff;
5710 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5712 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5714 /* this byte of the lit is zero,
5715 * if it's not the last then OR in the variable */
5717 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5722 pic16_emitpLabel(lbl->key);
5724 rFalseIfx.condition ^= 1;
5726 genSkipc(&rFalseIfx);
5730 pic16_emitpLabel(truelbl->key);
5731 if(ifx) ifx->generated = 1;
5735 /* Compare two variables */
5737 DEBUGpic16_emitcode(";sign","%d",sign);
5741 /* Sigh. thus sucks... */
5745 pctemp = pic16_popGetTempReg(1);
5746 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5747 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5748 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5749 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5750 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5751 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5752 pic16_popReleaseTempReg(pctemp, 1);
5754 /* Signed char comparison */
5755 /* Special thanks to Nikolai Golovchenko for this snippet */
5756 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5757 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5758 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5759 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5760 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5761 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5763 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5764 genSkipc(&rFalseIfx);
5766 if(ifx) ifx->generated = 1;
5772 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5773 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5777 /* The rest of the bytes of a multi-byte compare */
5781 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5784 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5785 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5790 pic16_emitpLabel(lbl->key);
5792 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5793 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5794 (AOP_TYPE(result) == AOP_REG)) {
5795 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5796 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5798 genSkipc(&rFalseIfx);
5800 //genSkipc(&rFalseIfx);
5801 if(ifx) ifx->generated = 1;
5808 if ((AOP_TYPE(result) != AOP_CRY)
5809 && AOP_SIZE(result)) {
5810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5812 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5814 pic16_outBitC(result);
5816 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5817 /* if the result is used in the next
5818 ifx conditional branch then generate
5819 code a little differently */
5821 genIfxJump (ifx,"c");
5823 pic16_outBitC(result);
5824 /* leave the result in acc */
5832 /*-----------------------------------------------------------------*/
5833 /* genCmpGt :- greater than comparison */
5834 /*-----------------------------------------------------------------*/
5835 static void genCmpGt (iCode *ic, iCode *ifx)
5837 operand *left, *right, *result;
5838 sym_link *letype , *retype;
5841 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5843 right= IC_RIGHT(ic);
5844 result = IC_RESULT(ic);
5846 letype = getSpec(operandType(left));
5847 retype =getSpec(operandType(right));
5848 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5849 /* assign the amsops */
5850 pic16_aopOp (left,ic,FALSE);
5851 pic16_aopOp (right,ic,FALSE);
5852 pic16_aopOp (result,ic,TRUE);
5854 genCmp(right, left, result, ifx, sign);
5856 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5857 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5858 pic16_freeAsmop(result,NULL,ic,TRUE);
5861 /*-----------------------------------------------------------------*/
5862 /* genCmpLt - less than comparisons */
5863 /*-----------------------------------------------------------------*/
5864 static void genCmpLt (iCode *ic, iCode *ifx)
5866 operand *left, *right, *result;
5867 sym_link *letype , *retype;
5870 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5872 right= IC_RIGHT(ic);
5873 result = IC_RESULT(ic);
5875 letype = getSpec(operandType(left));
5876 retype =getSpec(operandType(right));
5877 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5879 /* assign the amsops */
5880 pic16_aopOp (left,ic,FALSE);
5881 pic16_aopOp (right,ic,FALSE);
5882 pic16_aopOp (result,ic,TRUE);
5884 genCmp(left, right, result, ifx, sign);
5886 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5887 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5888 pic16_freeAsmop(result,NULL,ic,TRUE);
5893 // FIXME reenable literal optimisation when the pic16 port is stable
5895 /*-----------------------------------------------------------------*/
5896 /* genc16bit2lit - compare a 16 bit value to a literal */
5897 /*-----------------------------------------------------------------*/
5898 static void genc16bit2lit(operand *op, int lit, int offset)
5902 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5903 if( (lit&0xff) == 0)
5908 switch( BYTEofLONG(lit,i)) {
5910 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5913 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5916 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5919 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5920 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5925 switch( BYTEofLONG(lit,i)) {
5927 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5931 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5935 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5938 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5940 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5949 /*-----------------------------------------------------------------*/
5950 /* gencjneshort - compare and jump if not equal */
5951 /*-----------------------------------------------------------------*/
5952 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5954 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5956 int res_offset = 0; /* the result may be a different size then left or right */
5957 int res_size = AOP_SIZE(result);
5959 symbol *lbl, *lbl_done;
5961 unsigned long lit = 0L;
5962 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5964 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5965 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5967 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5968 resolveIfx(&rIfx,ifx);
5969 lbl = newiTempLabel(NULL);
5970 lbl_done = newiTempLabel(NULL);
5973 /* if the left side is a literal or
5974 if the right is in a pointer register and left
5976 if ((AOP_TYPE(left) == AOP_LIT) ||
5977 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5982 if(AOP_TYPE(right) == AOP_LIT)
5983 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5985 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5986 preserve_result = 1;
5988 if(result && !preserve_result)
5991 for(i = 0; i < AOP_SIZE(result); i++)
5992 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5996 /* if the right side is a literal then anything goes */
5997 if (AOP_TYPE(right) == AOP_LIT &&
5998 AOP_TYPE(left) != AOP_DIR ) {
6001 genc16bit2lit(left, lit, 0);
6003 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6006 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6009 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6010 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6012 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6016 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6018 if(res_offset < res_size-1)
6026 /* if the right side is in a register or in direct space or
6027 if the left is a pointer register & right is not */
6028 else if (AOP_TYPE(right) == AOP_REG ||
6029 AOP_TYPE(right) == AOP_DIR ||
6030 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
6031 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
6032 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
6033 int lbl_key = lbl->key;
6036 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
6037 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6039 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6040 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
6041 __FUNCTION__,__LINE__);
6045 /* switch(size) { */
6047 /* genc16bit2lit(left, lit, 0); */
6049 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
6054 if((AOP_TYPE(left) == AOP_DIR) &&
6055 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
6057 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6058 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6060 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
6062 switch (lit & 0xff) {
6064 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6067 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6068 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6069 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6073 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6074 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6075 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6076 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6080 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6081 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6086 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6089 if(AOP_TYPE(result) == AOP_CRY) {
6090 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6095 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6097 /* fix me. probably need to check result size too */
6098 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
6103 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6104 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6111 if(res_offset < res_size-1)
6116 } else if(AOP_TYPE(right) == AOP_REG &&
6117 AOP_TYPE(left) != AOP_DIR){
6120 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6121 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6122 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6127 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6129 if(res_offset < res_size-1)
6134 /* right is a pointer reg need both a & b */
6136 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
6138 pic16_emitcode("mov","b,%s",l);
6139 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6140 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
6145 if(result && preserve_result)
6148 for(i = 0; i < AOP_SIZE(result); i++)
6149 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6152 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
6154 if(result && preserve_result)
6155 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
6158 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6160 pic16_emitpLabel(lbl->key);
6162 if(result && preserve_result)
6165 for(i = 0; i < AOP_SIZE(result); i++)
6166 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6168 pic16_emitpLabel(lbl_done->key);
6171 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6179 /*-----------------------------------------------------------------*/
6180 /* gencjne - compare and jump if not equal */
6181 /*-----------------------------------------------------------------*/
6182 static void gencjne(operand *left, operand *right, iCode *ifx)
6184 symbol *tlbl = newiTempLabel(NULL);
6186 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6187 gencjneshort(left, right, lbl);
6189 pic16_emitcode("mov","a,%s",one);
6190 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
6191 pic16_emitcode("","%05d_DS_:",lbl->key+100);
6192 pic16_emitcode("clr","a");
6193 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6195 pic16_emitpLabel(lbl->key);
6196 pic16_emitpLabel(tlbl->key);
6202 /*-----------------------------------------------------------------*/
6203 /* is_LitOp - check if operand has to be treated as literal */
6204 /*-----------------------------------------------------------------*/
6205 static bool is_LitOp(operand *op)
6207 return (AOP_TYPE(op) == AOP_LIT)
6208 || ( (AOP_TYPE(op) == AOP_PCODE)
6209 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
6210 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
6213 /*-----------------------------------------------------------------*/
6214 /* is_LitAOp - check if operand has to be treated as literal */
6215 /*-----------------------------------------------------------------*/
6216 static bool is_LitAOp(asmop *aop)
6218 return (aop->type == AOP_LIT)
6219 || ( (aop->type == AOP_PCODE)
6220 && ( (aop->aopu.pcop->type == PO_LITERAL)
6221 || (aop->aopu.pcop->type == PO_IMMEDIATE) ));
6226 /*-----------------------------------------------------------------*/
6227 /* genCmpEq - generates code for equal to */
6228 /*-----------------------------------------------------------------*/
6229 static void genCmpEq (iCode *ic, iCode *ifx)
6231 operand *left, *right, *result;
6232 symbol *falselbl = newiTempLabel(NULL);
6233 symbol *donelbl = newiTempLabel(NULL);
6235 int preserve_result = 0;
6236 int generate_result = 0;
6239 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6240 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6241 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6244 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6246 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
6248 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6249 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
6253 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
6255 operand *tmp = right ;
6260 if ( regsInCommon(left, result) || regsInCommon(right, result) )
6261 preserve_result = 1;
6263 if(result && AOP_SIZE(result))
6264 generate_result = 1;
6266 if(generate_result && !preserve_result)
6268 for(i = 0; i < AOP_SIZE(result); i++)
6269 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6272 for(i=0; i < AOP_SIZE(left); i++)
6274 if(AOP_TYPE(left) != AOP_ACC)
6277 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
6279 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
6282 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
6284 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
6286 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
6291 if(generate_result && preserve_result)
6293 for(i = 0; i < AOP_SIZE(result); i++)
6294 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6298 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
6300 if(generate_result && preserve_result)
6301 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6303 if(ifx && IC_TRUE(ifx))
6304 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6306 if(ifx && IC_FALSE(ifx))
6307 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6309 pic16_emitpLabel(falselbl->key);
6313 if(ifx && IC_FALSE(ifx))
6314 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6316 if(generate_result && preserve_result)
6318 for(i = 0; i < AOP_SIZE(result); i++)
6319 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6322 pic16_emitpLabel(donelbl->key);
6328 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6329 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6330 pic16_freeAsmop(result,NULL,ic,TRUE);
6336 // old version kept for reference
6338 /*-----------------------------------------------------------------*/
6339 /* genCmpEq - generates code for equal to */
6340 /*-----------------------------------------------------------------*/
6341 static void genCmpEq (iCode *ic, iCode *ifx)
6343 operand *left, *right, *result;
6344 unsigned long lit = 0L;
6346 symbol *falselbl = newiTempLabel(NULL);
6349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6352 DEBUGpic16_emitcode ("; ifx is non-null","");
6354 DEBUGpic16_emitcode ("; ifx is null","");
6356 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6357 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6358 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6360 size = max(AOP_SIZE(left),AOP_SIZE(right));
6362 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6364 /* if literal, literal on the right or
6365 if the right is in a pointer register and left
6367 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
6368 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
6369 operand *tmp = right ;
6375 if(ifx && !AOP_SIZE(result)){
6377 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
6378 /* if they are both bit variables */
6379 if (AOP_TYPE(left) == AOP_CRY &&
6380 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6381 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
6382 if(AOP_TYPE(right) == AOP_LIT){
6383 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6385 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6386 pic16_emitcode("cpl","c");
6387 } else if(lit == 1L) {
6388 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6390 pic16_emitcode("clr","c");
6392 /* AOP_TYPE(right) == AOP_CRY */
6394 symbol *lbl = newiTempLabel(NULL);
6395 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6396 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6397 pic16_emitcode("cpl","c");
6398 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6400 /* if true label then we jump if condition
6402 tlbl = newiTempLabel(NULL);
6403 if ( IC_TRUE(ifx) ) {
6404 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
6405 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
6407 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
6408 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
6410 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6413 /* left and right are both bit variables, result is carry */
6416 resolveIfx(&rIfx,ifx);
6418 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
6419 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
6420 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
6421 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
6426 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
6428 /* They're not both bit variables. Is the right a literal? */
6429 if(AOP_TYPE(right) == AOP_LIT) {
6430 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6435 switch(lit & 0xff) {
6437 if ( IC_TRUE(ifx) ) {
6438 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
6440 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6442 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6443 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6447 if ( IC_TRUE(ifx) ) {
6448 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
6450 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6452 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6453 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6457 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6459 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6464 /* end of size == 1 */
6468 genc16bit2lit(left,lit,offset);
6471 /* end of size == 2 */
6476 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6477 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
6478 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6479 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6482 /* search for patterns that can be optimized */
6484 genc16bit2lit(left,lit,0);
6488 emitSKPZ; // if hi word unequal
6490 emitSKPNZ; // if hi word equal
6492 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
6493 genc16bit2lit(left,lit,2);
6496 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6497 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6501 pic16_emitpLabel(falselbl->key);
6510 } else if(AOP_TYPE(right) == AOP_CRY ) {
6511 /* we know the left is not a bit, but that the right is */
6512 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6513 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
6514 pic16_popGet(AOP(right),offset));
6515 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
6517 /* if the two are equal, then W will be 0 and the Z bit is set
6518 * we could test Z now, or go ahead and check the high order bytes if
6519 * the variable we're comparing is larger than a byte. */
6522 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
6524 if ( IC_TRUE(ifx) ) {
6526 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6527 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6530 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6531 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6535 /* They're both variables that are larger than bits */
6538 tlbl = newiTempLabel(NULL);
6541 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6542 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6544 if ( IC_TRUE(ifx) ) {
6548 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
6550 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
6551 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
6555 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
6558 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6559 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6564 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
6566 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6567 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6571 if(s>1 && IC_TRUE(ifx)) {
6572 pic16_emitpLabel(tlbl->key);
6573 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6577 /* mark the icode as generated */
6582 /* if they are both bit variables */
6583 if (AOP_TYPE(left) == AOP_CRY &&
6584 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6585 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
6586 if(AOP_TYPE(right) == AOP_LIT){
6587 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6589 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6590 pic16_emitcode("cpl","c");
6591 } else if(lit == 1L) {
6592 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6594 pic16_emitcode("clr","c");
6596 /* AOP_TYPE(right) == AOP_CRY */
6598 symbol *lbl = newiTempLabel(NULL);
6599 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6600 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6601 pic16_emitcode("cpl","c");
6602 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6605 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
6606 pic16_outBitC(result);
6610 genIfxJump (ifx,"c");
6613 /* if the result is used in an arithmetic operation
6614 then put the result in place */
6615 pic16_outBitC(result);
6618 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
6619 gencjne(left,right,result,ifx);
6622 gencjne(left,right,newiTempLabel(NULL));
6624 if(IC_TRUE(ifx)->key)
6625 gencjne(left,right,IC_TRUE(ifx)->key);
6627 gencjne(left,right,IC_FALSE(ifx)->key);
6631 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
6632 pic16_aopPut(AOP(result),"a",0);
6637 genIfxJump (ifx,"a");
6641 /* if the result is used in an arithmetic operation
6642 then put the result in place */
6644 if (AOP_TYPE(result) != AOP_CRY)
6645 pic16_outAcc(result);
6647 /* leave the result in acc */
6651 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6652 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6653 pic16_freeAsmop(result,NULL,ic,TRUE);
6657 /*-----------------------------------------------------------------*/
6658 /* ifxForOp - returns the icode containing the ifx for operand */
6659 /*-----------------------------------------------------------------*/
6660 static iCode *ifxForOp ( operand *op, iCode *ic )
6662 /* if true symbol then needs to be assigned */
6663 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6664 if (IS_TRUE_SYMOP(op))
6667 /* if this has register type condition and
6668 the next instruction is ifx with the same operand
6669 and live to of the operand is upto the ifx only then */
6671 && ic->next->op == IFX
6672 && IC_COND(ic->next)->key == op->key
6673 && OP_SYMBOL(op)->liveTo <= ic->next->seq
6675 DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
6680 ic->next->op == IFX &&
6681 IC_COND(ic->next)->key == op->key) {
6682 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6686 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6688 ic->next->op == IFX)
6689 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6692 ic->next->op == IFX &&
6693 IC_COND(ic->next)->key == op->key) {
6694 DEBUGpic16_emitcode ("; "," key is okay");
6695 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6696 OP_SYMBOL(op)->liveTo,
6701 /* the code below is completely untested
6702 * it just allows ulong2fs.c compile -- VR */
6705 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6706 __FILE__, __FUNCTION__, __LINE__);
6708 /* if this has register type condition and
6709 the next instruction is ifx with the same operand
6710 and live to of the operand is upto the ifx only then */
6712 ic->next->op == IFX &&
6713 IC_COND(ic->next)->key == op->key &&
6714 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6718 ic->next->op == IFX &&
6719 IC_COND(ic->next)->key == op->key) {
6720 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6724 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6725 __FILE__, __FUNCTION__, __LINE__);
6727 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6732 /*-----------------------------------------------------------------*/
6733 /* genAndOp - for && operation */
6734 /*-----------------------------------------------------------------*/
6735 static void genAndOp (iCode *ic)
6737 operand *left,*right, *result;
6740 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
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 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6745 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6746 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6748 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6750 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6751 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6752 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6754 /* if both are bit variables */
6755 /* if (AOP_TYPE(left) == AOP_CRY && */
6756 /* AOP_TYPE(right) == AOP_CRY ) { */
6757 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6758 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6759 /* pic16_outBitC(result); */
6761 /* tlbl = newiTempLabel(NULL); */
6762 /* pic16_toBoolean(left); */
6763 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6764 /* pic16_toBoolean(right); */
6765 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6766 /* pic16_outBitAcc(result); */
6769 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6770 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6771 pic16_freeAsmop(result,NULL,ic,TRUE);
6775 /*-----------------------------------------------------------------*/
6776 /* genOrOp - for || operation */
6777 /*-----------------------------------------------------------------*/
6780 modified this code, but it doesn't appear to ever get called
6783 static void genOrOp (iCode *ic)
6785 operand *left,*right, *result;
6788 /* note here that || operations that are in an
6789 if statement are taken away by backPatchLabels
6790 only those used in arthmetic operations remain */
6791 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6792 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6793 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6794 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6796 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6798 /* if both are bit variables */
6799 if (AOP_TYPE(left) == AOP_CRY &&
6800 AOP_TYPE(right) == AOP_CRY ) {
6801 pic16_emitcode("clrc","");
6802 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6803 AOP(left)->aopu.aop_dir,
6804 AOP(left)->aopu.aop_dir);
6805 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6806 AOP(right)->aopu.aop_dir,
6807 AOP(right)->aopu.aop_dir);
6808 pic16_emitcode("setc","");
6811 tlbl = newiTempLabel(NULL);
6812 pic16_toBoolean(left);
6814 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
6815 pic16_toBoolean(right);
6816 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6818 pic16_outBitAcc(result);
6821 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6822 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6823 pic16_freeAsmop(result,NULL,ic,TRUE);
6826 /*-----------------------------------------------------------------*/
6827 /* isLiteralBit - test if lit == 2^n */
6828 /*-----------------------------------------------------------------*/
6829 static int isLiteralBit(unsigned long lit)
6831 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6832 0x100L,0x200L,0x400L,0x800L,
6833 0x1000L,0x2000L,0x4000L,0x8000L,
6834 0x10000L,0x20000L,0x40000L,0x80000L,
6835 0x100000L,0x200000L,0x400000L,0x800000L,
6836 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6837 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6840 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6841 for(idx = 0; idx < 32; idx++)
6847 /*-----------------------------------------------------------------*/
6848 /* continueIfTrue - */
6849 /*-----------------------------------------------------------------*/
6850 static void continueIfTrue (iCode *ic)
6852 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6854 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6858 /*-----------------------------------------------------------------*/
6860 /*-----------------------------------------------------------------*/
6861 static void jumpIfTrue (iCode *ic)
6863 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6865 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6869 /*-----------------------------------------------------------------*/
6870 /* jmpTrueOrFalse - */
6871 /*-----------------------------------------------------------------*/
6872 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6874 // ugly but optimized by peephole
6875 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6877 symbol *nlbl = newiTempLabel(NULL);
6878 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6879 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6880 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6881 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6884 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6885 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6890 /*-----------------------------------------------------------------*/
6891 /* genAnd - code for and */
6892 /*-----------------------------------------------------------------*/
6893 static void genAnd (iCode *ic, iCode *ifx)
6895 operand *left, *right, *result;
6897 unsigned long lit = 0L;
6902 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6903 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6904 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6905 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6907 resolveIfx(&rIfx,ifx);
6909 /* if left is a literal & right is not then exchange them */
6910 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6911 AOP_NEEDSACC(left)) {
6912 operand *tmp = right ;
6917 /* if result = right then exchange them */
6918 if(pic16_sameRegs(AOP(result),AOP(right))){
6919 operand *tmp = right ;
6924 /* if right is bit then exchange them */
6925 if (AOP_TYPE(right) == AOP_CRY &&
6926 AOP_TYPE(left) != AOP_CRY){
6927 operand *tmp = right ;
6931 if(AOP_TYPE(right) == AOP_LIT)
6932 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6934 size = AOP_SIZE(result);
6936 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6939 // result = bit & yy;
6940 if (AOP_TYPE(left) == AOP_CRY){
6941 // c = bit & literal;
6942 if(AOP_TYPE(right) == AOP_LIT){
6944 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6947 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6950 if(size && (AOP_TYPE(result) == AOP_CRY)){
6951 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6954 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6958 pic16_emitcode("clr","c");
6961 if (AOP_TYPE(right) == AOP_CRY){
6963 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6964 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6967 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6969 pic16_emitcode("rrc","a");
6970 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6976 pic16_outBitC(result);
6978 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6979 genIfxJump(ifx, "c");
6983 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6984 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6985 if((AOP_TYPE(right) == AOP_LIT) &&
6986 (AOP_TYPE(result) == AOP_CRY) &&
6987 (AOP_TYPE(left) != AOP_CRY)){
6988 int posbit = isLiteralBit(lit);
6992 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6995 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
7001 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7002 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
7004 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7005 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
7008 DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
7009 size = AOP_SIZE(left);
7012 int bp = posbit, ofs=0;
7019 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
7020 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
7024 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
7025 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7027 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
7034 symbol *tlbl = newiTempLabel(NULL);
7035 int sizel = AOP_SIZE(left);
7041 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
7043 /* patch provided by Aaron Colwell */
7044 if((posbit = isLiteralBit(bytelit)) != 0) {
7045 pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
7046 pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
7047 (posbit-1),0, PO_GPR_REGISTER));
7049 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
7050 // pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7052 if (bytelit == 0xff) {
7053 /* Aaron had a MOVF instruction here, changed to MOVFW cause
7054 * a peephole could optimize it out -- VR */
7055 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7057 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7058 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
7061 pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
7062 pic16_popGetLabel(tlbl->key));
7066 /* old code, left here for reference -- VR 09/2004 */
7067 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7069 if((posbit = isLiteralBit(bytelit)) != 0)
7070 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
7072 if(bytelit != 0x0FFL)
7073 pic16_emitcode("anl","a,%s",
7074 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
7075 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7081 // bit = left & literal
7084 pic16_emitpLabel(tlbl->key);
7086 // if(left & literal)
7089 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7090 pic16_emitpLabel(tlbl->key);
7097 pic16_outBitC(result);
7101 /* if left is same as result */
7102 if(pic16_sameRegs(AOP(result),AOP(left))){
7104 for(;size--; offset++,lit>>=8) {
7105 if(AOP_TYPE(right) == AOP_LIT){
7106 switch(lit & 0xff) {
7108 /* and'ing with 0 has clears the result */
7109 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7110 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7113 /* and'ing with 0xff is a nop when the result and left are the same */
7118 int p = my_powof2( (~lit) & 0xff );
7120 /* only one bit is set in the literal, so use a bcf instruction */
7121 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
7122 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7125 pic16_emitcode("movlw","0x%x", (lit & 0xff));
7126 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7127 if(know_W != (lit&0xff))
7128 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7130 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7135 if (AOP_TYPE(left) == AOP_ACC) {
7136 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7138 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7139 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7146 // left & result in different registers
7147 if(AOP_TYPE(result) == AOP_CRY){
7149 // if(size), result in bit
7150 // if(!size && ifx), conditional oper: if(left & right)
7151 symbol *tlbl = newiTempLabel(NULL);
7152 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
7154 pic16_emitcode("setb","c");
7156 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7157 pic16_emitcode("anl","a,%s",
7158 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7159 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7164 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7165 pic16_outBitC(result);
7167 jmpTrueOrFalse(ifx, tlbl);
7169 for(;(size--);offset++) {
7171 // result = left & right
7172 if(AOP_TYPE(right) == AOP_LIT){
7173 int t = (lit >> (offset*8)) & 0x0FFL;
7176 pic16_emitcode("clrf","%s",
7177 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7178 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7181 pic16_emitcode("movf","%s,w",
7182 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7183 pic16_emitcode("movwf","%s",
7184 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7185 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7186 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7189 pic16_emitcode("movlw","0x%x",t);
7190 pic16_emitcode("andwf","%s,w",
7191 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7192 pic16_emitcode("movwf","%s",
7193 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7195 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7196 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7197 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7202 if (AOP_TYPE(left) == AOP_ACC) {
7203 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7204 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7206 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7207 pic16_emitcode("andwf","%s,w",
7208 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7209 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7210 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7212 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7213 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7219 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7220 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7221 pic16_freeAsmop(result,NULL,ic,TRUE);
7224 /*-----------------------------------------------------------------*/
7225 /* genOr - code for or */
7226 /*-----------------------------------------------------------------*/
7227 static void genOr (iCode *ic, iCode *ifx)
7229 operand *left, *right, *result;
7231 unsigned long lit = 0L;
7233 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7235 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7236 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7237 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7239 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7241 /* if left is a literal & right is not then exchange them */
7242 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7243 AOP_NEEDSACC(left)) {
7244 operand *tmp = right ;
7249 /* if result = right then exchange them */
7250 if(pic16_sameRegs(AOP(result),AOP(right))){
7251 operand *tmp = right ;
7256 /* if right is bit then exchange them */
7257 if (AOP_TYPE(right) == AOP_CRY &&
7258 AOP_TYPE(left) != AOP_CRY){
7259 operand *tmp = right ;
7264 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7266 if(AOP_TYPE(right) == AOP_LIT)
7267 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7269 size = AOP_SIZE(result);
7273 if (AOP_TYPE(left) == AOP_CRY){
7274 if(AOP_TYPE(right) == AOP_LIT){
7275 // c = bit & literal;
7277 // lit != 0 => result = 1
7278 if(AOP_TYPE(result) == AOP_CRY){
7280 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7281 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7282 // AOP(result)->aopu.aop_dir,
7283 // AOP(result)->aopu.aop_dir);
7285 continueIfTrue(ifx);
7289 // lit == 0 => result = left
7290 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7292 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
7295 if (AOP_TYPE(right) == AOP_CRY){
7296 if(pic16_sameRegs(AOP(result),AOP(left))){
7298 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7299 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
7300 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7302 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7303 AOP(result)->aopu.aop_dir,
7304 AOP(result)->aopu.aop_dir);
7305 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7306 AOP(right)->aopu.aop_dir,
7307 AOP(right)->aopu.aop_dir);
7308 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7309 AOP(result)->aopu.aop_dir,
7310 AOP(result)->aopu.aop_dir);
7312 if( AOP_TYPE(result) == AOP_ACC) {
7313 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7314 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7315 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7316 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
7320 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7321 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7322 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7323 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7325 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7326 AOP(result)->aopu.aop_dir,
7327 AOP(result)->aopu.aop_dir);
7328 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
7329 AOP(right)->aopu.aop_dir,
7330 AOP(right)->aopu.aop_dir);
7331 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7332 AOP(left)->aopu.aop_dir,
7333 AOP(left)->aopu.aop_dir);
7334 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7335 AOP(result)->aopu.aop_dir,
7336 AOP(result)->aopu.aop_dir);
7341 symbol *tlbl = newiTempLabel(NULL);
7342 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7345 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7346 if( AOP_TYPE(right) == AOP_ACC) {
7347 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
7349 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7350 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7355 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
7356 pic16_emitcode(";XXX setb","c");
7357 pic16_emitcode(";XXX jb","%s,%05d_DS_",
7358 AOP(left)->aopu.aop_dir,tlbl->key+100);
7359 pic16_toBoolean(right);
7360 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7361 if((AOP_TYPE(result) == AOP_CRY) && ifx){
7362 jmpTrueOrFalse(ifx, tlbl);
7366 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7373 pic16_outBitC(result);
7375 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7376 genIfxJump(ifx, "c");
7380 // if(val | 0xZZ) - size = 0, ifx != FALSE -
7381 // bit = val | 0xZZ - size = 1, ifx = FALSE -
7382 if((AOP_TYPE(right) == AOP_LIT) &&
7383 (AOP_TYPE(result) == AOP_CRY) &&
7384 (AOP_TYPE(left) != AOP_CRY)){
7386 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7389 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
7391 continueIfTrue(ifx);
7394 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7395 // lit = 0, result = boolean(left)
7397 pic16_emitcode(";XXX setb","c");
7398 pic16_toBoolean(right);
7400 symbol *tlbl = newiTempLabel(NULL);
7401 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7403 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7405 genIfxJump (ifx,"a");
7409 pic16_outBitC(result);
7413 /* if left is same as result */
7414 if(pic16_sameRegs(AOP(result),AOP(left))){
7416 for(;size--; offset++,lit>>=8) {
7417 if(AOP_TYPE(right) == AOP_LIT){
7418 if((lit & 0xff) == 0)
7419 /* or'ing with 0 has no effect */
7422 int p = my_powof2(lit & 0xff);
7424 /* only one bit is set in the literal, so use a bsf instruction */
7425 pic16_emitpcode(POC_BSF,
7426 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7428 if(know_W != (lit & 0xff))
7429 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7430 know_W = lit & 0xff;
7431 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7436 if (AOP_TYPE(left) == AOP_ACC) {
7437 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
7438 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7440 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7441 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7443 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7444 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7450 // left & result in different registers
7451 if(AOP_TYPE(result) == AOP_CRY){
7453 // if(size), result in bit
7454 // if(!size && ifx), conditional oper: if(left | right)
7455 symbol *tlbl = newiTempLabel(NULL);
7456 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7457 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7461 pic16_emitcode(";XXX setb","c");
7463 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7464 pic16_emitcode(";XXX orl","a,%s",
7465 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7466 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7471 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7472 pic16_outBitC(result);
7474 jmpTrueOrFalse(ifx, tlbl);
7475 } else for(;(size--);offset++){
7477 // result = left & right
7478 if(AOP_TYPE(right) == AOP_LIT){
7479 int t = (lit >> (offset*8)) & 0x0FFL;
7482 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7483 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7485 pic16_emitcode("movf","%s,w",
7486 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7487 pic16_emitcode("movwf","%s",
7488 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7491 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7492 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7493 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7495 pic16_emitcode("movlw","0x%x",t);
7496 pic16_emitcode("iorwf","%s,w",
7497 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7498 pic16_emitcode("movwf","%s",
7499 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7505 // faster than result <- left, anl result,right
7506 // and better if result is SFR
7507 if (AOP_TYPE(left) == AOP_ACC) {
7508 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
7509 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7511 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7512 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7514 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7515 pic16_emitcode("iorwf","%s,w",
7516 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7518 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7519 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7524 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7525 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7526 pic16_freeAsmop(result,NULL,ic,TRUE);
7529 /*-----------------------------------------------------------------*/
7530 /* genXor - code for xclusive or */
7531 /*-----------------------------------------------------------------*/
7532 static void genXor (iCode *ic, iCode *ifx)
7534 operand *left, *right, *result;
7536 unsigned long lit = 0L;
7538 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7540 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7541 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7542 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7544 /* if left is a literal & right is not ||
7545 if left needs acc & right does not */
7546 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7547 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
7548 operand *tmp = right ;
7553 /* if result = right then exchange them */
7554 if(pic16_sameRegs(AOP(result),AOP(right))){
7555 operand *tmp = right ;
7560 /* if right is bit then exchange them */
7561 if (AOP_TYPE(right) == AOP_CRY &&
7562 AOP_TYPE(left) != AOP_CRY){
7563 operand *tmp = right ;
7567 if(AOP_TYPE(right) == AOP_LIT)
7568 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7570 size = AOP_SIZE(result);
7574 if (AOP_TYPE(left) == AOP_CRY){
7575 if(AOP_TYPE(right) == AOP_LIT){
7576 // c = bit & literal;
7578 // lit>>1 != 0 => result = 1
7579 if(AOP_TYPE(result) == AOP_CRY){
7581 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
7582 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
7584 continueIfTrue(ifx);
7587 pic16_emitcode("setb","c");
7591 // lit == 0, result = left
7592 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7594 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7596 // lit == 1, result = not(left)
7597 if(size && pic16_sameRegs(AOP(result),AOP(left))){
7598 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
7599 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
7600 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
7603 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7604 pic16_emitcode("cpl","c");
7611 symbol *tlbl = newiTempLabel(NULL);
7612 if (AOP_TYPE(right) == AOP_CRY){
7614 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
7617 int sizer = AOP_SIZE(right);
7619 // if val>>1 != 0, result = 1
7620 pic16_emitcode("setb","c");
7622 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
7624 // test the msb of the lsb
7625 pic16_emitcode("anl","a,#0xfe");
7626 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7630 pic16_emitcode("rrc","a");
7632 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
7633 pic16_emitcode("cpl","c");
7634 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
7639 pic16_outBitC(result);
7641 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7642 genIfxJump(ifx, "c");
7646 if(pic16_sameRegs(AOP(result),AOP(left))){
7647 /* if left is same as result */
7648 for(;size--; offset++) {
7649 if(AOP_TYPE(right) == AOP_LIT){
7650 int t = (lit >> (offset*8)) & 0x0FFL;
7654 if (IS_AOP_PREG(left)) {
7655 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7656 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7657 pic16_aopPut(AOP(result),"a",offset);
7659 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7660 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7661 pic16_emitcode("xrl","%s,%s",
7662 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
7663 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7666 if (AOP_TYPE(left) == AOP_ACC)
7667 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7669 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7670 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7672 if (IS_AOP_PREG(left)) {
7673 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7674 pic16_aopPut(AOP(result),"a",offset);
7676 pic16_emitcode("xrl","%s,a",
7677 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7683 // left & result in different registers
7684 if(AOP_TYPE(result) == AOP_CRY){
7686 // if(size), result in bit
7687 // if(!size && ifx), conditional oper: if(left ^ right)
7688 symbol *tlbl = newiTempLabel(NULL);
7689 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7691 pic16_emitcode("setb","c");
7693 if((AOP_TYPE(right) == AOP_LIT) &&
7694 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
7695 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7697 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7698 pic16_emitcode("xrl","a,%s",
7699 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7701 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7706 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7707 pic16_outBitC(result);
7709 jmpTrueOrFalse(ifx, tlbl);
7710 } else for(;(size--);offset++){
7712 // result = left & right
7713 if(AOP_TYPE(right) == AOP_LIT){
7714 int t = (lit >> (offset*8)) & 0x0FFL;
7717 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7718 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7719 pic16_emitcode("movf","%s,w",
7720 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7721 pic16_emitcode("movwf","%s",
7722 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7725 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7726 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7727 pic16_emitcode("comf","%s,w",
7728 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7729 pic16_emitcode("movwf","%s",
7730 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7733 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7734 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7735 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7736 pic16_emitcode("movlw","0x%x",t);
7737 pic16_emitcode("xorwf","%s,w",
7738 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7739 pic16_emitcode("movwf","%s",
7740 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7746 // faster than result <- left, anl result,right
7747 // and better if result is SFR
7748 if (AOP_TYPE(left) == AOP_ACC) {
7749 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7750 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7752 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7753 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7754 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7755 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7757 if ( AOP_TYPE(result) != AOP_ACC){
7758 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7759 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7765 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7766 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7767 pic16_freeAsmop(result,NULL,ic,TRUE);
7770 /*-----------------------------------------------------------------*/
7771 /* genInline - write the inline code out */
7772 /*-----------------------------------------------------------------*/
7773 static void genInline (iCode *ic)
7775 char *buffer, *bp, *bp1;
7777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7779 _G.inLine += (!options.asmpeep);
7781 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7782 strcpy(buffer,IC_INLINE(ic));
7784 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7786 /* emit each line as a code */
7792 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7800 /* print label, use this special format with NULL directive
7801 * to denote that the argument should not be indented with tab */
7802 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7809 if ((bp1 != bp) && *bp1)
7810 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7815 _G.inLine -= (!options.asmpeep);
7818 /*-----------------------------------------------------------------*/
7819 /* genRRC - rotate right with carry */
7820 /*-----------------------------------------------------------------*/
7821 static void genRRC (iCode *ic)
7823 operand *left , *result ;
7824 int size, offset = 0, same;
7826 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7828 /* rotate right with carry */
7830 result=IC_RESULT(ic);
7831 pic16_aopOp (left,ic,FALSE);
7832 pic16_aopOp (result,ic,FALSE);
7834 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7836 same = pic16_sameRegs(AOP(result),AOP(left));
7838 size = AOP_SIZE(result);
7840 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7842 /* get the lsb and put it into the carry */
7843 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7850 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7852 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7859 pic16_freeAsmop(left,NULL,ic,TRUE);
7860 pic16_freeAsmop(result,NULL,ic,TRUE);
7863 /*-----------------------------------------------------------------*/
7864 /* genRLC - generate code for rotate left with carry */
7865 /*-----------------------------------------------------------------*/
7866 static void genRLC (iCode *ic)
7868 operand *left , *result ;
7869 int size, offset = 0;
7872 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7873 /* rotate right with carry */
7875 result=IC_RESULT(ic);
7876 pic16_aopOp (left,ic,FALSE);
7877 pic16_aopOp (result,ic,FALSE);
7879 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7881 same = pic16_sameRegs(AOP(result),AOP(left));
7883 /* move it to the result */
7884 size = AOP_SIZE(result);
7886 /* get the msb and put it into the carry */
7887 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7894 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7896 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7897 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7904 pic16_freeAsmop(left,NULL,ic,TRUE);
7905 pic16_freeAsmop(result,NULL,ic,TRUE);
7909 /* gpasm can get the highest order bit with HIGH/UPPER
7910 * so the following probably is not needed -- VR */
7912 /*-----------------------------------------------------------------*/
7913 /* genGetHbit - generates code get highest order bit */
7914 /*-----------------------------------------------------------------*/
7915 static void genGetHbit (iCode *ic)
7917 operand *left, *result;
7919 result=IC_RESULT(ic);
7920 pic16_aopOp (left,ic,FALSE);
7921 pic16_aopOp (result,ic,FALSE);
7923 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7924 /* get the highest order byte into a */
7925 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7926 if(AOP_TYPE(result) == AOP_CRY){
7927 pic16_emitcode("rlc","a");
7928 pic16_outBitC(result);
7931 pic16_emitcode("rl","a");
7932 pic16_emitcode("anl","a,#0x01");
7933 pic16_outAcc(result);
7937 pic16_freeAsmop(left,NULL,ic,TRUE);
7938 pic16_freeAsmop(result,NULL,ic,TRUE);
7942 /*-----------------------------------------------------------------*/
7943 /* AccRol - rotate left accumulator by known count */
7944 /*-----------------------------------------------------------------*/
7945 static void AccRol (int shCount)
7947 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7948 shCount &= 0x0007; // shCount : 0..7
7953 pic16_emitcode("rl","a");
7956 pic16_emitcode("rl","a");
7957 pic16_emitcode("rl","a");
7960 pic16_emitcode("swap","a");
7961 pic16_emitcode("rr","a");
7964 pic16_emitcode("swap","a");
7967 pic16_emitcode("swap","a");
7968 pic16_emitcode("rl","a");
7971 pic16_emitcode("rr","a");
7972 pic16_emitcode("rr","a");
7975 pic16_emitcode("rr","a");
7981 /*-----------------------------------------------------------------*/
7982 /* AccLsh - left shift accumulator by known count */
7983 /*-----------------------------------------------------------------*/
7984 static void AccLsh (int shCount)
7986 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7992 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7995 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7996 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7999 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8000 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8003 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8006 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8007 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8010 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8011 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8014 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8018 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
8021 /*-----------------------------------------------------------------*/
8022 /* AccRsh - right shift accumulator by known count */
8023 /*-----------------------------------------------------------------*/
8024 static void AccRsh (int shCount, int andmask)
8026 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8031 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8034 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8035 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8038 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8039 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8042 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8045 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8046 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8049 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8050 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8053 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8058 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
8060 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
8064 /*-----------------------------------------------------------------*/
8065 /* AccSRsh - signed right shift accumulator by known count */
8066 /*-----------------------------------------------------------------*/
8067 static void AccSRsh (int shCount)
8070 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8073 pic16_emitcode("mov","c,acc.7");
8074 pic16_emitcode("rrc","a");
8075 } else if(shCount == 2){
8076 pic16_emitcode("mov","c,acc.7");
8077 pic16_emitcode("rrc","a");
8078 pic16_emitcode("mov","c,acc.7");
8079 pic16_emitcode("rrc","a");
8081 tlbl = newiTempLabel(NULL);
8082 /* rotate right accumulator */
8083 AccRol(8 - shCount);
8084 /* and kill the higher order bits */
8085 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
8086 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
8087 pic16_emitcode("orl","a,#0x%02x",
8088 (unsigned char)~SRMask[shCount]);
8089 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8095 /*-----------------------------------------------------------------*/
8096 /* shiftR1Left2Result - shift right one byte from left to result */
8097 /*-----------------------------------------------------------------*/
8098 static void shiftR1Left2ResultSigned (operand *left, int offl,
8099 operand *result, int offr,
8104 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8106 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8110 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8112 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8114 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8115 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8121 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8123 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8125 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8126 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8128 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8129 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8135 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8137 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8138 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8141 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8142 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8143 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8145 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8146 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
8148 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8152 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8153 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8154 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8155 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
8156 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8160 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8162 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8163 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8165 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8166 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
8167 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8168 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
8169 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8174 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8175 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8176 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
8177 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8178 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
8179 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8181 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8182 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8183 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8184 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8185 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8191 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8192 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8193 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8194 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8196 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8197 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8198 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8206 /*-----------------------------------------------------------------*/
8207 /* shiftR1Left2Result - shift right one byte from left to result */
8208 /*-----------------------------------------------------------------*/
8209 static void shiftR1Left2Result (operand *left, int offl,
8210 operand *result, int offr,
8211 int shCount, int sign)
8215 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8217 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8219 /* Copy the msb into the carry if signed. */
8221 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
8231 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8233 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8234 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8240 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8242 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8243 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8246 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8251 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8253 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8254 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8257 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8258 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8259 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8260 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8264 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8265 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8266 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8270 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8271 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0e));
8272 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8274 pic16_emitpcode(POC_RRNCF, pic16_popGet(AOP(result),offr));
8279 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left),offl));
8280 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x81));
8281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8282 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8283 pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(result),offr));
8288 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8289 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8290 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8299 /*-----------------------------------------------------------------*/
8300 /* shiftL1Left2Result - shift left one byte from left to result */
8301 /*-----------------------------------------------------------------*/
8302 static void shiftL1Left2Result (operand *left, int offl,
8303 operand *result, int offr, int shCount)
8308 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8310 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
8311 DEBUGpic16_emitcode ("; ***","same = %d",same);
8312 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8314 /* shift left accumulator */
8315 //AccLsh(shCount); // don't comment out just yet...
8316 // pic16_aopPut(AOP(result),"a",offr);
8320 /* Shift left 1 bit position */
8321 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8323 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
8325 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
8326 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8330 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8331 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
8332 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8333 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8336 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8337 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
8338 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8339 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8340 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8343 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8344 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8345 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8348 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8349 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8350 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8351 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8354 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8355 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
8356 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8357 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8358 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8361 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8362 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8363 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8367 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
8372 /*-----------------------------------------------------------------*/
8373 /* movLeft2Result - move byte from left to result */
8374 /*-----------------------------------------------------------------*/
8375 static void movLeft2Result (operand *left, int offl,
8376 operand *result, int offr)
8379 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8380 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
8381 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8383 if (*l == '@' && (IS_AOP_PREG(result))) {
8384 pic16_emitcode("mov","a,%s",l);
8385 pic16_aopPut(AOP(result),"a",offr);
8387 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8388 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8393 /*-----------------------------------------------------------------*/
8394 /* shiftL2Left2Result - shift left two bytes from left to result */
8395 /*-----------------------------------------------------------------*/
8396 static void shiftL2Left2Result (operand *left, int offl,
8397 operand *result, int offr, int shCount)
8399 int same = pic16_sameRegs(AOP(result), AOP(left));
8402 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
8404 if (same && (offl != offr)) { // shift bytes
8407 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8408 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8410 } else { // just treat as different later on
8423 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
8424 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8425 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8429 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8430 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8436 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
8437 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
8438 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8439 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8440 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
8441 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8442 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8444 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8445 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8449 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8450 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8451 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8452 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8453 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8454 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8455 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8456 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8457 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8458 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8461 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8462 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8463 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8464 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8465 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8475 /* note, use a mov/add for the shift since the mov has a
8476 chance of getting optimized out */
8477 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8478 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8479 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8480 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8481 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8485 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8486 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8492 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8493 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
8494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8495 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8496 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8497 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0F));
8498 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8499 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8503 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8504 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8508 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8509 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8510 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
8511 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8513 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8514 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8515 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8516 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8517 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8518 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8519 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8520 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8523 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8524 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8525 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8526 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8527 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8532 /*-----------------------------------------------------------------*/
8533 /* shiftR2Left2Result - shift right two bytes from left to result */
8534 /*-----------------------------------------------------------------*/
8535 static void shiftR2Left2Result (operand *left, int offl,
8536 operand *result, int offr,
8537 int shCount, int sign)
8539 int same = pic16_sameRegs(AOP(result), AOP(left));
8541 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
8543 if (same && (offl != offr)) { // shift right bytes
8546 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8547 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8549 } else { // just treat as different later on
8561 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8566 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8567 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8569 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8570 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8571 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8572 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8577 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8580 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8581 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8588 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
8589 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
8590 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8592 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8593 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
8594 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8595 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8597 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8598 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8599 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8601 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8602 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8603 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8604 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8605 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8609 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8610 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8614 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
8615 pic16_emitpcode(POC_BTFSC,
8616 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
8617 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8625 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8626 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8628 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8629 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8630 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8631 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8633 pic16_emitpcode(POC_BTFSC,
8634 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8635 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8637 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8638 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
8639 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8640 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8642 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8643 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8644 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8645 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8646 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8647 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8648 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
8649 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8651 pic16_emitpcode(POC_BTFSC,
8652 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8653 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8655 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8656 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8663 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8664 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8665 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8666 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
8669 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
8671 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8676 /*-----------------------------------------------------------------*/
8677 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
8678 /*-----------------------------------------------------------------*/
8679 static void shiftLLeftOrResult (operand *left, int offl,
8680 operand *result, int offr, int shCount)
8682 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8684 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8685 /* shift left accumulator */
8687 /* or with result */
8688 /* back to result */
8689 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8692 /*-----------------------------------------------------------------*/
8693 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
8694 /*-----------------------------------------------------------------*/
8695 static void shiftRLeftOrResult (operand *left, int offl,
8696 operand *result, int offr, int shCount)
8698 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8700 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8701 /* shift right accumulator */
8703 /* or with result */
8704 /* back to result */
8705 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8708 /*-----------------------------------------------------------------*/
8709 /* genlshOne - left shift a one byte quantity by known count */
8710 /*-----------------------------------------------------------------*/
8711 static void genlshOne (operand *result, operand *left, int shCount)
8713 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8714 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8717 /*-----------------------------------------------------------------*/
8718 /* genlshTwo - left shift two bytes by known amount != 0 */
8719 /*-----------------------------------------------------------------*/
8720 static void genlshTwo (operand *result,operand *left, int shCount)
8724 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8725 size = pic16_getDataSize(result);
8727 /* if shCount >= 8 */
8733 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8735 movLeft2Result(left, LSB, result, MSB16);
8737 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8740 /* 1 <= shCount <= 7 */
8743 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8745 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8749 /*-----------------------------------------------------------------*/
8750 /* shiftLLong - shift left one long from left to result */
8751 /* offr = LSB or MSB16 */
8752 /*-----------------------------------------------------------------*/
8753 static void shiftLLong (operand *left, operand *result, int offr )
8755 int size = AOP_SIZE(result);
8756 int same = pic16_sameRegs(AOP(left),AOP(result));
8759 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8761 if (same && (offr == MSB16)) { //shift one byte
8762 for(i=size-1;i>=MSB16;i--) {
8763 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8764 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8767 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8770 if (size > LSB+offr ){
8772 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8774 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8775 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8779 if(size > MSB16+offr){
8781 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8783 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8784 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8788 if(size > MSB24+offr){
8790 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8792 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8793 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8797 if(size > MSB32+offr){
8799 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8801 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8802 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8806 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8810 /*-----------------------------------------------------------------*/
8811 /* genlshFour - shift four byte by a known amount != 0 */
8812 /*-----------------------------------------------------------------*/
8813 static void genlshFour (operand *result, operand *left, int shCount)
8817 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8818 size = AOP_SIZE(result);
8820 /* if shifting more that 3 bytes */
8821 if (shCount >= 24 ) {
8824 /* lowest order of left goes to the highest
8825 order of the destination */
8826 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8828 movLeft2Result(left, LSB, result, MSB32);
8830 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8831 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8832 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8837 /* more than two bytes */
8838 else if ( shCount >= 16 ) {
8839 /* lower order two bytes goes to higher order two bytes */
8841 /* if some more remaining */
8843 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8845 movLeft2Result(left, MSB16, result, MSB32);
8846 movLeft2Result(left, LSB, result, MSB24);
8848 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8849 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8853 /* if more than 1 byte */
8854 else if ( shCount >= 8 ) {
8855 /* lower order three bytes goes to higher order three bytes */
8859 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8861 movLeft2Result(left, LSB, result, MSB16);
8863 else{ /* size = 4 */
8865 movLeft2Result(left, MSB24, result, MSB32);
8866 movLeft2Result(left, MSB16, result, MSB24);
8867 movLeft2Result(left, LSB, result, MSB16);
8868 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8870 else if(shCount == 1)
8871 shiftLLong(left, result, MSB16);
8873 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8874 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8875 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8876 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8881 /* 1 <= shCount <= 7 */
8882 else if(shCount <= 3)
8884 shiftLLong(left, result, LSB);
8885 while(--shCount >= 1)
8886 shiftLLong(result, result, LSB);
8888 /* 3 <= shCount <= 7, optimize */
8890 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8891 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8892 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8896 /*-----------------------------------------------------------------*/
8897 /* genLeftShiftLiteral - left shifting by known count */
8898 /*-----------------------------------------------------------------*/
8899 static void genLeftShiftLiteral (operand *left,
8904 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8907 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8908 pic16_freeAsmop(right,NULL,ic,TRUE);
8910 pic16_aopOp(left,ic,FALSE);
8911 pic16_aopOp(result,ic,FALSE);
8913 size = getSize(operandType(result));
8916 pic16_emitcode("; shift left ","result %d, left %d",size,
8920 /* I suppose that the left size >= result size */
8923 movLeft2Result(left, size, result, size);
8927 else if(shCount >= (size * 8))
8929 pic16_aopPut(AOP(result),zero,size);
8933 genlshOne (result,left,shCount);
8938 genlshTwo (result,left,shCount);
8942 genlshFour (result,left,shCount);
8946 pic16_freeAsmop(left,NULL,ic,TRUE);
8947 pic16_freeAsmop(result,NULL,ic,TRUE);
8950 /*-----------------------------------------------------------------*
8951 * genMultiAsm - repeat assembly instruction for size of register.
8952 * if endian == 1, then the high byte (i.e base address + size of
8953 * register) is used first else the low byte is used first;
8954 *-----------------------------------------------------------------*/
8955 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8973 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8978 /*-----------------------------------------------------------------*/
8979 /* genLeftShift - generates code for left shifting */
8980 /*-----------------------------------------------------------------*/
8981 static void genLeftShift (iCode *ic)
8983 operand *left,*right, *result;
8986 symbol *tlbl , *tlbl1;
8989 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8991 right = IC_RIGHT(ic);
8993 result = IC_RESULT(ic);
8995 pic16_aopOp(right,ic,FALSE);
8997 /* if the shift count is known then do it
8998 as efficiently as possible */
8999 if (AOP_TYPE(right) == AOP_LIT) {
9000 genLeftShiftLiteral (left,right,result,ic);
9004 /* shift count is unknown then we have to form
9005 * a loop. Get the loop count in WREG : Note: we take
9006 * only the lower order byte since shifting
9007 * more than 32 bits make no sense anyway, ( the
9008 * largest size of an object can be only 32 bits ) */
9010 pic16_aopOp(left,ic,FALSE);
9011 pic16_aopOp(result,ic,FALSE);
9013 /* now move the left to the result if they are not the
9014 * same, and if size > 1,
9015 * and if right is not same to result (!!!) -- VR */
9016 if (!pic16_sameRegs(AOP(left),AOP(result))
9017 && (AOP_SIZE(result) > 1)) {
9019 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9021 size = AOP_SIZE(result);
9026 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9027 if (*l == '@' && (IS_AOP_PREG(result))) {
9029 pic16_emitcode("mov","a,%s",l);
9030 pic16_aopPut(AOP(result),"a",offset);
9034 /* we don't know if left is a literal or a register, take care -- VR */
9035 mov2f(AOP(result), AOP(left), offset);
9041 size = AOP_SIZE(result);
9043 /* if it is only one byte then */
9045 if(optimized_for_speed) {
9046 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9047 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9048 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9049 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9050 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9051 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9052 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9053 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9054 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9055 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9056 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9057 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9060 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9062 tlbl = newiTempLabel(NULL);
9065 /* this is already done, why change it? */
9066 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9067 mov2f(AOP(result), AOP(left), 0);
9071 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9072 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9073 pic16_emitpLabel(tlbl->key);
9074 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9075 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9077 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9082 if (pic16_sameRegs(AOP(left),AOP(result))) {
9084 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9086 tlbl = newiTempLabel(NULL);
9087 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9088 genMultiAsm(POC_RRCF, result, size,1);
9089 pic16_emitpLabel(tlbl->key);
9090 genMultiAsm(POC_RLCF, result, size,0);
9091 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9093 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9097 //tlbl = newiTempLabel(NULL);
9099 //tlbl1 = newiTempLabel(NULL);
9101 //reAdjustPreg(AOP(result));
9103 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9104 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9105 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9107 //pic16_emitcode("add","a,acc");
9108 //pic16_aopPut(AOP(result),"a",offset++);
9110 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9112 // pic16_emitcode("rlc","a");
9113 // pic16_aopPut(AOP(result),"a",offset++);
9115 //reAdjustPreg(AOP(result));
9117 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9118 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9121 tlbl = newiTempLabel(NULL);
9122 tlbl1= newiTempLabel(NULL);
9124 size = AOP_SIZE(result);
9127 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9129 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9131 /* offset should be 0, 1 or 3 */
9133 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9135 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9137 pic16_emitpcode(POC_MOVWF, pctemp);
9140 pic16_emitpLabel(tlbl->key);
9143 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9145 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9147 pic16_emitpcode(POC_DECFSZ, pctemp);
9148 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9149 pic16_emitpLabel(tlbl1->key);
9151 pic16_popReleaseTempReg(pctemp,1);
9155 pic16_freeAsmop (right,NULL,ic,TRUE);
9156 pic16_freeAsmop(left,NULL,ic,TRUE);
9157 pic16_freeAsmop(result,NULL,ic,TRUE);
9163 #error old code (left here for reference)
9164 /*-----------------------------------------------------------------*/
9165 /* genLeftShift - generates code for left shifting */
9166 /*-----------------------------------------------------------------*/
9167 static void genLeftShift (iCode *ic)
9169 operand *left,*right, *result;
9172 symbol *tlbl , *tlbl1;
9175 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9177 right = IC_RIGHT(ic);
9179 result = IC_RESULT(ic);
9181 pic16_aopOp(right,ic,FALSE);
9183 /* if the shift count is known then do it
9184 as efficiently as possible */
9185 if (AOP_TYPE(right) == AOP_LIT) {
9186 genLeftShiftLiteral (left,right,result,ic);
9190 /* shift count is unknown then we have to form
9191 a loop get the loop count in B : Note: we take
9192 only the lower order byte since shifting
9193 more that 32 bits make no sense anyway, ( the
9194 largest size of an object can be only 32 bits ) */
9197 pic16_aopOp(left,ic,FALSE);
9198 pic16_aopOp(result,ic,FALSE);
9200 /* now move the left to the result if they are not the
9202 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9203 AOP_SIZE(result) > 1) {
9205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9207 size = AOP_SIZE(result);
9210 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9211 if (*l == '@' && (IS_AOP_PREG(result))) {
9213 pic16_emitcode("mov","a,%s",l);
9214 pic16_aopPut(AOP(result),"a",offset);
9217 /* we don't know if left is a literal or a register, take care -- VR */
9218 mov2f(AOP(result), AOP(left), offset);
9224 size = AOP_SIZE(result);
9226 /* if it is only one byte then */
9228 if(optimized_for_speed) {
9229 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9230 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9231 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9232 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9233 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9234 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9235 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9236 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9237 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9238 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9239 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9240 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9245 tlbl = newiTempLabel(NULL);
9246 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9247 mov2f(AOP(result), AOP(left), 0);
9249 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9250 // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9253 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9254 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9255 pic16_emitpLabel(tlbl->key);
9256 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9257 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9259 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9264 if (pic16_sameRegs(AOP(left),AOP(result))) {
9266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9268 tlbl = newiTempLabel(NULL);
9269 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9270 genMultiAsm(POC_RRCF, result, size,1);
9271 pic16_emitpLabel(tlbl->key);
9272 genMultiAsm(POC_RLCF, result, size,0);
9273 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9275 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9279 //tlbl = newiTempLabel(NULL);
9281 //tlbl1 = newiTempLabel(NULL);
9283 //reAdjustPreg(AOP(result));
9285 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9286 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9287 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9289 //pic16_emitcode("add","a,acc");
9290 //pic16_aopPut(AOP(result),"a",offset++);
9292 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9294 // pic16_emitcode("rlc","a");
9295 // pic16_aopPut(AOP(result),"a",offset++);
9297 //reAdjustPreg(AOP(result));
9299 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9300 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9303 tlbl = newiTempLabel(NULL);
9304 tlbl1= newiTempLabel(NULL);
9306 size = AOP_SIZE(result);
9309 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9311 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9313 /* offset should be 0, 1 or 3 */
9315 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9317 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9319 pic16_emitpcode(POC_MOVWF, pctemp);
9322 pic16_emitpLabel(tlbl->key);
9325 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9327 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9329 pic16_emitpcode(POC_DECFSZ, pctemp);
9330 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9331 pic16_emitpLabel(tlbl1->key);
9333 pic16_popReleaseTempReg(pctemp,1);
9337 pic16_freeAsmop (right,NULL,ic,TRUE);
9338 pic16_freeAsmop(left,NULL,ic,TRUE);
9339 pic16_freeAsmop(result,NULL,ic,TRUE);
9343 /*-----------------------------------------------------------------*/
9344 /* genrshOne - right shift a one byte quantity by known count */
9345 /*-----------------------------------------------------------------*/
9346 static void genrshOne (operand *result, operand *left,
9347 int shCount, int sign)
9349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9350 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
9353 /*-----------------------------------------------------------------*/
9354 /* genrshTwo - right shift two bytes by known amount != 0 */
9355 /*-----------------------------------------------------------------*/
9356 static void genrshTwo (operand *result,operand *left,
9357 int shCount, int sign)
9359 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
9360 /* if shCount >= 8 */
9364 shiftR1Left2Result(left, MSB16, result, LSB,
9367 movLeft2Result(left, MSB16, result, LSB);
9369 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
9372 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9373 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
9377 /* 1 <= shCount <= 7 */
9379 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
9382 /*-----------------------------------------------------------------*/
9383 /* shiftRLong - shift right one long from left to result */
9384 /* offl = LSB or MSB16 */
9385 /*-----------------------------------------------------------------*/
9386 static void shiftRLong (operand *left, int offl,
9387 operand *result, int sign)
9389 int size = AOP_SIZE(result);
9390 int same = pic16_sameRegs(AOP(left),AOP(result));
9392 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
9394 if (same && (offl == MSB16)) { //shift one byte right
9395 for(i=MSB16;i<size;i++) {
9396 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
9397 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
9402 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
9408 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
9410 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
9411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
9415 /* add sign of "a" */
9416 pic16_addSign(result, MSB32, sign);
9420 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
9422 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
9423 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
9427 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
9429 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
9430 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
9434 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
9437 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
9438 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
9443 /*-----------------------------------------------------------------*/
9444 /* genrshFour - shift four byte by a known amount != 0 */
9445 /*-----------------------------------------------------------------*/
9446 static void genrshFour (operand *result, operand *left,
9447 int shCount, int sign)
9449 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9450 /* if shifting more that 3 bytes */
9451 if(shCount >= 24 ) {
9454 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
9456 movLeft2Result(left, MSB32, result, LSB);
9458 pic16_addSign(result, MSB16, sign);
9460 else if(shCount >= 16){
9463 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
9465 movLeft2Result(left, MSB24, result, LSB);
9466 movLeft2Result(left, MSB32, result, MSB16);
9468 pic16_addSign(result, MSB24, sign);
9470 else if(shCount >= 8){
9473 shiftRLong(left, MSB16, result, sign);
9474 else if(shCount == 0){
9475 movLeft2Result(left, MSB16, result, LSB);
9476 movLeft2Result(left, MSB24, result, MSB16);
9477 movLeft2Result(left, MSB32, result, MSB24);
9478 pic16_addSign(result, MSB32, sign);
9480 else{ //shcount >= 2
9481 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
9482 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
9483 /* the last shift is signed */
9484 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
9485 pic16_addSign(result, MSB32, sign);
9488 else{ /* 1 <= shCount <= 7 */
9490 shiftRLong(left, LSB, result, sign);
9492 shiftRLong(result, LSB, result, sign);
9495 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
9496 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
9497 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
9502 /*-----------------------------------------------------------------*/
9503 /* genRightShiftLiteral - right shifting by known count */
9504 /*-----------------------------------------------------------------*/
9505 static void genRightShiftLiteral (operand *left,
9511 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
9514 pic16_freeAsmop(right,NULL,ic,TRUE);
9516 pic16_aopOp(left,ic,FALSE);
9517 pic16_aopOp(result,ic,FALSE);
9519 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
9522 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
9526 lsize = pic16_getDataSize(left);
9527 res_size = pic16_getDataSize(result);
9528 /* test the LEFT size !!! */
9530 /* I suppose that the left size >= result size */
9533 movLeft2Result(left, lsize, result, res_size);
9536 else if(shCount >= (lsize * 8)){
9539 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
9541 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9542 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
9547 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
9548 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9549 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9551 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
9556 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
9563 genrshOne (result,left,shCount,sign);
9567 genrshTwo (result,left,shCount,sign);
9571 genrshFour (result,left,shCount,sign);
9579 pic16_freeAsmop(left,NULL,ic,TRUE);
9580 pic16_freeAsmop(result,NULL,ic,TRUE);
9583 /*-----------------------------------------------------------------*/
9584 /* genSignedRightShift - right shift of signed number */
9585 /*-----------------------------------------------------------------*/
9586 static void genSignedRightShift (iCode *ic)
9588 operand *right, *left, *result;
9591 symbol *tlbl, *tlbl1 ;
9594 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
9596 /* we do it the hard way put the shift count in b
9597 and loop thru preserving the sign */
9598 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9600 right = IC_RIGHT(ic);
9602 result = IC_RESULT(ic);
9604 pic16_aopOp(right,ic,FALSE);
9605 pic16_aopOp(left,ic,FALSE);
9606 pic16_aopOp(result,ic,FALSE);
9609 if ( AOP_TYPE(right) == AOP_LIT) {
9610 genRightShiftLiteral (left,right,result,ic,1);
9613 /* shift count is unknown then we have to form
9614 a loop get the loop count in B : Note: we take
9615 only the lower order byte since shifting
9616 more that 32 bits make no sense anyway, ( the
9617 largest size of an object can be only 32 bits ) */
9619 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9620 //pic16_emitcode("inc","b");
9621 //pic16_freeAsmop (right,NULL,ic,TRUE);
9622 //pic16_aopOp(left,ic,FALSE);
9623 //pic16_aopOp(result,ic,FALSE);
9625 /* now move the left to the result if they are not the
9627 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9628 AOP_SIZE(result) > 1) {
9630 size = AOP_SIZE(result);
9634 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9635 if (*l == '@' && IS_AOP_PREG(result)) {
9637 pic16_emitcode("mov","a,%s",l);
9638 pic16_aopPut(AOP(result),"a",offset);
9640 pic16_aopPut(AOP(result),l,offset);
9642 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
9643 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9649 /* mov the highest order bit to OVR */
9650 tlbl = newiTempLabel(NULL);
9651 tlbl1= newiTempLabel(NULL);
9653 size = AOP_SIZE(result);
9656 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9658 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9660 /* offset should be 0, 1 or 3 */
9661 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
9663 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9665 pic16_emitpcode(POC_MOVWF, pctemp);
9668 pic16_emitpLabel(tlbl->key);
9670 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
9671 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
9674 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
9677 pic16_emitpcode(POC_DECFSZ, pctemp);
9678 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9679 pic16_emitpLabel(tlbl1->key);
9681 pic16_popReleaseTempReg(pctemp,1);
9683 size = AOP_SIZE(result);
9685 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
9686 pic16_emitcode("rlc","a");
9687 pic16_emitcode("mov","ov,c");
9688 /* if it is only one byte then */
9690 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9692 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9693 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9694 pic16_emitcode("mov","c,ov");
9695 pic16_emitcode("rrc","a");
9696 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9697 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9698 pic16_aopPut(AOP(result),"a",0);
9702 reAdjustPreg(AOP(result));
9703 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9704 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9705 pic16_emitcode("mov","c,ov");
9707 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9709 pic16_emitcode("rrc","a");
9710 pic16_aopPut(AOP(result),"a",offset--);
9712 reAdjustPreg(AOP(result));
9713 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9714 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9719 pic16_freeAsmop(left,NULL,ic,TRUE);
9720 pic16_freeAsmop(result,NULL,ic,TRUE);
9721 pic16_freeAsmop(right,NULL,ic,TRUE);
9724 /*-----------------------------------------------------------------*/
9725 /* genRightShift - generate code for right shifting */
9726 /*-----------------------------------------------------------------*/
9727 static void genRightShift (iCode *ic)
9729 operand *right, *left, *result;
9733 symbol *tlbl, *tlbl1 ;
9735 /* if signed then we do it the hard way preserve the
9736 sign bit moving it inwards */
9737 letype = getSpec(operandType(IC_LEFT(ic)));
9738 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9740 if (!SPEC_USIGN(letype)) {
9741 genSignedRightShift (ic);
9745 /* signed & unsigned types are treated the same : i.e. the
9746 signed is NOT propagated inwards : quoting from the
9747 ANSI - standard : "for E1 >> E2, is equivalent to division
9748 by 2**E2 if unsigned or if it has a non-negative value,
9749 otherwise the result is implementation defined ", MY definition
9750 is that the sign does not get propagated */
9752 right = IC_RIGHT(ic);
9754 result = IC_RESULT(ic);
9756 pic16_aopOp(right,ic,FALSE);
9758 /* if the shift count is known then do it
9759 as efficiently as possible */
9760 if (AOP_TYPE(right) == AOP_LIT) {
9761 genRightShiftLiteral (left,right,result,ic, 0);
9765 /* shift count is unknown then we have to form
9766 a loop get the loop count in B : Note: we take
9767 only the lower order byte since shifting
9768 more that 32 bits make no sense anyway, ( the
9769 largest size of an object can be only 32 bits ) */
9771 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9772 pic16_emitcode("inc","b");
9773 pic16_aopOp(left,ic,FALSE);
9774 pic16_aopOp(result,ic,FALSE);
9776 /* now move the left to the result if they are not the
9778 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9779 AOP_SIZE(result) > 1) {
9781 size = AOP_SIZE(result);
9784 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9785 if (*l == '@' && IS_AOP_PREG(result)) {
9787 pic16_emitcode("mov","a,%s",l);
9788 pic16_aopPut(AOP(result),"a",offset);
9790 pic16_aopPut(AOP(result),l,offset);
9795 tlbl = newiTempLabel(NULL);
9796 tlbl1= newiTempLabel(NULL);
9797 size = AOP_SIZE(result);
9800 /* if it is only one byte then */
9803 tlbl = newiTempLabel(NULL);
9804 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9805 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9806 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9809 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9810 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9811 pic16_emitpLabel(tlbl->key);
9812 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9813 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9815 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9820 reAdjustPreg(AOP(result));
9821 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9822 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9825 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9827 pic16_emitcode("rrc","a");
9828 pic16_aopPut(AOP(result),"a",offset--);
9830 reAdjustPreg(AOP(result));
9832 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9833 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9836 pic16_freeAsmop(left,NULL,ic,TRUE);
9837 pic16_freeAsmop (right,NULL,ic,TRUE);
9838 pic16_freeAsmop(result,NULL,ic,TRUE);
9842 void pic16_loadFSR0(operand *op)
9844 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9847 /*-----------------------------------------------------------------*/
9848 /* genUnpackBits - generates code for unpacking bits */
9849 /*-----------------------------------------------------------------*/
9850 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
9857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9858 etype = getSpec(operandType(result));
9860 /* the following call to pic16_loadFSR0 is temporary until
9861 * optimization to handle single bit assignments is added
9862 * to the function. Until then use the old safe way! -- VR */
9863 pic16_loadFSR0( left );
9865 /* read the first byte */
9872 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9875 pic16_emitcode("clr","a");
9876 pic16_emitcode("movc","a","@a+dptr");
9881 /* if we have bitdisplacement then it fits */
9882 /* into this byte completely or if length is */
9883 /* less than a byte */
9884 if ((shCnt = SPEC_BSTR(etype)) ||
9885 (SPEC_BLEN(etype) <= 8)) {
9887 /* shift right acc */
9890 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9891 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
9893 /* VR -- normally I would use the following, but since we use the hack,
9894 * to avoid the masking from AccRsh, why not mask it right now? */
9897 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
9900 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9906 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9907 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9910 /* bit field did not fit in a byte */
9911 rlen = SPEC_BLEN(etype) - 8;
9912 pic16_aopPut(AOP(result),"a",offset++);
9919 pic16_emitcode("inc","%s",rname);
9920 pic16_emitcode("mov","a,@%s",rname);
9924 pic16_emitcode("inc","%s",rname);
9925 pic16_emitcode("movx","a,@%s",rname);
9929 pic16_emitcode("inc","dptr");
9930 pic16_emitcode("movx","a,@dptr");
9934 pic16_emitcode("clr","a");
9935 pic16_emitcode("inc","dptr");
9936 pic16_emitcode("movc","a","@a+dptr");
9940 pic16_emitcode("inc","dptr");
9941 pic16_emitcode("lcall","__gptrget");
9946 /* if we are done */
9950 pic16_aopPut(AOP(result),"a",offset++);
9955 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9956 pic16_aopPut(AOP(result),"a",offset);
9963 static void genDataPointerGet(operand *left,
9967 int size, offset = 0, leoffset=0 ;
9969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9970 pic16_aopOp(result, ic, FALSE);
9972 size = AOP_SIZE(result);
9973 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9977 /* The following tests may save a redudant movff instruction when
9978 * accessing unions */
9980 /* if they are the same */
9981 if (operandsEqu (left, result)) {
9982 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9988 /* if they are the same registers */
9989 if (pic16_sameRegs(AOP(left),AOP(result))) {
9990 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9996 if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
9997 pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
9998 DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
10005 if ( AOP_TYPE(left) == AOP_PCODE) {
10006 fprintf(stderr,"genDataPointerGet %s, %d\n",
10007 AOP(left)->aopu.pcop->name,
10008 (AOP(left)->aopu.pcop->type == PO_DIR)?
10009 PCOR(AOP(left)->aopu.pcop)->instance:
10010 PCOI(AOP(left)->aopu.pcop)->offset);
10014 if(AOP(left)->aopu.pcop->type == PO_DIR)
10015 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
10017 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10020 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
10022 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
10023 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
10024 mov2w(AOP(left), offset); // patch 8
10025 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
10027 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
10028 pic16_popGet(AOP(left), offset), //patch 8
10029 pic16_popGet(AOP(result), offset)));
10037 pic16_freeAsmop(result,NULL,ic,TRUE);
10042 /*-----------------------------------------------------------------*/
10043 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
10044 /*-----------------------------------------------------------------*/
10045 static void genNearPointerGet (operand *left,
10050 //regs *preg = NULL ;
10051 sym_link *rtype, *retype;
10052 sym_link *ltype = operandType(left);
10054 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10055 rtype = operandType(result);
10056 retype= getSpec(rtype);
10058 pic16_aopOp(left,ic,FALSE);
10060 // pic16_DumpOp("(left)",left);
10061 // pic16_DumpOp("(result)",result);
10063 /* if left is rematerialisable and
10064 * result is not bit variable type and
10065 * the left is pointer to data space i.e
10066 * lower 128 bytes of space */
10067 if (AOP_TYPE(left) == AOP_PCODE
10068 && !IS_BITFIELD(retype)
10069 && DCL_TYPE(ltype) == POINTER) {
10071 genDataPointerGet (left,result,ic);
10072 pic16_freeAsmop(left, NULL, ic, TRUE);
10076 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10078 /* if the value is already in a pointer register
10079 * then don't need anything more */
10080 if (!AOP_INPREG(AOP(left))) {
10081 /* otherwise get a free pointer register */
10082 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10084 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
10085 if( (AOP_TYPE(left) == AOP_PCODE)
10086 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10087 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
10089 if(!IS_BITFIELD(retype))
10090 pic16_loadFSR0( left ); // patch 10
10092 // set up FSR0 with address from left
10093 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10094 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10098 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10100 pic16_aopOp (result,ic,FALSE);
10102 /* if bitfield then unpack the bits */
10103 if (IS_BITFIELD(retype))
10104 genUnpackBits (result, left, NULL, POINTER);
10106 /* we have can just get the values */
10107 int size = AOP_SIZE(result);
10110 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10113 /* fsr0 is loaded already -- VR */
10114 // pic16_loadFSR0( left );
10116 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
10117 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
10121 pic16_emitpcode(POC_MOVFF,
10122 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
10123 pic16_popGet(AOP(result), offset++)));
10125 pic16_emitpcode(POC_MOVFF,
10126 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
10127 pic16_popGet(AOP(result), offset++)));
10131 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
10132 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
10134 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
10138 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
10140 pic16_emitcode("mov","a,@%s",rname);
10141 pic16_aopPut(AOP(result),"a",offset);
10143 sprintf(buffer,"@%s",rname);
10144 pic16_aopPut(AOP(result),buffer,offset);
10148 pic16_emitcode("inc","%s",rname);
10153 /* now some housekeeping stuff */
10155 /* we had to allocate for this iCode */
10156 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10157 pic16_freeAsmop(NULL,aop,ic,TRUE);
10159 /* we did not allocate which means left
10160 already in a pointer register, then
10161 if size > 0 && this could be used again
10162 we have to point it back to where it
10164 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10165 if (AOP_SIZE(result) > 1 &&
10166 !OP_SYMBOL(left)->remat &&
10167 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10169 // int size = AOP_SIZE(result) - 1;
10171 // pic16_emitcode("dec","%s",rname);
10176 pic16_freeAsmop(left,NULL,ic,TRUE);
10177 pic16_freeAsmop(result,NULL,ic,TRUE);
10181 /*-----------------------------------------------------------------*/
10182 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
10183 /*-----------------------------------------------------------------*/
10184 static void genPagedPointerGet (operand *left,
10189 regs *preg = NULL ;
10191 sym_link *rtype, *retype;
10193 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10195 rtype = operandType(result);
10196 retype= getSpec(rtype);
10198 pic16_aopOp(left,ic,FALSE);
10200 /* if the value is already in a pointer register
10201 then don't need anything more */
10202 if (!AOP_INPREG(AOP(left))) {
10203 /* otherwise get a free pointer register */
10205 preg = getFreePtr(ic,&aop,FALSE);
10206 pic16_emitcode("mov","%s,%s",
10208 pic16_aopGet(AOP(left),0,FALSE,TRUE));
10209 rname = preg->name ;
10211 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10213 pic16_freeAsmop(left,NULL,ic,TRUE);
10214 pic16_aopOp (result,ic,FALSE);
10216 /* if bitfield then unpack the bits */
10217 if (IS_BITFIELD(retype))
10218 genUnpackBits (result,left,rname,PPOINTER);
10220 /* we have can just get the values */
10221 int size = AOP_SIZE(result);
10226 pic16_emitcode("movx","a,@%s",rname);
10227 pic16_aopPut(AOP(result),"a",offset);
10232 pic16_emitcode("inc","%s",rname);
10236 /* now some housekeeping stuff */
10238 /* we had to allocate for this iCode */
10239 pic16_freeAsmop(NULL,aop,ic,TRUE);
10241 /* we did not allocate which means left
10242 already in a pointer register, then
10243 if size > 0 && this could be used again
10244 we have to point it back to where it
10246 if (AOP_SIZE(result) > 1 &&
10247 !OP_SYMBOL(left)->remat &&
10248 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10250 int size = AOP_SIZE(result) - 1;
10252 pic16_emitcode("dec","%s",rname);
10257 pic16_freeAsmop(result,NULL,ic,TRUE);
10262 /*-----------------------------------------------------------------*/
10263 /* genFarPointerGet - gget value from far space */
10264 /*-----------------------------------------------------------------*/
10265 static void genFarPointerGet (operand *left,
10266 operand *result, iCode *ic)
10269 sym_link *retype = getSpec(operandType(result));
10271 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10273 pic16_aopOp(left,ic,FALSE);
10275 /* if the operand is already in dptr
10276 then we do nothing else we move the value to dptr */
10277 if (AOP_TYPE(left) != AOP_STR) {
10278 /* if this is remateriazable */
10279 if (AOP_TYPE(left) == AOP_IMMD)
10280 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10281 else { /* we need to get it byte by byte */
10282 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10283 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10284 if (options.model == MODEL_FLAT24)
10286 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10290 /* so dptr know contains the address */
10291 pic16_freeAsmop(left,NULL,ic,TRUE);
10292 pic16_aopOp(result,ic,FALSE);
10294 /* if bit then unpack */
10295 if (IS_BITFIELD(retype))
10296 genUnpackBits(result,left,"dptr",FPOINTER);
10298 size = AOP_SIZE(result);
10302 pic16_emitcode("movx","a,@dptr");
10303 pic16_aopPut(AOP(result),"a",offset++);
10305 pic16_emitcode("inc","dptr");
10309 pic16_freeAsmop(result,NULL,ic,TRUE);
10312 /*-----------------------------------------------------------------*/
10313 /* genCodePointerGet - get value from code space */
10314 /*-----------------------------------------------------------------*/
10315 static void genCodePointerGet (operand *left,
10316 operand *result, iCode *ic)
10319 sym_link *retype = getSpec(operandType(result));
10321 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10323 pic16_aopOp(left,ic,FALSE);
10325 /* if the operand is already in dptr
10326 then we do nothing else we move the value to dptr */
10327 if (AOP_TYPE(left) != AOP_STR) {
10328 /* if this is remateriazable */
10329 if (AOP_TYPE(left) == AOP_IMMD)
10330 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10331 else { /* we need to get it byte by byte */
10332 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10333 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10334 if (options.model == MODEL_FLAT24)
10336 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10340 /* so dptr know contains the address */
10341 pic16_freeAsmop(left,NULL,ic,TRUE);
10342 pic16_aopOp(result,ic,FALSE);
10344 /* if bit then unpack */
10345 if (IS_BITFIELD(retype))
10346 genUnpackBits(result,left,"dptr",CPOINTER);
10348 size = AOP_SIZE(result);
10352 pic16_emitcode("clr","a");
10353 pic16_emitcode("movc","a,@a+dptr");
10354 pic16_aopPut(AOP(result),"a",offset++);
10356 pic16_emitcode("inc","dptr");
10360 pic16_freeAsmop(result,NULL,ic,TRUE);
10364 /*-----------------------------------------------------------------*/
10365 /* genGenPointerGet - gget value from generic pointer space */
10366 /*-----------------------------------------------------------------*/
10367 static void genGenPointerGet (operand *left,
10368 operand *result, iCode *ic)
10370 int size, offset, lit;
10371 sym_link *retype = getSpec(operandType(result));
10373 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10374 pic16_aopOp(left,ic,FALSE);
10375 pic16_aopOp(result,ic,FALSE);
10376 size = AOP_SIZE(result);
10378 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10380 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10382 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10383 // load FSR0 from immediate
10384 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10386 // pic16_loadFSR0( left );
10391 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10393 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10400 else { /* we need to get it byte by byte */
10401 // set up FSR0 with address from left
10402 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10403 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10409 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10411 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10418 /* if bit then unpack */
10419 if (IS_BITFIELD(retype))
10420 genUnpackBits(result,left,"BAD",GPOINTER);
10423 pic16_freeAsmop(left,NULL,ic,TRUE);
10424 pic16_freeAsmop(result,NULL,ic,TRUE);
10430 /*-----------------------------------------------------------------*/
10431 /* genGenPointerGet - gget value from generic pointer space */
10432 /*-----------------------------------------------------------------*/
10433 static void genGenPointerGet (operand *left,
10434 operand *result, iCode *ic)
10436 int size, offset, lit;
10437 sym_link *retype = getSpec(operandType(result));
10440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10441 pic16_aopOp(left,ic,FALSE);
10442 pic16_aopOp(result,ic,FALSE);
10443 size = AOP_SIZE(result);
10445 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10447 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10449 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10450 // load FSR0 from immediate
10451 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10453 werror(W_POSSBUG2, __FILE__, __LINE__);
10458 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10460 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10467 } else { /* we need to get it byte by byte */
10469 /* set up WREG:PRODL:FSR0L with address from left */
10470 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10471 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
10472 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
10475 case 1: strcpy(fgptrget, "__gptrget1"); break;
10476 case 2: strcpy(fgptrget, "__gptrget2"); break;
10477 case 3: strcpy(fgptrget, "__gptrget3"); break;
10478 case 4: strcpy(fgptrget, "__gptrget4"); break;
10480 werror(W_POSSBUG2, __FILE__, __LINE__);
10484 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget ));
10486 assignResultValue(result, 1);
10491 sym = newSymbol( fgptrget, 0 );
10492 strcpy(sym->rname, fgptrget);
10493 checkAddSym(&externs, sym);
10495 // fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
10501 /* if bit then unpack */
10502 if (IS_BITFIELD(retype))
10503 genUnpackBits(result,left,"BAD",GPOINTER);
10506 pic16_freeAsmop(left,NULL,ic,TRUE);
10507 pic16_freeAsmop(result,NULL,ic,TRUE);
10510 /*-----------------------------------------------------------------*/
10511 /* genConstPointerGet - get value from const generic pointer space */
10512 /*-----------------------------------------------------------------*/
10513 static void genConstPointerGet (operand *left,
10514 operand *result, iCode *ic)
10516 //sym_link *retype = getSpec(operandType(result));
10517 // symbol *albl = newiTempLabel(NULL); // patch 15
10518 // symbol *blbl = newiTempLabel(NULL); //
10519 // PIC_OPCODE poc; // patch 15
10523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10524 pic16_aopOp(left,ic,FALSE);
10525 pic16_aopOp(result,ic,TRUE);
10526 size = AOP_SIZE(result);
10528 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10530 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
10532 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
10533 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
10534 pic16_emitpLabel(albl->key);
10536 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
10538 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
10539 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
10540 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
10541 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
10542 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
10544 pic16_emitpLabel(blbl->key);
10546 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
10550 // set up table pointer
10551 if( (AOP_TYPE(left) == AOP_PCODE)
10552 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10553 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
10555 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
10556 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
10557 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
10558 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
10559 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
10560 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
10564 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
10565 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
10566 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
10572 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
10573 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
10577 pic16_freeAsmop(left,NULL,ic,TRUE);
10578 pic16_freeAsmop(result,NULL,ic,TRUE);
10583 /*-----------------------------------------------------------------*/
10584 /* genPointerGet - generate code for pointer get */
10585 /*-----------------------------------------------------------------*/
10586 static void genPointerGet (iCode *ic)
10588 operand *left, *result ;
10589 sym_link *type, *etype;
10592 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10594 left = IC_LEFT(ic);
10595 result = IC_RESULT(ic) ;
10597 /* depending on the type of pointer we need to
10598 move it to the correct pointer register */
10599 type = operandType(left);
10600 etype = getSpec(type);
10603 if (IS_PTR_CONST(type))
10605 if (IS_CODEPTR(type))
10607 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
10609 /* if left is of type of pointer then it is simple */
10610 if (IS_PTR(type) && !IS_FUNC(type->next))
10611 p_type = DCL_TYPE(type);
10613 /* we have to go by the storage class */
10614 p_type = PTR_TYPE(SPEC_OCLS(etype));
10616 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
10618 if (SPEC_OCLS(etype)->codesp ) {
10619 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
10620 //p_type = CPOINTER ;
10623 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
10624 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
10625 /*p_type = FPOINTER ;*/
10627 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
10628 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
10629 /* p_type = PPOINTER; */
10631 if (SPEC_OCLS(etype) == idata )
10632 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
10633 /* p_type = IPOINTER; */
10635 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
10636 /* p_type = POINTER ; */
10639 /* now that we have the pointer type we assign
10640 the pointer values */
10645 genNearPointerGet (left,result,ic);
10649 genPagedPointerGet(left,result,ic);
10653 genFarPointerGet (left,result,ic);
10657 genConstPointerGet (left,result,ic);
10658 //pic16_emitcodePointerGet (left,result,ic);
10663 if (IS_PTR_CONST(type))
10664 genConstPointerGet (left,result,ic);
10667 genGenPointerGet (left,result,ic);
10671 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10672 "genPointerGet: illegal pointer type");
10678 /*-----------------------------------------------------------------*/
10679 /* genPackBits - generates code for packed bit storage */
10680 /*-----------------------------------------------------------------*/
10681 static void genPackBits (sym_link *etype , operand *result,
10683 char *rname, int p_type)
10691 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10692 blen = SPEC_BLEN(etype);
10693 bstr = SPEC_BSTR(etype);
10695 if(AOP_TYPE(right) == AOP_LIT) {
10696 if((blen == 1) && (bstr < 8)) {
10698 /* it is a single bit, so use the appropriate bit instructions */
10700 DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
10702 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10703 // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10704 if((p_type == POINTER) && (result)) {
10705 /* workaround to reduce the extra lfsr instruction */
10707 pic16_emitpcode(POC_BSF,
10708 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10710 pic16_emitpcode(POC_BCF,
10711 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10716 pic16_emitpcode(POC_BSF,
10717 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10719 pic16_emitpcode(POC_BCF,
10720 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10727 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
10730 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
10732 /* if the bit lenth is less than or */
10733 /* it exactly fits a byte then */
10734 if((shCnt=SPEC_BSTR(etype))
10735 || SPEC_BLEN(etype) <= 8 ) {
10737 /* shift left acc */
10740 /* using PRODL as a temporary register here */
10741 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
10747 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10748 // pic16_emitcode ("mov","b,a");
10749 // pic16_emitcode("mov","a,@%s",rname);
10753 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
10754 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
10755 (unsigned char)(0xff >> (8-bstr))) ));
10756 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
10757 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10764 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
10765 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
10770 if ( SPEC_BLEN(etype) <= 8 )
10773 pic16_emitcode("inc","%s",rname);
10774 rLen = SPEC_BLEN(etype) ;
10778 /* now generate for lengths greater than one byte */
10781 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
10791 pic16_emitcode("mov","@%s,a",rname);
10793 pic16_emitcode("mov","@%s,%s",rname,l);
10798 pic16_emitcode("movx","@dptr,a");
10803 DEBUGpic16_emitcode(";lcall","__gptrput");
10806 pic16_emitcode ("inc","%s",rname);
10811 /* last last was not complete */
10813 /* save the byte & read byte */
10816 pic16_emitcode ("mov","b,a");
10817 pic16_emitcode("mov","a,@%s",rname);
10821 pic16_emitcode ("mov","b,a");
10822 pic16_emitcode("movx","a,@dptr");
10826 pic16_emitcode ("push","b");
10827 pic16_emitcode ("push","acc");
10828 pic16_emitcode ("lcall","__gptrget");
10829 pic16_emitcode ("pop","b");
10833 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
10834 pic16_emitcode ("orl","a,b");
10837 if (p_type == GPOINTER)
10838 pic16_emitcode("pop","b");
10843 pic16_emitcode("mov","@%s,a",rname);
10847 pic16_emitcode("movx","@dptr,a");
10851 DEBUGpic16_emitcode(";lcall","__gptrput");
10855 /*-----------------------------------------------------------------*/
10856 /* genDataPointerSet - remat pointer to data space */
10857 /*-----------------------------------------------------------------*/
10858 static void genDataPointerSet(operand *right,
10862 int size, offset = 0, resoffset=0 ;
10864 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10865 pic16_aopOp(right,ic,FALSE);
10867 size = AOP_SIZE(right);
10869 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
10872 if ( AOP_TYPE(result) == AOP_PCODE) {
10873 fprintf(stderr,"genDataPointerSet %s, %d\n",
10874 AOP(result)->aopu.pcop->name,
10875 (AOP(result)->aopu.pcop->type == PO_DIR)?
10876 PCOR(AOP(result)->aopu.pcop)->instance:
10877 PCOI(AOP(result)->aopu.pcop)->offset);
10881 if(AOP(result)->aopu.pcop->type == PO_DIR)
10882 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
10885 if (AOP_TYPE(right) == AOP_LIT) {
10888 if(!IS_FLOAT(operandType( right )))
10889 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
10892 unsigned long lit_int;
10896 /* take care if literal is a float */
10897 info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
10898 lit = info.lit_int;
10901 lit = lit >> (8*offset);
10903 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
10904 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
10906 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
10909 mov2w(AOP(right), offset);
10910 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
10916 pic16_freeAsmop(right,NULL,ic,TRUE);
10921 /*-----------------------------------------------------------------*/
10922 /* genNearPointerSet - pic16_emitcode for near pointer put */
10923 /*-----------------------------------------------------------------*/
10924 static void genNearPointerSet (operand *right,
10931 sym_link *ptype = operandType(result);
10932 sym_link *resetype;
10934 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10935 retype= getSpec(operandType(right));
10936 resetype = getSpec(operandType(result));
10938 pic16_aopOp(result,ic,FALSE);
10940 /* if the result is rematerializable &
10941 * in data space & not a bit variable */
10943 /* and result is not a bit variable */
10944 if (AOP_TYPE(result) == AOP_PCODE
10945 // && AOP_TYPE(result) == AOP_IMMD
10946 && DCL_TYPE(ptype) == POINTER
10947 && !IS_BITFIELD(retype)
10948 && !IS_BITFIELD(resetype)) {
10950 genDataPointerSet (right,result,ic);
10951 pic16_freeAsmop(result,NULL,ic,TRUE);
10955 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10956 pic16_aopOp(right,ic,FALSE);
10957 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10959 /* if the value is already in a pointer register
10960 * then don't need anything more */
10961 if (!AOP_INPREG(AOP(result))) {
10962 /* otherwise get a free pointer register */
10963 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10965 if( (AOP_TYPE(result) == AOP_PCODE)
10966 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
10967 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
10969 if(!IS_BITFIELD(resetype))
10970 pic16_loadFSR0( result ); // patch 10
10972 // set up FSR0 with address of result
10973 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10974 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10979 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10981 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10983 /* if bitfield then unpack the bits */
10984 if (IS_BITFIELD(resetype)) {
10985 genPackBits (resetype, result, right, NULL, POINTER);
10987 /* we have can just get the values */
10988 int size = AOP_SIZE(right);
10991 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10993 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10996 //pic16_emitcode("mov","@%s,a",rname);
10997 pic16_emitcode("movf","indf0,w ;1");
11000 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
11001 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
11003 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
11005 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
11007 } else { // no literal //
11009 pic16_emitpcode(POC_MOVFF, //
11010 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
11011 pic16_popCopyReg(&pic16_pc_postinc0))); //
11013 pic16_emitpcode(POC_MOVFF, //
11014 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
11015 pic16_popCopyReg(&pic16_pc_indf0))); //
11023 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11024 /* now some housekeeping stuff */
11026 /* we had to allocate for this iCode */
11027 pic16_freeAsmop(NULL,aop,ic,TRUE);
11029 /* we did not allocate which means left
11030 * already in a pointer register, then
11031 * if size > 0 && this could be used again
11032 * we have to point it back to where it
11034 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11035 if (AOP_SIZE(right) > 1
11036 && !OP_SYMBOL(result)->remat
11037 && ( OP_SYMBOL(result)->liveTo > ic->seq
11040 int size = AOP_SIZE(right) - 1;
11043 pic16_emitcode("decf","fsr0,f");
11044 //pic16_emitcode("dec","%s",rname);
11048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11051 pic16_freeAsmop(right,NULL,ic,TRUE);
11052 pic16_freeAsmop(result,NULL,ic,TRUE);
11055 /*-----------------------------------------------------------------*/
11056 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
11057 /*-----------------------------------------------------------------*/
11058 static void genPagedPointerSet (operand *right,
11063 regs *preg = NULL ;
11067 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11069 retype= getSpec(operandType(right));
11071 pic16_aopOp(result,ic,FALSE);
11073 /* if the value is already in a pointer register
11074 then don't need anything more */
11075 if (!AOP_INPREG(AOP(result))) {
11076 /* otherwise get a free pointer register */
11078 preg = getFreePtr(ic,&aop,FALSE);
11079 pic16_emitcode("mov","%s,%s",
11081 pic16_aopGet(AOP(result),0,FALSE,TRUE));
11082 rname = preg->name ;
11084 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11086 pic16_freeAsmop(result,NULL,ic,TRUE);
11087 pic16_aopOp (right,ic,FALSE);
11089 /* if bitfield then unpack the bits */
11090 if (IS_BITFIELD(retype))
11091 genPackBits (retype,result,right,rname,PPOINTER);
11093 /* we have can just get the values */
11094 int size = AOP_SIZE(right);
11098 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
11101 pic16_emitcode("movx","@%s,a",rname);
11104 pic16_emitcode("inc","%s",rname);
11110 /* now some housekeeping stuff */
11112 /* we had to allocate for this iCode */
11113 pic16_freeAsmop(NULL,aop,ic,TRUE);
11115 /* we did not allocate which means left
11116 already in a pointer register, then
11117 if size > 0 && this could be used again
11118 we have to point it back to where it
11120 if (AOP_SIZE(right) > 1 &&
11121 !OP_SYMBOL(result)->remat &&
11122 ( OP_SYMBOL(result)->liveTo > ic->seq ||
11124 int size = AOP_SIZE(right) - 1;
11126 pic16_emitcode("dec","%s",rname);
11131 pic16_freeAsmop(right,NULL,ic,TRUE);
11136 /*-----------------------------------------------------------------*/
11137 /* genFarPointerSet - set value from far space */
11138 /*-----------------------------------------------------------------*/
11139 static void genFarPointerSet (operand *right,
11140 operand *result, iCode *ic)
11143 sym_link *retype = getSpec(operandType(right));
11145 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11146 pic16_aopOp(result,ic,FALSE);
11148 /* if the operand is already in dptr
11149 then we do nothing else we move the value to dptr */
11150 if (AOP_TYPE(result) != AOP_STR) {
11151 /* if this is remateriazable */
11152 if (AOP_TYPE(result) == AOP_IMMD)
11153 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
11154 else { /* we need to get it byte by byte */
11155 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
11156 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
11157 if (options.model == MODEL_FLAT24)
11159 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
11163 /* so dptr know contains the address */
11164 pic16_freeAsmop(result,NULL,ic,TRUE);
11165 pic16_aopOp(right,ic,FALSE);
11167 /* if bit then unpack */
11168 if (IS_BITFIELD(retype))
11169 genPackBits(retype,result,right,"dptr",FPOINTER);
11171 size = AOP_SIZE(right);
11175 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11177 pic16_emitcode("movx","@dptr,a");
11179 pic16_emitcode("inc","dptr");
11183 pic16_freeAsmop(right,NULL,ic,TRUE);
11186 /*-----------------------------------------------------------------*/
11187 /* genGenPointerSet - set value from generic pointer space */
11188 /*-----------------------------------------------------------------*/
11190 static void genGenPointerSet (operand *right,
11191 operand *result, iCode *ic)
11193 int i, size, offset, lit;
11194 sym_link *retype = getSpec(operandType(right));
11196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11198 pic16_aopOp(result,ic,FALSE);
11199 pic16_aopOp(right,ic,FALSE);
11200 size = AOP_SIZE(right);
11203 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11205 /* if the operand is already in dptr
11206 then we do nothing else we move the value to dptr */
11207 if (AOP_TYPE(result) != AOP_STR) {
11208 /* if this is remateriazable */
11209 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11210 // WARNING: anythig until "else" is untested!
11211 if (AOP_TYPE(result) == AOP_IMMD) {
11212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11213 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
11214 // load FSR0 from immediate
11215 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11219 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11221 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11227 else { /* we need to get it byte by byte */
11228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11229 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11231 // set up FSR0 with address of result
11232 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11233 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11235 /* hack hack! see if this the FSR. If so don't load W */
11236 if(AOP_TYPE(right) != AOP_ACC) {
11238 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11240 if(AOP_TYPE(right) == AOP_LIT)
11243 // note: pic16_popGet handles sign extension
11244 for(i=0;i<size;i++) {
11245 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
11247 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
11249 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
11254 for(i=0;i<size;i++) {
11256 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11257 pic16_popCopyReg(&pic16_pc_postinc0)));
11259 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11260 pic16_popCopyReg(&pic16_pc_indf0)));
11266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11267 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11269 } // if (AOP_TYPE(result) != AOP_IMMD)
11271 } // if (AOP_TYPE(result) != AOP_STR)
11272 /* so dptr know contains the address */
11275 /* if bit then unpack */
11276 if (IS_BITFIELD(retype))
11277 genPackBits(retype,result,right,"dptr",GPOINTER);
11279 size = AOP_SIZE(right);
11282 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11284 // set up FSR0 with address of result
11285 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11286 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11289 if (AOP_TYPE(right) == AOP_LIT) {
11290 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11292 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
11294 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11296 } else { // no literal
11298 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11300 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11308 pic16_freeAsmop(right,NULL,ic,TRUE);
11309 pic16_freeAsmop(result,NULL,ic,TRUE);
11313 static void genGenPointerSet (operand *right,
11314 operand *result, iCode *ic)
11317 sym_link *retype = getSpec(operandType(right));
11320 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11322 pic16_aopOp(result,ic,FALSE);
11323 pic16_aopOp(right,ic,FALSE);
11324 size = AOP_SIZE(right);
11326 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11329 /* if bit then unpack */
11330 if (IS_BITFIELD(retype)) {
11331 // pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11332 genPackBits(retype,result,right,"dptr",GPOINTER);
11336 size = AOP_SIZE(right);
11338 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11342 /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
11344 /* value of right+0 is placed on stack, which will be retrieved
11345 * by the support function this restoring the stack. The important
11346 * thing is that there is no need to manually restore stack pointer
11348 pushaop(AOP(right), 0);
11349 // mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
11350 if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
11351 if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
11352 if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
11354 /* load address to write to in WREG:FSR0H:FSR0L */
11355 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
11356 pic16_popCopyReg(&pic16_pc_fsr0l)));
11357 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
11358 pic16_popCopyReg(&pic16_pc_prodl)));
11359 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
11362 /* put code here */
11364 case 1: strcpy(fgptrput, "__gptrput1"); break;
11365 case 2: strcpy(fgptrput, "__gptrput2"); break;
11366 case 3: strcpy(fgptrput, "__gptrput3"); break;
11367 case 4: strcpy(fgptrput, "__gptrput4"); break;
11369 werror(W_POSSBUG2, __FILE__, __LINE__);
11373 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput ));
11378 sym = newSymbol( fgptrput, 0 );
11379 strcpy(sym->rname, fgptrput);
11380 checkAddSym(&externs, sym);
11384 pic16_freeAsmop(right,NULL,ic,TRUE);
11385 pic16_freeAsmop(result,NULL,ic,TRUE);
11388 /*-----------------------------------------------------------------*/
11389 /* genPointerSet - stores the value into a pointer location */
11390 /*-----------------------------------------------------------------*/
11391 static void genPointerSet (iCode *ic)
11393 operand *right, *result ;
11394 sym_link *type, *etype;
11397 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11399 right = IC_RIGHT(ic);
11400 result = IC_RESULT(ic) ;
11402 /* depending on the type of pointer we need to
11403 move it to the correct pointer register */
11404 type = operandType(result);
11405 etype = getSpec(type);
11406 /* if left is of type of pointer then it is simple */
11407 if (IS_PTR(type) && !IS_FUNC(type->next)) {
11408 p_type = DCL_TYPE(type);
11411 /* we have to go by the storage class */
11412 p_type = PTR_TYPE(SPEC_OCLS(etype));
11414 /* if (SPEC_OCLS(etype)->codesp ) { */
11415 /* p_type = CPOINTER ; */
11418 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
11419 /* p_type = FPOINTER ; */
11421 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
11422 /* p_type = PPOINTER ; */
11424 /* if (SPEC_OCLS(etype) == idata ) */
11425 /* p_type = IPOINTER ; */
11427 /* p_type = POINTER ; */
11430 /* now that we have the pointer type we assign
11431 the pointer values */
11436 genNearPointerSet (right,result,ic);
11440 genPagedPointerSet (right,result,ic);
11444 genFarPointerSet (right,result,ic);
11448 genGenPointerSet (right,result,ic);
11452 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
11453 "genPointerSet: illegal pointer type");
11457 /*-----------------------------------------------------------------*/
11458 /* genIfx - generate code for Ifx statement */
11459 /*-----------------------------------------------------------------*/
11460 static void genIfx (iCode *ic, iCode *popIc)
11462 operand *cond = IC_COND(ic);
11465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11467 pic16_aopOp(cond,ic,FALSE);
11469 /* get the value into acc */
11470 if (AOP_TYPE(cond) != AOP_CRY)
11471 pic16_toBoolean(cond);
11474 /* the result is now in the accumulator */
11475 pic16_freeAsmop(cond,NULL,ic,TRUE);
11477 /* if there was something to be popped then do it */
11481 /* if the condition is a bit variable */
11482 if (isbit && IS_ITEMP(cond) &&
11484 genIfxJump(ic,SPIL_LOC(cond)->rname);
11485 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
11488 if (isbit && !IS_ITEMP(cond))
11489 genIfxJump(ic,OP_SYMBOL(cond)->rname);
11491 genIfxJump(ic,"a");
11497 /*-----------------------------------------------------------------*/
11498 /* genAddrOf - generates code for address of */
11499 /*-----------------------------------------------------------------*/
11500 static void genAddrOf (iCode *ic)
11502 operand *result, *left;
11504 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
11505 pCodeOp *pcop0, *pcop1, *pcop2;
11507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11509 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
11511 sym = OP_SYMBOL( IC_LEFT(ic) );
11514 /* get address of symbol on stack */
11515 DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
11517 fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__,
11518 OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack);
11521 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
11522 pic16_popCopyReg(&pic16_pc_fsr2l),
11523 pic16_popGet(AOP(result), 0)));
11524 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
11525 pic16_popCopyReg(&pic16_pc_fsr2h),
11526 pic16_popGet(AOP(result), 1)));
11528 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( OP_SYMBOL( IC_LEFT(ic))->stack ) /*+ _G.stack_lat*/);
11529 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 0));
11531 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 1));
11536 // if(pic16_debug_verbose) {
11537 // fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
11538 // __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
11541 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
11542 size = AOP_SIZE(IC_RESULT(ic));
11545 /* Assume that what we want the address of is in data space
11546 * since there is no stack on the PIC, yet! -- VR */
11548 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11549 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11550 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11553 pic16_emitpcode(POC_MOVLW, pcop0);
11554 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
11555 pic16_emitpcode(POC_MOVLW, pcop1);
11556 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
11557 pic16_emitpcode(POC_MOVLW, pcop2);
11558 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
11561 pic16_emitpcode(POC_MOVLW, pcop0);
11562 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11563 pic16_emitpcode(POC_MOVLW, pcop1);
11564 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
11566 pic16_emitpcode(POC_MOVLW, pcop0);
11567 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11570 pic16_freeAsmop(left, NULL, ic, FALSE);
11572 pic16_freeAsmop(result,NULL,ic,TRUE);
11577 /*-----------------------------------------------------------------*/
11578 /* genFarFarAssign - assignment when both are in far space */
11579 /*-----------------------------------------------------------------*/
11580 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
11582 int size = AOP_SIZE(right);
11585 /* first push the right side on to the stack */
11587 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11589 pic16_emitcode ("push","acc");
11592 pic16_freeAsmop(right,NULL,ic,FALSE);
11593 /* now assign DPTR to result */
11594 pic16_aopOp(result,ic,FALSE);
11595 size = AOP_SIZE(result);
11597 pic16_emitcode ("pop","acc");
11598 pic16_aopPut(AOP(result),"a",--offset);
11600 pic16_freeAsmop(result,NULL,ic,FALSE);
11605 /*-----------------------------------------------------------------*/
11606 /* genAssign - generate code for assignment */
11607 /*-----------------------------------------------------------------*/
11608 static void genAssign (iCode *ic)
11610 operand *result, *right;
11611 int size, offset,know_W;
11612 unsigned long lit = 0L;
11614 result = IC_RESULT(ic);
11615 right = IC_RIGHT(ic) ;
11617 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11619 /* if they are the same */
11620 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
11623 /* reversed order operands are aopOp'ed so that result operand
11624 * is effective in case right is a stack symbol. This maneauver
11625 * allows to use the _G.resDirect flag later */
11626 pic16_aopOp(result,ic,TRUE);
11627 pic16_aopOp(right,ic,FALSE);
11629 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11631 /* if they are the same registers */
11632 if (pic16_sameRegs(AOP(right),AOP(result)))
11635 /* if the result is a bit */
11636 if (AOP_TYPE(result) == AOP_CRY) {
11637 /* if the right size is a literal then
11638 we know what the value is */
11639 if (AOP_TYPE(right) == AOP_LIT) {
11641 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
11642 pic16_popGet(AOP(result),0));
11644 if (((int) operandLitValue(right)))
11645 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11646 AOP(result)->aopu.aop_dir,
11647 AOP(result)->aopu.aop_dir);
11649 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11650 AOP(result)->aopu.aop_dir,
11651 AOP(result)->aopu.aop_dir);
11655 /* the right is also a bit variable */
11656 if (AOP_TYPE(right) == AOP_CRY) {
11657 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11658 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11659 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11661 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11662 AOP(result)->aopu.aop_dir,
11663 AOP(result)->aopu.aop_dir);
11664 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
11665 AOP(right)->aopu.aop_dir,
11666 AOP(right)->aopu.aop_dir);
11667 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11668 AOP(result)->aopu.aop_dir,
11669 AOP(result)->aopu.aop_dir);
11673 /* we need to or */
11674 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11675 pic16_toBoolean(right);
11677 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11678 //pic16_aopPut(AOP(result),"a",0);
11682 /* bit variables done */
11684 size = AOP_SIZE(result);
11687 if(AOP_TYPE(right) == AOP_LIT) {
11688 if(!IS_FLOAT(operandType( right )))
11689 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
11692 unsigned long lit_int;
11696 /* take care if literal is a float */
11697 info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
11698 lit = info.lit_int;
11702 // fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
11703 // sizeof(unsigned long int), sizeof(float));
11705 if(AOP_TYPE(right) != AOP_LIT
11706 && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
11707 && !IS_FUNC(OP_SYM_TYPE(right))
11709 DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
11710 // fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
11712 // set up table pointer
11713 if( (AOP_TYPE(right) == AOP_PCODE)
11714 && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
11715 // || (AOP(right)->aopu.pcop->type == PO_DIR)
11719 // fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
11720 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
11721 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
11722 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
11723 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
11724 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
11725 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
11727 // fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
11728 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
11729 pic16_popCopyReg(&pic16_pc_tblptrl)));
11730 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
11731 pic16_popCopyReg(&pic16_pc_tblptrh)));
11732 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
11733 pic16_popCopyReg(&pic16_pc_tblptru)));
11736 size = min(AOP_SIZE(right), AOP_SIZE(result));
11738 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
11739 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
11740 pic16_popGet(AOP(result),offset)));
11744 if(AOP_SIZE(result) > AOP_SIZE(right)) {
11745 size = AOP_SIZE(result) - AOP_SIZE(right);
11747 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
11757 /* VR - What is this?! */
11758 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
11759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11760 if(aopIdx(AOP(result),0) == 4) {
11762 /* this is a workaround to save value of right into wreg too,
11763 * value of wreg is going to be used later */
11764 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11765 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11766 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11770 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
11776 DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
11777 if(AOP_TYPE(right) == AOP_LIT) {
11779 if(know_W != (lit&0xff))
11780 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
11782 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11784 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11788 } else if (AOP_TYPE(right) == AOP_CRY) {
11789 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11791 // debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
11792 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
11793 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
11795 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
11796 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11797 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11799 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11801 if(!_G.resDirect) /* use this aopForSym feature */
11802 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
11809 pic16_freeAsmop (right,NULL,ic,FALSE);
11810 pic16_freeAsmop (result,NULL,ic,TRUE);
11813 /*-----------------------------------------------------------------*/
11814 /* genJumpTab - generates code for jump table */
11815 /*-----------------------------------------------------------------*/
11816 static void genJumpTab (iCode *ic)
11821 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11823 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
11824 /* get the condition into accumulator */
11825 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
11827 /* multiply by three */
11828 pic16_emitcode("add","a,acc");
11829 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
11831 jtab = newiTempLabel(NULL);
11832 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
11833 pic16_emitcode("jmp","@a+dptr");
11834 pic16_emitcode("","%05d_DS_:",jtab->key+100);
11837 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
11838 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
11840 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
11841 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
11842 pic16_emitpLabel(jtab->key);
11846 pCodeOp *jt_offs = pic16_popGetTempReg(0);
11847 pCodeOp *jt_offs_hi = pic16_popGetTempReg(1);
11848 pCodeOp *jt_label = pic16_popGetLabel (jtab->key);
11849 //fprintf (stderr, "Creating jump table...\n");
11851 // calculate offset into jump table (idx * sizeof (GOTO))
11852 pic16_emitpcode(POC_CLRF , jt_offs_hi);
11853 pic16_emitpcode(POC_RLCFW , pic16_popGet(AOP(IC_JTCOND(ic)),0));
11854 pic16_emitpcode(POC_RLCF , jt_offs_hi);
11855 pic16_emitpcode(POC_RLCFW , pic16_popCopyReg(&pic16_pc_wreg));
11856 pic16_emitpcode(POC_RLCF , jt_offs_hi);
11857 pic16_emitpcode(POC_ANDLW , pic16_popGetLit (0xFC));
11858 pic16_emitpcode(POC_MOVWF , jt_offs);
11860 // prepare PCLATx (set to first entry in jump table)
11861 pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 2, 0));
11862 pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pclatu));
11863 pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 1, 0));
11864 pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pclath));
11865 pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 0, 0));
11867 // set PCLATx to selected entry (new PCL is stored in jt_offs)
11868 pic16_emitpcode(POC_ADDWF , jt_offs);
11869 pic16_emitpcode(POC_MOVFW , jt_offs_hi);
11870 pic16_emitpcode(POC_ADDWFC, pic16_popCopyReg(&pic16_pc_pclath));
11872 pic16_emitpcode(POC_INCF , pic16_popCopyReg(&pic16_pc_pclatu));
11874 // release temporaries and prepare jump into table (new PCL --> WREG)
11875 pic16_emitpcode(POC_MOVFW , jt_offs);
11876 pic16_popReleaseTempReg (jt_offs_hi, 1);
11877 pic16_popReleaseTempReg (jt_offs, 0);
11879 // jump into the table
11880 pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl));
11882 // this goto prevents the next label from being removed...
11883 pic16_emitpcode(POC_GOTO, jt_label);
11884 pic16_emitpLabel(jtab->key);
11887 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
11889 /* now generate the jump labels */
11890 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
11891 jtab = setNextItem(IC_JTLABELS(ic))) {
11892 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
11893 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
11899 /*-----------------------------------------------------------------*/
11900 /* genMixedOperation - gen code for operators between mixed types */
11901 /*-----------------------------------------------------------------*/
11903 TSD - Written for the PIC port - but this unfortunately is buggy.
11904 This routine is good in that it is able to efficiently promote
11905 types to different (larger) sizes. Unfortunately, the temporary
11906 variables that are optimized out by this routine are sometimes
11907 used in other places. So until I know how to really parse the
11908 iCode tree, I'm going to not be using this routine :(.
11910 static int genMixedOperation (iCode *ic)
11913 operand *result = IC_RESULT(ic);
11914 sym_link *ctype = operandType(IC_LEFT(ic));
11915 operand *right = IC_RIGHT(ic);
11921 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
11923 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11929 nextright = IC_RIGHT(nextic);
11930 nextleft = IC_LEFT(nextic);
11931 nextresult = IC_RESULT(nextic);
11933 pic16_aopOp(right,ic,FALSE);
11934 pic16_aopOp(result,ic,FALSE);
11935 pic16_aopOp(nextright, nextic, FALSE);
11936 pic16_aopOp(nextleft, nextic, FALSE);
11937 pic16_aopOp(nextresult, nextic, FALSE);
11939 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
11941 operand *t = right;
11945 pic16_emitcode(";remove right +","");
11947 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
11949 operand *t = right;
11953 pic16_emitcode(";remove left +","");
11957 big = AOP_SIZE(nextleft);
11958 small = AOP_SIZE(nextright);
11960 switch(nextic->op) {
11963 pic16_emitcode(";optimize a +","");
11964 /* if unsigned or not an integral type */
11965 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
11966 pic16_emitcode(";add a bit to something","");
11969 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
11971 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
11972 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
11973 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
11975 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
11983 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11984 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11985 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11988 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11990 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
11991 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
11992 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
11993 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11994 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
11997 pic16_emitcode("rlf","known_zero,w");
12004 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
12005 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
12006 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
12008 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
12018 pic16_freeAsmop(right,NULL,ic,TRUE);
12019 pic16_freeAsmop(result,NULL,ic,TRUE);
12020 pic16_freeAsmop(nextright,NULL,ic,TRUE);
12021 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
12023 nextic->generated = 1;
12030 /*-----------------------------------------------------------------*/
12031 /* genCast - gen code for casting */
12032 /*-----------------------------------------------------------------*/
12033 static void genCast (iCode *ic)
12035 operand *result = IC_RESULT(ic);
12036 sym_link *ctype = operandType(IC_LEFT(ic));
12037 sym_link *rtype = operandType(IC_RIGHT(ic));
12038 operand *right = IC_RIGHT(ic);
12041 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12042 /* if they are equivalent then do nothing */
12043 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
12046 pic16_aopOp(right,ic,FALSE) ;
12047 pic16_aopOp(result,ic,FALSE);
12049 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
12051 /* if the result is a bit */
12052 if (AOP_TYPE(result) == AOP_CRY) {
12054 /* if the right size is a literal then
12055 * we know what the value is */
12056 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12058 if (AOP_TYPE(right) == AOP_LIT) {
12059 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
12060 pic16_popGet(AOP(result),0));
12062 if (((int) operandLitValue(right)))
12063 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
12064 AOP(result)->aopu.aop_dir,
12065 AOP(result)->aopu.aop_dir);
12067 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
12068 AOP(result)->aopu.aop_dir,
12069 AOP(result)->aopu.aop_dir);
12073 /* the right is also a bit variable */
12074 if (AOP_TYPE(right) == AOP_CRY) {
12076 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12078 pic16_emitcode("clrc","");
12079 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
12080 AOP(right)->aopu.aop_dir,
12081 AOP(right)->aopu.aop_dir);
12082 pic16_aopPut(AOP(result),"c",0);
12086 /* we need to or */
12087 if (AOP_TYPE(right) == AOP_REG) {
12088 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
12089 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
12090 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
12092 pic16_toBoolean(right);
12093 pic16_aopPut(AOP(result),"a",0);
12097 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
12100 size = AOP_SIZE(result);
12102 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12104 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
12105 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12106 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
12109 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12114 /* if they are the same size : or less */
12115 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
12117 /* if they are in the same place */
12118 if (pic16_sameRegs(AOP(right),AOP(result)))
12121 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12123 if (IS_PTR_CONST(rtype))
12125 if (IS_CODEPTR(rtype))
12127 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
12130 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
12132 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
12134 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
12137 if(AOP_TYPE(right) == AOP_IMMD) {
12138 pCodeOp *pcop0, *pcop1, *pcop2;
12139 symbol *sym = OP_SYMBOL( right );
12141 size = AOP_SIZE(result);
12143 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12145 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12147 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12150 pic16_emitpcode(POC_MOVLW, pcop0);
12151 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
12152 pic16_emitpcode(POC_MOVLW, pcop1);
12153 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
12154 pic16_emitpcode(POC_MOVLW, pcop2);
12155 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
12158 pic16_emitpcode(POC_MOVLW, pcop0);
12159 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12160 pic16_emitpcode(POC_MOVLW, pcop1);
12161 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12163 pic16_emitpcode(POC_MOVLW, pcop0);
12164 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12168 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12169 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
12170 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12171 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
12172 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12173 if(AOP_SIZE(result) <2)
12174 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
12176 /* if they in different places then copy */
12177 size = AOP_SIZE(result);
12180 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
12181 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12188 /* if the result is of type pointer */
12189 if (IS_PTR(ctype)) {
12191 sym_link *type = operandType(right);
12192 sym_link *etype = getSpec(type);
12194 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
12196 /* pointer to generic pointer */
12197 if (IS_GENPTR(ctype)) {
12201 p_type = DCL_TYPE(type);
12203 /* we have to go by the storage class */
12204 p_type = PTR_TYPE(SPEC_OCLS(etype));
12206 /* if (SPEC_OCLS(etype)->codesp ) */
12207 /* p_type = CPOINTER ; */
12209 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
12210 /* p_type = FPOINTER ; */
12212 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
12213 /* p_type = PPOINTER; */
12215 /* if (SPEC_OCLS(etype) == idata ) */
12216 /* p_type = IPOINTER ; */
12218 /* p_type = POINTER ; */
12221 /* the first two bytes are known */
12222 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
12223 size = GPTRSIZE - 1;
12226 if(offset < AOP_SIZE(right)) {
12227 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
12228 mov2f(AOP(result), AOP(right), offset);
12230 if ((AOP_TYPE(right) == AOP_PCODE) &&
12231 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12232 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
12233 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12236 pic16_aopPut(AOP(result),
12237 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12242 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
12245 /* the last byte depending on type */
12249 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
12250 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
12251 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
12255 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12259 pic16_emitcode(";BUG!? ","%d",__LINE__);
12263 pic16_emitcode(";BUG!? ","%d",__LINE__);
12268 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12272 /* this should never happen */
12273 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12274 "got unknown pointer type");
12277 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
12281 /* just copy the pointers */
12282 size = AOP_SIZE(result);
12285 pic16_aopPut(AOP(result),
12286 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12295 /* so we now know that the size of destination is greater
12296 than the size of the source.
12297 Now, if the next iCode is an operator then we might be
12298 able to optimize the operation without performing a cast.
12300 if(genMixedOperation(ic))
12303 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12305 /* we move to result for the size of source */
12306 size = AOP_SIZE(right);
12309 mov2f(AOP(result), AOP(right), offset);
12313 /* now depending on the sign of the destination */
12314 size = AOP_SIZE(result) - AOP_SIZE(right);
12315 /* if unsigned or not an integral type */
12316 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
12318 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12320 /* we need to extend the sign :( */
12323 /* Save one instruction of casting char to int */
12324 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
12325 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12326 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
12328 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
12331 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12333 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12335 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
12338 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
12343 pic16_freeAsmop(right,NULL,ic,TRUE);
12344 pic16_freeAsmop(result,NULL,ic,TRUE);
12348 /*-----------------------------------------------------------------*/
12349 /* genDjnz - generate decrement & jump if not zero instrucion */
12350 /*-----------------------------------------------------------------*/
12351 static int genDjnz (iCode *ic, iCode *ifx)
12353 symbol *lbl, *lbl1;
12354 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12359 /* if the if condition has a false label
12360 then we cannot save */
12364 /* if the minus is not of the form
12366 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
12367 !IS_OP_LITERAL(IC_RIGHT(ic)))
12370 if (operandLitValue(IC_RIGHT(ic)) != 1)
12373 /* if the size of this greater than one then no
12375 if (getSize(operandType(IC_RESULT(ic))) > 1)
12378 /* otherwise we can save BIG */
12379 lbl = newiTempLabel(NULL);
12380 lbl1= newiTempLabel(NULL);
12382 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12384 if (IS_AOP_PREG(IC_RESULT(ic))) {
12385 pic16_emitcode("dec","%s",
12386 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12387 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12388 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
12392 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
12393 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
12395 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12396 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
12400 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12401 ifx->generated = 1;
12405 /*-----------------------------------------------------------------*/
12406 /* genReceive - generate code for a receive iCode */
12407 /*-----------------------------------------------------------------*/
12408 static void genReceive (iCode *ic)
12410 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12413 fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__,
12414 OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack);
12416 // pic16_DumpOp(__FUNCTION__, IC_RESULT(ic));
12418 if (isOperandInFarSpace(IC_RESULT(ic))
12419 && ( OP_SYMBOL(IC_RESULT(ic))->isspilt
12420 || IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
12422 int size = getSize(operandType(IC_RESULT(ic)));
12423 int offset = pic16_fReturnSizePic - size;
12427 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
12428 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
12432 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
12434 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12435 size = AOP_SIZE(IC_RESULT(ic));
12438 pic16_emitcode ("pop","acc");
12439 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
12442 DEBUGpic16_emitcode ("; ***","2 %s %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
12445 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12447 assignResultValue(IC_RESULT(ic), 0);
12450 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12453 /*-----------------------------------------------------------------*/
12454 /* genDummyRead - generate code for dummy read of volatiles */
12455 /*-----------------------------------------------------------------*/
12457 genDummyRead (iCode * ic)
12459 pic16_emitcode ("; genDummyRead","");
12460 pic16_emitcode ("; not implemented","");
12465 /*-----------------------------------------------------------------*/
12466 /* genpic16Code - generate code for pic16 based controllers */
12467 /*-----------------------------------------------------------------*/
12469 * At this point, ralloc.c has gone through the iCode and attempted
12470 * to optimize in a way suitable for a PIC. Now we've got to generate
12471 * PIC instructions that correspond to the iCode.
12473 * Once the instructions are generated, we'll pass through both the
12474 * peep hole optimizer and the pCode optimizer.
12475 *-----------------------------------------------------------------*/
12477 void genpic16Code (iCode *lic)
12482 lineHead = lineCurr = NULL;
12484 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
12485 pic16_addpBlock(pb);
12488 /* if debug information required */
12489 if (options.debug && currFunc) {
12491 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
12496 for (ic = lic ; ic ; ic = ic->next ) {
12498 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
12499 if ( cln != ic->lineno ) {
12500 if ( options.debug ) {
12501 debugFile->writeCLine (ic);
12504 if(!options.noCcodeInAsm) {
12505 pic16_addpCode2pBlock(pb,
12506 pic16_newpCodeCSource(ic->lineno, ic->filename,
12507 printCLine(ic->filename, ic->lineno)));
12513 if(options.iCodeInAsm) {
12515 /* insert here code to print iCode as comment */
12516 l = Safe_strdup(printILine(ic));
12517 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
12520 /* if the result is marked as
12521 spilt and rematerializable or code for
12522 this has already been generated then
12524 if (resultRemat(ic) || ic->generated )
12527 /* depending on the operation */
12546 /* IPOP happens only when trying to restore a
12547 spilt live range, if there is an ifx statement
12548 following this pop then the if statement might
12549 be using some of the registers being popped which
12550 would destroy the contents of the register so
12551 we need to check for this condition and handle it */
12553 ic->next->op == IFX &&
12554 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
12555 genIfx (ic->next,ic);
12573 genEndFunction (ic);
12589 pic16_genPlus (ic) ;
12593 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
12594 pic16_genMinus (ic);
12610 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
12614 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
12621 /* note these two are xlated by algebraic equivalence
12622 during parsing SDCC.y */
12623 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12624 "got '>=' or '<=' shouldn't have come here");
12628 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
12640 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
12644 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
12648 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
12672 genRightShift (ic);
12675 case GET_VALUE_AT_ADDRESS:
12680 if (POINTER_SET(ic))
12707 addSet(&_G.sendSet,ic);
12708 /* create a reversed list of SEND iCodes */
12709 // addSetHead(&_G.sendSet, ic);
12712 case DUMMY_READ_VOLATILE:
12722 /* now we are ready to call the
12723 peep hole optimizer */
12724 if (!options.nopeep) {
12725 peepHole (&lineHead);
12727 /* now do the actual printing */
12728 printLine (lineHead, codeOutFile);
12731 DFPRINTF((stderr,"printing pBlock\n\n"));
12732 pic16_printpBlock(stdout,pb);