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 true is null");
586 DEBUGpic16_emitcode("; +++","ifx false is non-null");
588 DEBUGpic16_emitcode("; +++","ifx false is null");
592 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset);
596 /*-----------------------------------------------------------------*/
597 /* pointerCode - returns the code for a pointer type */
598 /*-----------------------------------------------------------------*/
599 static int pointerCode (sym_link *etype)
602 return PTR_TYPE(SPEC_OCLS(etype));
607 /*-----------------------------------------------------------------*/
608 /* aopForSym - for a true symbol */
609 /*-----------------------------------------------------------------*/
610 static asmop *aopForSym (iCode *ic, operand *op, bool result)
612 symbol *sym=OP_SYMBOL(op);
614 memmap *space= SPEC_OCLS(sym->etype);
616 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
618 _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
620 // sym = OP_SYMBOL(op);
622 /* if already has one */
624 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
629 /* if symbol was initially placed onStack then we must re-place it
630 * to direct memory, since pic16 does not have a specific stack */
632 fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
637 /* assign depending on the storage class */
638 /* if it is on the stack or indirectly addressable */
639 /* space we need to assign either r0 or r1 to it */
640 if (sym->onStack || sym->iaccess) {
644 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
645 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
647 /* acquire a temporary register -- it is saved in function */
649 sym->aop = aop = newAsmop(AOP_STA);
650 aop->aopu.stk.stk = sym->stack;
651 aop->size = getSize(sym->type);
654 DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
655 pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
656 if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
657 && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
659 for(i=0;i<aop->size;i++)
660 aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
661 _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
663 for(i=0;i<aop->size;i++) {
664 aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
665 _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
669 // fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
672 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
675 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
678 for(i=0;i<aop->size;i++) {
680 /* initialise for stack access via frame pointer */
681 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack + i + _G.stack_lat));
683 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
684 pic16_popCopyReg(&pic16_pc_plusw2), pcop[i]));
688 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
695 /* now assign the address of the variable to
696 the pointer register */
697 if (aop->type != AOP_STK) {
701 pic16_emitcode("push","acc");
703 pic16_emitcode("mov","a,_bp");
704 pic16_emitcode("add","a,#0x%02x",
706 ((char)(sym->stack - _G.nRegsSaved )) :
707 ((char)sym->stack)) & 0xff);
708 pic16_emitcode("mov","%s,a",
709 aop->aopu.aop_ptr->name);
712 pic16_emitcode("pop","acc");
714 pic16_emitcode("mov","%s,#%s",
715 aop->aopu.aop_ptr->name,
717 aop->paged = space->paged;
719 aop->aopu.aop_stk = sym->stack;
727 if (sym->onStack && options.stack10bit)
729 /* It's on the 10 bit stack, which is located in
733 //DEBUGpic16_emitcode(";","%d",__LINE__);
736 pic16_emitcode("push","acc");
738 pic16_emitcode("mov","a,_bp");
739 pic16_emitcode("add","a,#0x%02x",
741 ((char)(sym->stack - _G.nRegsSaved )) :
742 ((char)sym->stack)) & 0xff);
745 pic16_emitcode ("mov","dpx1,#0x40");
746 pic16_emitcode ("mov","dph1,#0x00");
747 pic16_emitcode ("mov","dpl1, a");
751 pic16_emitcode("pop","acc");
753 sym->aop = aop = newAsmop(AOP_DPTR2);
754 aop->size = getSize(sym->type);
760 /* special case for a function */
761 if (IS_FUNC(sym->type)) {
762 sym->aop = aop = newAsmop(AOP_PCODE);
763 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
764 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
765 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
766 PCOI(aop->aopu.pcop)->index = 0;
767 aop->size = FPTRSIZE;
768 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
775 //DEBUGpic16_emitcode(";","%d",__LINE__);
776 /* if in bit space */
777 if (IN_BITSPACE(space)) {
778 sym->aop = aop = newAsmop (AOP_CRY);
779 aop->aopu.aop_dir = sym->rname ;
780 aop->size = getSize(sym->type);
781 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
784 /* if it is in direct space */
785 if (IN_DIRSPACE(space)) {
786 sym->aop = aop = newAsmop (AOP_DIR);
787 aop->aopu.aop_dir = sym->rname ;
788 aop->size = getSize(sym->type);
789 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
790 pic16_allocDirReg( IC_LEFT(ic) );
795 if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
796 sym->aop = aop = newAsmop (AOP_DIR);
797 aop->aopu.aop_dir = sym->rname ;
798 aop->size = getSize(sym->type);
799 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
800 pic16_allocDirReg( IC_LEFT(ic) );
805 /* only remaining is far space */
806 sym->aop = aop = newAsmop(AOP_PCODE);
808 /* change the next if to 1 to revert to good old immediate code */
809 if(IN_CODESPACE(space)) {
810 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
811 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
812 PCOI(aop->aopu.pcop)->index = 0;
814 /* try to allocate via direct register */
815 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
816 // aop->size = getSize( sym->type );
819 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
820 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
823 if(!pic16_allocDirReg (IC_LEFT(ic)))
827 if(IN_DIRSPACE( space ))
829 else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
830 aop->size = FPTRSIZE;
831 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
832 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
833 else if(sym->onStack) {
839 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
841 /* if it is in code space */
842 if (IN_CODESPACE(space))
848 /*-----------------------------------------------------------------*/
849 /* aopForRemat - rematerialzes an object */
850 /*-----------------------------------------------------------------*/
851 static asmop *aopForRemat (operand *op) // x symbol *sym)
853 symbol *sym = OP_SYMBOL(op);
855 iCode *ic = NULL, *oldic;
856 asmop *aop = newAsmop(AOP_PCODE);
862 ic = sym->rematiCode;
864 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
866 if(IS_OP_POINTER(op)) {
867 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
873 // pic16_emitpcomment("ic: %s\n", printILine(ic));
876 val += (int) operandLitValue(IC_RIGHT(ic));
877 } else if (ic->op == '-') {
878 val -= (int) operandLitValue(IC_RIGHT(ic));
882 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
885 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
888 if(!op->isaddr)viaimmd++; else viaimmd=0;
890 /* set the following if to 1 to revert to good old immediate code */
891 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
894 DEBUGpic16_emitcode(";", "%s:%d immediate, size: %d", __FILE__, __LINE__, getSize( sym->type ));
896 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
899 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
901 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
904 PCOI(aop->aopu.pcop)->index = val;
906 aop->size = getSize( sym->type );
908 DEBUGpic16_emitcode(";", "%s:%d dir size: %d", __FILE__, __LINE__, getSize( OP_SYMBOL( IC_LEFT(ic))->type));
910 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
911 getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
913 aop->size = getSize( OP_SYMBOL( IC_LEFT(ic))->type );
917 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
918 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
920 val, IS_PTR_CONST(operandType(op)));
922 val, IS_CODEPTR(operandType(op)));
925 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
927 pic16_allocDirReg (IC_LEFT(ic));
929 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
936 static int aopIdx (asmop *aop, int offset)
941 if(aop->type != AOP_REG)
944 return aop->aopu.aop_reg[offset]->rIdx;
949 /*-----------------------------------------------------------------*/
950 /* regsInCommon - two operands have some registers in common */
951 /*-----------------------------------------------------------------*/
952 static bool regsInCommon (operand *op1, operand *op2)
957 /* if they have registers in common */
958 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
961 sym1 = OP_SYMBOL(op1);
962 sym2 = OP_SYMBOL(op2);
964 if (sym1->nRegs == 0 || sym2->nRegs == 0)
967 for (i = 0 ; i < sym1->nRegs ; i++) {
972 for (j = 0 ; j < sym2->nRegs ;j++ ) {
976 if (sym2->regs[j] == sym1->regs[i])
984 /*-----------------------------------------------------------------*/
985 /* operandsEqu - equivalent */
986 /*-----------------------------------------------------------------*/
987 static bool operandsEqu ( operand *op1, operand *op2)
991 /* if they not symbols */
992 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
995 sym1 = OP_SYMBOL(op1);
996 sym2 = OP_SYMBOL(op2);
998 /* if both are itemps & one is spilt
999 and the other is not then false */
1000 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
1001 sym1->isspilt != sym2->isspilt )
1004 /* if they are the same */
1008 if (sym1->rname[0] && sym2->rname[0]
1009 && strcmp (sym1->rname, sym2->rname) == 0)
1013 /* if left is a tmp & right is not */
1014 if (IS_ITEMP(op1) &&
1017 (sym1->usl.spillLoc == sym2))
1020 if (IS_ITEMP(op2) &&
1024 (sym2->usl.spillLoc == sym1))
1030 /*-----------------------------------------------------------------*/
1031 /* pic16_sameRegs - two asmops have the same registers */
1032 /*-----------------------------------------------------------------*/
1033 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
1040 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
1041 pic16_AopType(aop1->type), pic16_AopType(aop2->type));
1043 if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
1045 if (aop1->type != AOP_REG ||
1046 aop2->type != AOP_REG )
1049 if (aop1->size != aop2->size )
1052 for (i = 0 ; i < aop1->size ; i++ ) {
1053 // if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE;
1055 // if(aop1->aopu.aop_reg[i]->type == AOP_REG)
1056 if (strcmp(aop1->aopu.aop_reg[i]->name, aop2->aopu.aop_reg[i]->name ))
1063 bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
1065 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
1066 pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
1068 if(aop1 == aop2)return TRUE;
1069 if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
1071 if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
1077 /*-----------------------------------------------------------------*/
1078 /* pic16_aopOp - allocates an asmop for an operand : */
1079 /*-----------------------------------------------------------------*/
1080 void pic16_aopOp (operand *op, iCode *ic, bool result)
1089 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
1091 /* if this a literal */
1092 if (IS_OP_LITERAL(op)) {
1093 op->aop = aop = newAsmop(AOP_LIT);
1094 aop->aopu.aop_lit = op->operand.valOperand;
1095 aop->size = getSize(operandType(op));
1100 sym_link *type = operandType(op);
1102 if(IS_PTR_CONST(type))
1104 if(IS_CODEPTR(type))
1106 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1109 /* if already has a asmop then continue */
1113 /* if the underlying symbol has a aop */
1114 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
1115 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
1116 op->aop = OP_SYMBOL(op)->aop;
1120 /* if this is a true symbol */
1121 if (IS_TRUE_SYMOP(op)) {
1122 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
1123 op->aop = aopForSym(ic, op, result);
1127 /* this is a temporary : this has
1133 e) can be a return use only */
1135 sym = OP_SYMBOL(op);
1137 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s, regType = %d", __LINE__, sym->name, sym->regType);
1138 /* if the type is a conditional */
1139 if (sym->regType == REG_CND) {
1140 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
1145 /* if it is spilt then two situations
1147 b) has a spill location */
1148 if (sym->isspilt || sym->nRegs == 0) {
1150 DEBUGpic16_emitcode(";","%d",__LINE__);
1151 /* rematerialize it NOW */
1154 sym->aop = op->aop = aop = aopForRemat (op);
1155 // aop->size = getSize(sym->type);
1156 // DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
1163 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
1164 aop->size = getSize(sym->type);
1165 for ( i = 0 ; i < 1 ; i++ ) {
1166 aop->aopu.aop_str[i] = accUse[i];
1167 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
1169 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
1170 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
1178 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1179 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1180 //pic16_allocDirReg (IC_LEFT(ic));
1181 aop->size = getSize(sym->type);
1186 aop = op->aop = sym->aop = newAsmop(AOP_STR);
1187 aop->size = getSize(sym->type);
1188 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
1189 aop->aopu.aop_str[i] = fReturn[i];
1191 DEBUGpic16_emitcode(";","%d",__LINE__);
1195 /* else spill location */
1196 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
1197 /* force a new aop if sizes differ */
1198 sym->usl.spillLoc->aop = NULL;
1202 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1203 __FUNCTION__,__LINE__,
1204 sym->usl.spillLoc->rname,
1205 sym->rname, sym->usl.spillLoc->offset);
1208 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1209 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1210 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1212 sym->usl.spillLoc->offset, op);
1213 aop->size = getSize(sym->type);
1219 sym_link *type = operandType(op);
1221 if(IS_PTR_CONST(type))
1223 if(IS_CODEPTR(type))
1225 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1228 /* must be in a register */
1229 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1230 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1231 aop->size = sym->nRegs;
1232 for ( i = 0 ; i < sym->nRegs ;i++)
1233 aop->aopu.aop_reg[i] = sym->regs[i];
1236 /*-----------------------------------------------------------------*/
1237 /* pic16_freeAsmop - free up the asmop given to an operand */
1238 /*----------------------------------------------------------------*/
1239 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1256 /* depending on the asmop type only three cases need work AOP_RO
1257 , AOP_R1 && AOP_STK */
1259 switch (aop->type) {
1261 if (_G.fsr0Pushed ) {
1263 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
1264 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
1265 // pic16_emitcode ("pop","ar0");
1269 bitVectUnSetBit(ic->rUsed,IDX_FSR0);
1273 bitVectUnSetBit(ic->rUsed,IDX_FSR2);
1279 pic16_emitcode ("pop","ar0");
1283 bitVectUnSetBit(ic->rUsed,R0_IDX);
1289 pic16_emitcode ("pop","ar1");
1293 bitVectUnSetBit(ic->rUsed,R1_IDX);
1300 /* we must store the result on stack */
1301 if((op == IC_RESULT(ic)) && RESULTONSTA(ic)) {
1302 if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1303 for(i=0;i<aop->size;i++) {
1304 /* initialise for stack access via frame pointer */
1305 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(OP_SYMBOL(IC_RESULT(ic))->stack + i + _G.stack_lat));
1307 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
1308 aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2)));
1311 if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
1315 for(i=0;i<aop->size;i++)
1316 PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
1325 int stk = aop->aopu.aop_stk + aop->size;
1326 bitVectUnSetBit(ic->rUsed,R0_IDX);
1327 bitVectUnSetBit(ic->rUsed,R1_IDX);
1329 getFreePtr(ic,&aop,FALSE);
1331 if (options.stack10bit)
1333 /* I'm not sure what to do here yet... */
1336 "*** Warning: probably generating bad code for "
1337 "10 bit stack mode.\n");
1341 pic16_emitcode ("mov","a,_bp");
1342 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1343 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1345 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1349 pic16_emitcode("pop","acc");
1350 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1352 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1355 pic16_freeAsmop(op,NULL,ic,TRUE);
1357 pic16_emitcode("pop","ar0");
1362 pic16_emitcode("pop","ar1");
1372 /* all other cases just dealloc */
1376 OP_SYMBOL(op)->aop = NULL;
1377 /* if the symbol has a spill */
1379 SPIL_LOC(op)->aop = NULL;
1384 /*-----------------------------------------------------------------*/
1385 /* pic16_aopGet - for fetching value of the aop */
1386 /*-----------------------------------------------------------------*/
1387 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1392 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1394 /* offset is greater than size then zero */
1395 if (offset > (aop->size - 1) &&
1396 aop->type != AOP_LIT)
1399 /* depending on type */
1400 switch (aop->type) {
1404 sprintf(s, "%s", aop->aopu.aop_ptr->name);
1405 rs = Safe_calloc(1, strlen(s)+1);
1410 /* if we need to increment it */
1411 while (offset > aop->coff)
1413 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1417 while (offset < aop->coff)
1419 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1425 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
1426 return (dname ? "acc" : "a");
1428 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
1429 rs = Safe_calloc (1, strlen (s) + 1);
1437 sprintf (s,"%s",aop->aopu.aop_immd);
1440 sprintf(s,"(%s >> %d)",
1445 aop->aopu.aop_immd);
1446 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1447 rs = Safe_calloc(1,strlen(s)+1);
1453 sprintf(s,"(%s + %d)",
1456 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1458 sprintf(s,"%s",aop->aopu.aop_dir);
1459 rs = Safe_calloc(1,strlen(s)+1);
1465 // return aop->aopu.aop_reg[offset]->dname;
1467 return aop->aopu.aop_reg[offset]->name;
1470 //pic16_emitcode(";","%d",__LINE__);
1471 return aop->aopu.aop_dir;
1474 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
1475 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1477 // return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1478 rs = Safe_strdup("WREG");
1482 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1483 rs = Safe_calloc(1,strlen(s)+1);
1488 aop->coff = offset ;
1489 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1492 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1494 return aop->aopu.aop_str[offset];
1498 pCodeOp *pcop = aop->aopu.pcop;
1499 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1501 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1502 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1503 sprintf(s,"%s", pcop->name);
1505 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1508 rs = Safe_calloc(1,strlen(s)+1);
1513 rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
1517 // pCodeOp *pcop = aop->aop
1522 fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type));
1523 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1524 "aopget got unsupported aop->type");
1530 /* lock has the following meaning: When allocating temporary registers
1531 * for stack variables storage, the value of the temporary register is
1532 * saved on stack. Its value is restored at the end. This procedure is
1533 * done via calls to pic16_aopOp and pic16_freeAsmop functions. There is
1534 * a possibility that before a call to pic16_aopOp, a temporary register
1535 * is allocated for a while and it is freed after some time, this will
1536 * mess the stack and values will not be restored properly. So use lock=1
1537 * to allocate temporary registers used internally by the programmer, and
1538 * lock=0 to allocate registers for stack use. lock=1 will emit a warning
1539 * to inform the compiler developer about a possible bug. This is an internal
1540 * feature for developing the compiler -- VR */
1542 int _TempReg_lock = 0;
1543 /*-----------------------------------------------------------------*/
1544 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1545 /*-----------------------------------------------------------------*/
1546 pCodeOp *pic16_popGetTempReg(int lock)
1551 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1553 // werror(W_POSSBUG2, __FILE__, __LINE__);
1556 _TempReg_lock += lock;
1561 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1562 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1563 PCOR(pcop)->r->wasUsed=1;
1564 PCOR(pcop)->r->isFree=0;
1566 /* push value on stack */
1567 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1575 /*-----------------------------------------------------------------*/
1576 /* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */
1577 /* don't save if inside v */
1578 /*-----------------------------------------------------------------*/
1579 pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
1584 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1587 // werror(W_POSSBUG2, __FILE__, __LINE__);
1590 _TempReg_lock += lock;
1595 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1596 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1597 PCOR(pcop)->r->wasUsed=1;
1598 PCOR(pcop)->r->isFree=0;
1600 if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
1601 /* push value on stack */
1602 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1612 /*-----------------------------------------------------------------*/
1613 /* pic16_popReleaseTempReg - create a new temporary pCodeOp */
1614 /*-----------------------------------------------------------------*/
1615 void pic16_popReleaseTempReg(pCodeOp *pcop, int lock)
1617 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1619 _TempReg_lock -= lock;
1621 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1622 PCOR(pcop)->r->isFree = 1;
1623 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1626 /*-----------------------------------------------------------------*/
1627 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1628 /*-----------------------------------------------------------------*/
1629 pCodeOp *pic16_popGetLabel(unsigned int key)
1632 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
1637 return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset);
1640 /*-----------------------------------------------------------------*/
1641 /* pic16_popCopyReg - copy a pcode operator */
1642 /*-----------------------------------------------------------------*/
1643 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1647 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1648 pcor->pcop.type = pc->pcop.type;
1650 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1651 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1653 pcor->pcop.name = NULL;
1656 pcor->rIdx = pc->rIdx;
1659 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1664 /*-----------------------------------------------------------------*/
1665 /* pic16_popGetLit - asm operator to pcode operator conversion */
1666 /*-----------------------------------------------------------------*/
1667 pCodeOp *pic16_popGetLit(int lit)
1669 return pic16_newpCodeOpLit(lit);
1672 /*-----------------------------------------------------------------*/
1673 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1674 /*-----------------------------------------------------------------*/
1675 pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2)
1677 return pic16_newpCodeOpLit2(lit, arg2);
1681 /*-----------------------------------------------------------------*/
1682 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1683 /*-----------------------------------------------------------------*/
1684 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1686 return pic16_newpCodeOpImmd(name, offset,index, 0);
1690 /*-----------------------------------------------------------------*/
1691 /* pic16_popGet - asm operator to pcode operator conversion */
1692 /*-----------------------------------------------------------------*/
1693 pCodeOp *pic16_popGetWithString(char *str)
1699 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1703 pcop = pic16_newpCodeOp(str,PO_STR);
1708 /*-----------------------------------------------------------------*/
1709 /* pic16_popRegFromString - */
1710 /*-----------------------------------------------------------------*/
1711 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op)
1714 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1715 pcop->type = PO_DIR;
1717 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1718 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1723 pcop->name = Safe_calloc(1,strlen(str)+1);
1724 strcpy(pcop->name,str);
1726 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1728 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1730 /* make sure that register doesn't exist,
1731 * and operand isn't NULL
1732 * and symbol isn't in codespace (codespace symbols are handled elsewhere) */
1733 if((PCOR(pcop)->r == NULL)
1735 && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
1736 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1737 // __FUNCTION__, __LINE__, str, size, offset);
1739 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
1740 fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
1743 PCOR(pcop)->instance = offset;
1748 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1752 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1754 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1755 PCOR(pcop)->rIdx = rIdx;
1756 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1758 PCOR(pcop)->r->isFree = 0;
1759 PCOR(pcop)->r->wasUsed = 1;
1761 pcop->type = PCOR(pcop)->r->pc_type;
1766 /*---------------------------------------------------------------------------------*/
1767 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1769 /*---------------------------------------------------------------------------------*/
1770 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1775 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1777 /* comment the following check, so errors to throw up */
1778 // if(!pcop2)return NULL;
1780 temp = pic16_popGet(aop_dst, offset);
1781 pcop2->pcop2 = temp;
1788 /*--------------------------------------------------------------------------------.-*/
1789 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1790 /* VR 030601 , adapted by Hans Dorn */
1791 /*--------------------------------------------------------------------------------.-*/
1792 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1796 pcop2 = (pCodeOpReg2 *)src;
1804 /*---------------------------------------------------------------------------------*/
1805 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1806 /* movff instruction */
1807 /*---------------------------------------------------------------------------------*/
1808 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1813 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1814 pcop2->pcop2 = pic16_popCopyReg(dst);
1816 /* the pCodeOp may be already allocated */
1817 pcop2 = (pCodeOpReg2 *)(src);
1818 pcop2->pcop2 = (pCodeOp *)(dst);
1825 /*-----------------------------------------------------------------*/
1826 /* pic16_popGet - asm operator to pcode operator conversion */
1827 /*-----------------------------------------------------------------*/
1828 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1830 //char *s = buffer ;
1834 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1835 /* offset is greater than
1838 // if (offset > (aop->size - 1) &&
1839 // aop->type != AOP_LIT)
1840 // return NULL; //zero;
1842 /* depending on type */
1843 switch (aop->type) {
1849 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1850 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1857 pcop = Safe_calloc(1, sizeof(pCodeOpReg));
1858 PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
1859 PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
1860 PCOR(pcop)->r->wasUsed = 1;
1861 PCOR(pcop)->r->isFree = 0;
1863 PCOR(pcop)->instance = offset;
1864 pcop->type = PCOR(pcop)->r->pc_type;
1868 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1869 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1872 /* pCodeOp is already allocated from aopForSym */
1873 DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
1874 pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
1880 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1882 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1884 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1886 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1887 PCOR(pcop)->rIdx = rIdx;
1888 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1889 PCOR(pcop)->r->wasUsed=1;
1890 PCOR(pcop)->r->isFree=0;
1892 PCOR(pcop)->instance = offset;
1893 pcop->type = PCOR(pcop)->r->pc_type;
1894 // rs = aop->aopu.aop_reg[offset]->name;
1895 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1899 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1900 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1906 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1907 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
1911 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1913 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1915 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1916 // pcop->type = PO_GPR_REGISTER;
1917 PCOR(pcop)->rIdx = rIdx;
1918 PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
1919 PCOR(pcop)->r->wasUsed=1;
1920 PCOR(pcop)->r->isFree=0;
1922 PCOR(pcop)->instance = offset;
1923 pcop->type = PCOR(pcop)->r->pc_type;
1925 DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s\n", __LINE__, dumpPicOptype(pcop->type));
1926 rs = aop->aopu.aop_reg[offset]->name;
1927 DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs);
1932 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1934 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
1935 PCOR(pcop)->instance = offset;
1936 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1937 //if(PCOR(pcop)->r == NULL)
1938 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1942 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1943 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1946 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1947 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1950 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1951 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1952 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1953 pcop->type = PCOR(pcop)->r->pc_type;
1954 pcop->name = PCOR(pcop)->r->name;
1960 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1962 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1963 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1965 switch( aop->aopu.pcop->type ) {
1966 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1967 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1969 assert( 0 ); /* should never reach here */;
1972 PCOI(pcop)->offset = offset;
1977 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1978 "pic16_popGet got unsupported aop->type");
1981 /*-----------------------------------------------------------------*/
1982 /* pic16_aopPut - puts a string for a aop */
1983 /*-----------------------------------------------------------------*/
1984 void pic16_aopPut (asmop *aop, char *s, int offset)
1991 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1993 if (aop->size && offset > ( aop->size - 1)) {
1994 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1995 "pic16_aopPut got offset > aop->size");
1999 /* will assign value to value */
2000 /* depending on where it is ofcourse */
2001 switch (aop->type) {
2004 sprintf(d,"(%s + %d)",
2005 aop->aopu.aop_dir,offset);
2006 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
2009 sprintf(d,"%s",aop->aopu.aop_dir);
2012 DEBUGpic16_emitcode(";","%d",__LINE__);
2014 pic16_emitcode("movf","%s,w",s);
2015 pic16_emitcode("movwf","%s",d);
2018 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
2019 if(offset >= aop->size) {
2020 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2023 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
2026 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2033 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
2034 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
2037 strcmp(s,"r0") == 0 ||
2038 strcmp(s,"r1") == 0 ||
2039 strcmp(s,"r2") == 0 ||
2040 strcmp(s,"r3") == 0 ||
2041 strcmp(s,"r4") == 0 ||
2042 strcmp(s,"r5") == 0 ||
2043 strcmp(s,"r6") == 0 ||
2044 strcmp(s,"r7") == 0 )
2045 pic16_emitcode("mov","%s,%s ; %d",
2046 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
2050 if(strcmp(s,"W")==0 )
2051 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
2053 pic16_emitcode("movwf","%s",
2054 aop->aopu.aop_reg[offset]->name);
2056 if(strcmp(s,zero)==0) {
2057 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2059 } else if(strcmp(s,"W")==0) {
2060 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
2061 pcop->type = PO_GPR_REGISTER;
2063 PCOR(pcop)->rIdx = -1;
2064 PCOR(pcop)->r = NULL;
2066 DEBUGpic16_emitcode(";","%d",__LINE__);
2067 pcop->name = Safe_strdup(s);
2068 pic16_emitpcode(POC_MOVFW,pcop);
2069 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2070 } else if(strcmp(s,one)==0) {
2071 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
2072 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
2074 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
2082 if (aop->type == AOP_DPTR2)
2088 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2089 "pic16_aopPut writting to code space");
2093 while (offset > aop->coff) {
2095 pic16_emitcode ("inc","dptr");
2098 while (offset < aop->coff) {
2100 pic16_emitcode("lcall","__decdptr");
2105 /* if not in accumulater */
2108 pic16_emitcode ("movx","@dptr,a");
2110 if (aop->type == AOP_DPTR2)
2118 while (offset > aop->coff) {
2120 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
2122 while (offset < aop->coff) {
2124 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
2130 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
2135 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
2137 if (strcmp(s,"r0") == 0 ||
2138 strcmp(s,"r1") == 0 ||
2139 strcmp(s,"r2") == 0 ||
2140 strcmp(s,"r3") == 0 ||
2141 strcmp(s,"r4") == 0 ||
2142 strcmp(s,"r5") == 0 ||
2143 strcmp(s,"r6") == 0 ||
2144 strcmp(s,"r7") == 0 ) {
2146 sprintf(buffer,"a%s",s);
2147 pic16_emitcode("mov","@%s,%s",
2148 aop->aopu.aop_ptr->name,buffer);
2150 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
2155 if (strcmp(s,"a") == 0)
2156 pic16_emitcode("push","acc");
2158 pic16_emitcode("push","%s",s);
2163 /* if bit variable */
2164 if (!aop->aopu.aop_dir) {
2165 pic16_emitcode("clr","a");
2166 pic16_emitcode("rlc","a");
2169 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
2172 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
2175 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2177 lbl = newiTempLabel(NULL);
2179 if (strcmp(s,"a")) {
2182 pic16_emitcode("clr","c");
2183 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
2184 pic16_emitcode("cpl","c");
2185 pic16_emitcode("","%05d_DS_:",lbl->key+100);
2186 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2193 if (strcmp(aop->aopu.aop_str[offset],s))
2194 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
2199 if (!offset && (strcmp(s,"acc") == 0))
2202 if (strcmp(aop->aopu.aop_str[offset],s))
2203 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
2207 fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type);
2208 // werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2209 // "pic16_aopPut got unsupported aop->type");
2215 /*-----------------------------------------------------------------*/
2216 /* mov2w - generate either a MOVLW or MOVFW based operand type */
2217 /*-----------------------------------------------------------------*/
2218 static void mov2w (asmop *aop, int offset)
2220 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
2223 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
2225 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
2228 static void mov2f(asmop *dst, asmop *src, int offset)
2230 if(is_LitAOp(src)) {
2231 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2232 pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
2234 if(pic16_sameRegsOfs(src, dst, offset))return;
2235 pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset),
2236 pic16_popGet(dst, offset)));
2240 static void mov2fp(pCodeOp *dst, asmop *src, int offset)
2242 if(is_LitAOp(src)) {
2243 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2244 pic16_emitpcode(POC_MOVWF, dst);
2246 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(src, offset), dst));
2250 void pic16_testStackOverflow(void)
2252 #define GSTACK_TEST_NAME "__gstack_test"
2254 pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME ));
2259 sym = newSymbol( GSTACK_TEST_NAME , 0 );
2260 strcpy(sym->rname, GSTACK_TEST_NAME);
2261 checkAddSym(&externs, sym);
2266 /* push pcop into stack */
2267 void pic16_pushpCodeOp(pCodeOp *pcop)
2269 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2270 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
2271 if(pic16_options.gstack)
2272 pic16_testStackOverflow();
2276 /* pop pcop from stack */
2277 void pic16_poppCodeOp(pCodeOp *pcop)
2279 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
2280 if(pic16_options.gstack)
2281 pic16_testStackOverflow();
2285 /*-----------------------------------------------------------------*/
2286 /* pushw - pushes wreg to stack */
2287 /*-----------------------------------------------------------------*/
2290 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2291 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2292 if(pic16_options.gstack)
2293 pic16_testStackOverflow();
2297 /*-----------------------------------------------------------------*/
2298 /* pushaop - pushes aop to stack */
2299 /*-----------------------------------------------------------------*/
2300 void pushaop(asmop *aop, int offset)
2302 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2304 if(is_LitAOp(aop)) {
2305 pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
2306 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2308 pic16_emitpcode(POC_MOVFF,
2309 pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg(&pic16_pc_postdec1)));
2312 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
2313 if(pic16_options.gstack)
2314 pic16_testStackOverflow();
2317 /*-----------------------------------------------------------------*/
2318 /* popaop - pops aop from stack */
2319 /*-----------------------------------------------------------------*/
2320 void popaop(asmop *aop, int offset)
2322 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
2323 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
2324 if(pic16_options.gstack)
2325 pic16_testStackOverflow();
2328 void popaopidx(asmop *aop, int offset, int index)
2332 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2334 if(STACK_MODEL_LARGE)ofs++;
2336 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
2337 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
2338 if(pic16_options.gstack)
2339 pic16_testStackOverflow();
2342 /*-----------------------------------------------------------------*/
2343 /* reAdjustPreg - points a register back to where it should */
2344 /*-----------------------------------------------------------------*/
2345 static void reAdjustPreg (asmop *aop)
2349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2351 if ((size = aop->size) <= 1)
2354 switch (aop->type) {
2358 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
2362 if (aop->type == AOP_DPTR2)
2368 pic16_emitcode("lcall","__decdptr");
2371 if (aop->type == AOP_DPTR2)
2383 /*-----------------------------------------------------------------*/
2384 /* opIsGptr: returns non-zero if the passed operand is */
2385 /* a generic pointer type. */
2386 /*-----------------------------------------------------------------*/
2387 static int opIsGptr(operand *op)
2389 sym_link *type = operandType(op);
2391 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2392 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2400 /*-----------------------------------------------------------------*/
2401 /* pic16_getDataSize - get the operand data size */
2402 /*-----------------------------------------------------------------*/
2403 int pic16_getDataSize(operand *op)
2405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2408 return AOP_SIZE(op);
2410 // tsd- in the pic port, the genptr size is 1, so this code here
2411 // fails. ( in the 8051 port, the size was 4).
2414 size = AOP_SIZE(op);
2415 if (size == GPTRSIZE)
2417 sym_link *type = operandType(op);
2418 if (IS_GENPTR(type))
2420 /* generic pointer; arithmetic operations
2421 * should ignore the high byte (pointer type).
2424 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2431 /*-----------------------------------------------------------------*/
2432 /* pic16_outAcc - output Acc */
2433 /*-----------------------------------------------------------------*/
2434 void pic16_outAcc(operand *result)
2437 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2438 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2441 size = pic16_getDataSize(result);
2443 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2446 /* unsigned or positive */
2448 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2453 /*-----------------------------------------------------------------*/
2454 /* pic16_outBitC - output a bit C */
2455 /* Move to result the value of Carry flag -- VR */
2456 /*-----------------------------------------------------------------*/
2457 void pic16_outBitC(operand *result)
2461 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2463 /* if the result is bit */
2464 if (AOP_TYPE(result) == AOP_CRY) {
2465 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2466 pic16_aopPut(AOP(result),"c",0);
2469 i = AOP_SIZE(result);
2471 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2473 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2477 /*-----------------------------------------------------------------*/
2478 /* pic16_outBitOp - output a bit from Op */
2479 /* Move to result the value of set/clr op -- VR */
2480 /*-----------------------------------------------------------------*/
2481 void pic16_outBitOp(operand *result, pCodeOp *pcop)
2485 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2487 /* if the result is bit */
2488 if (AOP_TYPE(result) == AOP_CRY) {
2489 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2490 pic16_aopPut(AOP(result),"c",0);
2493 i = AOP_SIZE(result);
2495 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2497 pic16_emitpcode(POC_RRCF, pcop);
2498 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2502 /*-----------------------------------------------------------------*/
2503 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2504 /*-----------------------------------------------------------------*/
2505 void pic16_toBoolean(operand *oper)
2507 int size = AOP_SIZE(oper) - 1;
2510 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2512 if ( AOP_TYPE(oper) != AOP_ACC) {
2513 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2516 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2521 #if !defined(GEN_Not)
2522 /*-----------------------------------------------------------------*/
2523 /* genNot - generate code for ! operation */
2524 /*-----------------------------------------------------------------*/
2525 static void pic16_genNot (iCode *ic)
2530 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2531 /* assign asmOps to operand & result */
2532 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2533 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2535 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2536 /* if in bit space then a special case */
2537 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2538 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2539 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2540 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2542 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2543 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2544 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2549 size = AOP_SIZE(IC_LEFT(ic));
2551 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2552 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2553 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2556 pic16_toBoolean(IC_LEFT(ic));
2558 tlbl = newiTempLabel(NULL);
2559 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2560 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2561 pic16_outBitC(IC_RESULT(ic));
2564 /* release the aops */
2565 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2566 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2571 #if !defined(GEN_Cpl)
2572 /*-----------------------------------------------------------------*/
2573 /* genCpl - generate code for complement */
2574 /*-----------------------------------------------------------------*/
2575 static void pic16_genCpl (iCode *ic)
2581 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2582 /* assign asmOps to operand & result */
2583 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2584 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2586 /* if both are in bit space then
2588 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2589 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2591 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2592 pic16_emitcode("cpl","c");
2593 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2597 size = AOP_SIZE(IC_RESULT(ic));
2600 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2602 pic16_emitcode("cpl","a");
2603 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2605 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2606 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2608 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2609 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2617 /* release the aops */
2618 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2619 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2623 /*-----------------------------------------------------------------*/
2624 /* genUminusFloat - unary minus for floating points */
2625 /*-----------------------------------------------------------------*/
2626 static void genUminusFloat(operand *op,operand *result)
2628 int size ,offset =0 ;
2630 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2631 /* for this we just need to flip the
2632 first it then copy the rest in place */
2633 size = AOP_SIZE(op);
2636 mov2f(AOP(result), AOP(op), offset);
2640 /* toggle the MSB's highest bit */
2641 pic16_emitpcode(POC_BTG, pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), offset-1), 7));
2644 /*-----------------------------------------------------------------*/
2645 /* genUminus - unary minus code generation */
2646 /*-----------------------------------------------------------------*/
2647 static void genUminus (iCode *ic)
2650 sym_link *optype, *rtype;
2652 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2655 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2656 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2658 /* if both in bit space then special case */
2659 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
2660 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2662 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2663 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2664 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2669 optype = operandType(IC_LEFT(ic));
2670 rtype = operandType(IC_RESULT(ic));
2672 /* if float then do float stuff */
2673 if (IS_FLOAT(optype)) {
2674 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2678 /* otherwise subtract from zero by taking the 2's complement */
2679 size = AOP_SIZE(IC_LEFT(ic));
2681 for(i=0; i<size; i++) {
2682 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2683 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2685 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2686 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2690 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2691 for(i=1; i<size; i++) {
2693 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2697 /* release the aops */
2698 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2699 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2703 /*-----------------------------------------------------------------*/
2704 /* saveRegisters - will look for a call and save the registers */
2705 /*-----------------------------------------------------------------*/
2706 static void saveRegisters(iCode *lic)
2713 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2715 for (ic = lic ; ic ; ic = ic->next)
2716 if (ic->op == CALL || ic->op == PCALL)
2720 fprintf(stderr,"found parameter push with no function call\n");
2724 /* if the registers have been saved already then
2726 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2729 /* find the registers in use at this time
2730 and push them away to safety */
2731 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2735 if (options.useXstack) {
2736 if (bitVectBitValue(rsave,R0_IDX))
2737 pic16_emitcode("mov","b,r0");
2738 pic16_emitcode("mov","r0,%s",spname);
2739 for (i = 0 ; i < pic16_nRegs ; i++) {
2740 if (bitVectBitValue(rsave,i)) {
2742 pic16_emitcode("mov","a,b");
2744 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2745 pic16_emitcode("movx","@r0,a");
2746 pic16_emitcode("inc","r0");
2749 pic16_emitcode("mov","%s,r0",spname);
2750 if (bitVectBitValue(rsave,R0_IDX))
2751 pic16_emitcode("mov","r0,b");
2753 //for (i = 0 ; i < pic16_nRegs ; i++) {
2754 // if (bitVectBitValue(rsave,i))
2755 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2758 dtype = operandType(IC_LEFT(ic));
2759 if (currFunc && dtype &&
2760 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2761 IFFUNC_ISISR(currFunc->type) &&
2764 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2767 /*-----------------------------------------------------------------*/
2768 /* unsaveRegisters - pop the pushed registers */
2769 /*-----------------------------------------------------------------*/
2770 static void unsaveRegisters (iCode *ic)
2775 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2776 /* find the registers in use at this time
2777 and push them away to safety */
2778 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2781 if (options.useXstack) {
2782 pic16_emitcode("mov","r0,%s",spname);
2783 for (i = pic16_nRegs ; i >= 0 ; i--) {
2784 if (bitVectBitValue(rsave,i)) {
2785 pic16_emitcode("dec","r0");
2786 pic16_emitcode("movx","a,@r0");
2788 pic16_emitcode("mov","b,a");
2790 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2794 pic16_emitcode("mov","%s,r0",spname);
2795 if (bitVectBitValue(rsave,R0_IDX))
2796 pic16_emitcode("mov","r0,b");
2798 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2799 // if (bitVectBitValue(rsave,i))
2800 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2807 /*-----------------------------------------------------------------*/
2809 /*-----------------------------------------------------------------*/
2810 static void pushSide(operand * oper, int size)
2813 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2815 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2816 if (AOP_TYPE(oper) != AOP_REG &&
2817 AOP_TYPE(oper) != AOP_DIR &&
2819 pic16_emitcode("mov","a,%s",l);
2820 pic16_emitcode("push","acc");
2822 pic16_emitcode("push","%s",l);
2827 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2829 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2830 pic16_emitpcode(POC_MOVFW, src);
2831 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2833 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2834 src, pic16_popGet(AOP(op), offset)));
2839 /*-----------------------------------------------------------------*/
2840 /* assignResultValue - assign results to oper, rescall==1 is */
2841 /* called from genCall() or genPcall() */
2842 /*-----------------------------------------------------------------*/
2843 static void assignResultValue(operand * oper, int rescall)
2845 int size = AOP_SIZE(oper);
2848 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2849 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2852 /* assign result from a call/pcall function() */
2854 /* function results are stored in a special order,
2855 * see top of file with Function return policy, or manual */
2858 /* 8-bits, result in WREG */
2859 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2862 /* 16-bits, result in PRODL:WREG */
2863 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2867 /* 24-bits, result in PRODH:PRODL:WREG */
2868 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2872 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2873 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2877 /* >32-bits, result on stack, and FSR0 points to beginning.
2878 * Fix stack when done */
2880 // debugf("WARNING: Possible bug when returning more than 4-bytes\n");
2882 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2883 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2885 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2890 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2891 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2892 if(STACK_MODEL_LARGE) {
2894 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2898 int areg = 0; /* matching argument register */
2900 // debugf("_G.useWreg = %d\tGpsuedoStkPtr = %d\n", _G.useWreg, GpsuedoStkPtr);
2901 areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
2904 /* its called from genReceive (probably) -- VR */
2905 if(!GpsuedoStkPtr && _G.useWreg) {
2906 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2908 /* The last byte in the assignment is in W */
2909 if(areg <= GpsuedoStkPtr) {
2911 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
2913 // debugf("receive from WREG\n", 0);
2917 _G.stack_lat = AOP_SIZE(oper)-1;
2922 popaopidx(AOP(oper), offset, GpsuedoStkPtr);
2923 // debugf("receive from STACK\n", 0);
2930 /*-----------------------------------------------------------------*/
2931 /* genIpush - generate code for pushing this gets a little complex */
2932 /*-----------------------------------------------------------------*/
2933 static void genIpush (iCode *ic)
2935 // int size, offset=0;
2937 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2940 pic16_aopOp(IC_LEFT(ic), ic, FALSE );
2942 /* send to stack as normal */
2943 addSet(&_G.sendSet,ic);
2944 // addSetHead(&_G.sendSet,ic);
2945 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2950 int size, offset = 0 ;
2954 /* if this is not a parm push : ie. it is spill push
2955 and spill push is always done on the local stack */
2956 if (!ic->parmPush) {
2958 /* and the item is spilt then do nothing */
2959 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2962 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2963 size = AOP_SIZE(IC_LEFT(ic));
2964 /* push it on the stack */
2966 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2971 pic16_emitcode("push","%s",l);
2976 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2980 /*-----------------------------------------------------------------*/
2981 /* genIpop - recover the registers: can happen only for spilling */
2982 /*-----------------------------------------------------------------*/
2983 static void genIpop (iCode *ic)
2985 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2990 /* if the temp was not pushed then */
2991 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2994 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2995 size = AOP_SIZE(IC_LEFT(ic));
2998 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
3001 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3006 /*-----------------------------------------------------------------*/
3007 /* unsaverbank - restores the resgister bank from stack */
3008 /*-----------------------------------------------------------------*/
3009 static void unsaverbank (int bank,iCode *ic,bool popPsw)
3011 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3017 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3019 if (options.useXstack) {
3021 r = getFreePtr(ic,&aop,FALSE);
3024 pic16_emitcode("mov","%s,_spx",r->name);
3025 pic16_emitcode("movx","a,@%s",r->name);
3026 pic16_emitcode("mov","psw,a");
3027 pic16_emitcode("dec","%s",r->name);
3030 pic16_emitcode ("pop","psw");
3033 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
3034 if (options.useXstack) {
3035 pic16_emitcode("movx","a,@%s",r->name);
3036 //pic16_emitcode("mov","(%s+%d),a",
3037 // regspic16[i].base,8*bank+regspic16[i].offset);
3038 pic16_emitcode("dec","%s",r->name);
3041 pic16_emitcode("pop",""); //"(%s+%d)",
3042 //regspic16[i].base,8*bank); //+regspic16[i].offset);
3045 if (options.useXstack) {
3047 pic16_emitcode("mov","_spx,%s",r->name);
3048 pic16_freeAsmop(NULL,aop,ic,TRUE);
3054 /*-----------------------------------------------------------------*/
3055 /* saverbank - saves an entire register bank on the stack */
3056 /*-----------------------------------------------------------------*/
3057 static void saverbank (int bank, iCode *ic, bool pushPsw)
3059 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3065 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3066 if (options.useXstack) {
3069 r = getFreePtr(ic,&aop,FALSE);
3070 pic16_emitcode("mov","%s,_spx",r->name);
3074 for (i = 0 ; i < pic16_nRegs ;i++) {
3075 if (options.useXstack) {
3076 pic16_emitcode("inc","%s",r->name);
3077 //pic16_emitcode("mov","a,(%s+%d)",
3078 // regspic16[i].base,8*bank+regspic16[i].offset);
3079 pic16_emitcode("movx","@%s,a",r->name);
3081 pic16_emitcode("push","");// "(%s+%d)",
3082 //regspic16[i].base,8*bank+regspic16[i].offset);
3086 if (options.useXstack) {
3087 pic16_emitcode("mov","a,psw");
3088 pic16_emitcode("movx","@%s,a",r->name);
3089 pic16_emitcode("inc","%s",r->name);
3090 pic16_emitcode("mov","_spx,%s",r->name);
3091 pic16_freeAsmop (NULL,aop,ic,TRUE);
3094 pic16_emitcode("push","psw");
3096 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
3104 static int wparamCmp(void *p1, void *p2)
3106 return (!strcmp((char *)p1, (char *)p2));
3109 int inWparamList(char *s)
3111 return isinSetWith(wparamList, s, wparamCmp);
3115 /*-----------------------------------------------------------------*/
3116 /* genCall - generates a call statement */
3117 /*-----------------------------------------------------------------*/
3118 static void genCall (iCode *ic)
3126 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3128 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3129 /* if caller saves & we have not saved then */
3130 // if (!ic->regsSaved)
3131 // saveRegisters(ic);
3133 /* initialise stackParms for IPUSH pushes */
3134 // stackParms = psuedoStkPtr;
3135 // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
3136 fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
3137 inwparam = inWparamList(OP_SYMBOL(IC_LEFT(ic))->name);
3140 gpsimDebug_StackDump(__FILE__, __LINE__, fname );
3143 /* if send set is not empty the assign */
3146 int psuedoStkPtr=-1;
3147 int firstTimeThruLoop = 1;
3150 /* reverse sendSet if function is not reentrant */
3151 if(!IFFUNC_ISREENT(ftype))
3152 _G.sendSet = reverseSet(_G.sendSet);
3154 /* First figure how many parameters are getting passed */
3158 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3162 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3163 size = AOP_SIZE(IC_LEFT(sic));
3167 /* pass the last byte through WREG */
3171 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3172 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3173 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3175 if(!firstTimeThruLoop) {
3176 /* If this is not the first time we've been through the loop
3177 * then we need to save the parameter in a temporary
3178 * register. The last byte of the last parameter is
3182 // --psuedoStkPtr; // sanity check
3186 firstTimeThruLoop=0;
3188 mov2w (AOP(IC_LEFT(sic)), size);
3193 /* all arguments are passed via stack */
3197 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3198 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3199 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3201 // pushaop(AOP(IC_LEFT(sic)), size);
3202 mov2w (AOP(IC_LEFT(sic)), size);
3207 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3211 if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype)) {
3212 pushw(); /* save last parameter to stack if functions has varargs */
3216 } else use_wreg = 0;
3218 _G.stackRegSet = _G.sendSet;
3223 pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
3227 /* if we need to assign a result value */
3228 if ((IS_ITEMP(IC_RESULT(ic))
3229 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3230 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3231 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3234 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3237 assignResultValue(IC_RESULT(ic), 1);
3239 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3240 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3242 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3245 if(!stackParms && ic->parmBytes) {
3246 stackParms = ic->parmBytes;
3249 stackParms -= use_wreg;
3252 if(stackParms == 1) {
3253 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
3255 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3256 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3258 if(STACK_MODEL_LARGE) {
3260 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3265 gpsimDebug_StackDump(__FILE__, __LINE__, fname);
3268 /* adjust the stack for parameters if required */
3269 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3272 /* if register bank was saved then pop them */
3274 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3276 /* if we hade saved some registers then unsave them */
3277 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3278 unsaveRegisters (ic);
3284 /*-----------------------------------------------------------------*/
3285 /* genPcall - generates a call by pointer statement */
3286 /* new version, created from genCall - HJD */
3287 /*-----------------------------------------------------------------*/
3288 static void genPcall (iCode *ic)
3290 sym_link *ftype, *fntype;
3292 symbol *retlbl = newiTempLabel(NULL);
3293 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
3295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3297 ftype = OP_SYM_TYPE(IC_LEFT(ic));
3298 fntype = operandType( IC_LEFT(ic) )->next;
3300 /* if send set is not empty the assign */
3303 int psuedoStkPtr=-1;
3305 /* reverse sendSet if function is not reentrant */
3306 if(!IFFUNC_ISREENT(fntype))
3307 _G.sendSet = reverseSet(_G.sendSet);
3311 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3314 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3315 size = AOP_SIZE(IC_LEFT(sic));
3318 /* all parameters are passed via stack, since WREG is clobbered
3319 * by the calling sequence */
3321 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3322 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3323 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3325 mov2w (AOP(IC_LEFT(sic)), size);
3329 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3332 _G.stackRegSet = _G.sendSet;
3336 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3338 // push return address
3339 // push $ on return stack, then replace with retlbl
3341 pic16_emitpcodeNULLop(POC_PUSH);
3343 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
3344 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
3345 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
3346 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
3347 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
3348 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
3350 /* make the call by writing the pointer into pc */
3351 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
3352 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
3354 // note: MOVFF to PCL not allowed
3355 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
3356 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
3359 /* return address is here: (X) */
3360 pic16_emitpLabelFORCE(retlbl->key);
3362 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3365 /* if we need assign a result value */
3366 if ((IS_ITEMP(IC_RESULT(ic))
3367 && (OP_SYMBOL(IC_RESULT(ic))->nRegs
3368 || OP_SYMBOL(IC_RESULT(ic))->spildir ))
3369 || IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3372 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3375 assignResultValue(IC_RESULT(ic), 1);
3377 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3378 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3380 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3383 // stackParms -= use_wreg;
3386 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3387 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3388 if(STACK_MODEL_LARGE) {
3389 /* this implies that stackParms < 256 !!! -- VR */
3391 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3396 /*-----------------------------------------------------------------*/
3397 /* resultRemat - result is rematerializable */
3398 /*-----------------------------------------------------------------*/
3399 static int resultRemat (iCode *ic)
3401 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3402 if (SKIP_IC(ic) || ic->op == IFX)
3405 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3406 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3407 if (sym->remat && !POINTER_SET(ic))
3414 #if defined(__BORLANDC__) || defined(_MSC_VER)
3415 #define STRCASECMP stricmp
3417 #define STRCASECMP strcasecmp
3421 /*-----------------------------------------------------------------*/
3422 /* inExcludeList - return 1 if the string is in exclude Reg list */
3423 /*-----------------------------------------------------------------*/
3424 static bool inExcludeList(char *s)
3426 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3430 if (options.excludeRegs[i] &&
3431 STRCASECMP(options.excludeRegs[i],"none") == 0)
3434 for ( i = 0 ; options.excludeRegs[i]; i++) {
3435 if (options.excludeRegs[i] &&
3436 STRCASECMP(s,options.excludeRegs[i]) == 0)
3443 /*-----------------------------------------------------------------*/
3444 /* genFunction - generated code for function entry */
3445 /*-----------------------------------------------------------------*/
3446 static void genFunction (iCode *ic)
3451 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
3453 pic16_labelOffset += (max_key+4);
3458 ftype = operandType(IC_LEFT(ic));
3459 sym = OP_SYMBOL(IC_LEFT(ic));
3461 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3462 /* create an absolute section at the interrupt vector:
3463 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3471 sym = OP_SYMBOL( IC_LEFT(ic));
3473 if(interrupts[i]->name
3474 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3481 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3482 __FILE__, __LINE__, sym->name);
3485 _G.interruptvector = found;
3488 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3489 asym = newSymbol(asymname, 0);
3491 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3492 pic16_addpBlock( apb );
3494 pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
3495 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3496 pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3498 /* mark the end of this tiny function */
3499 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3504 abSym = Safe_calloc(1, sizeof(absSym));
3505 strcpy(abSym->name, asymname);
3507 switch( _G.interruptvector ) {
3508 case 0: abSym->address = 0x000000; break;
3509 case 1: abSym->address = 0x000008; break;
3510 case 2: abSym->address = 0x000018; break;
3513 /* relocate interrupt vectors if needed */
3514 abSym->address += pic16_options.ivt_loc;
3516 addSet(&absSymSet, abSym);
3520 /* create the function header */
3521 pic16_emitcode(";","-----------------------------------------");
3522 pic16_emitcode(";"," function %s",sym->name);
3523 pic16_emitcode(";","-----------------------------------------");
3525 pic16_emitcode("","%s:",sym->rname);
3526 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3532 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) {
3533 if(!strcmp(ab->name, sym->rname)) {
3534 pic16_pBlockConvert2Absolute(pb);
3541 if(IFFUNC_ISNAKED(ftype)) {
3542 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3546 /* if critical function then turn interrupts off */
3547 if (IFFUNC_ISCRITICAL(ftype)) {
3548 //pic16_emitcode("clr","ea");
3551 _G.fregsUsed = sym->regsUsed;
3553 /* if this is an interrupt service routine then
3554 * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
3555 if (IFFUNC_ISISR(sym->type)) {
3556 _G.usefastretfie = 1; /* use shadow registers by default */
3558 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3559 if(!(_G.interruptvector == 1)) {
3560 /* do not save WREG,STATUS,BSR for high priority interrupts
3561 * because they are stored in the hardware shadow registers already */
3562 _G.usefastretfie = 0;
3563 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3564 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3565 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3568 /* these should really be optimized somehow, because not all
3569 * interrupt handlers modify them */
3570 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3571 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3572 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3573 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3575 // pic16_pBlockConvert2ISR(pb);
3579 /* emit code to setup stack frame if user enabled,
3580 * and function is not main() */
3582 //fprintf(stderr, "function name: %s\n", sym->name);
3583 if(strcmp(sym->name, "main")) {
3584 if(1 /*!options.ommitFramePtr || sym->regsUsed*/) {
3585 /* setup the stack frame */
3586 if(STACK_MODEL_LARGE)
3587 pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2h));
3588 pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2l));
3589 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3590 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3591 if(STACK_MODEL_LARGE)
3592 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3596 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3599 if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
3601 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3602 pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3604 pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
3607 if(inWparamList(sym->name)) {
3608 if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
3615 /* if callee-save to be used for this function
3616 * then save the registers being used in this function */
3617 // if (IFFUNC_CALLEESAVES(sym->type))
3621 /* if any registers used */
3622 if (sym->regsUsed) {
3623 /* save the registers used */
3624 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3625 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
3626 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3627 if (bitVectBitValue(sym->regsUsed,i)) {
3628 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3631 if(!pic16_regWithIdx(i)->wasUsed) {
3632 fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
3633 __FILE__, __LINE__, pic16_regWithIdx(i)->name);
3634 pic16_regWithIdx(i)->wasUsed = 1;
3638 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END));
3642 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3643 // fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
3646 /*-----------------------------------------------------------------*/
3647 /* genEndFunction - generates epilogue for functions */
3648 /*-----------------------------------------------------------------*/
3649 static void genEndFunction (iCode *ic)
3651 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3653 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3655 if(IFFUNC_ISNAKED(sym->type)) {
3656 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3662 /* add code for ISCRITICAL */
3663 if(IFFUNC_ISCRITICAL(sym->type)) {
3664 /* if critical function, turn on interrupts */
3666 /* TODO: add code here -- VR */
3669 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
3671 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
3672 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
3674 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
3677 // sym->regsUsed = _G.fregsUsed;
3679 /* now we need to restore the registers */
3680 /* if any registers used */
3681 if (sym->regsUsed) {
3684 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN));
3685 /* restore registers used */
3686 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3687 for ( i = sym->regsUsed->size; i >= 0; i--) {
3688 if (bitVectBitValue(sym->regsUsed,i)) {
3689 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3693 pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
3697 if(strcmp(sym->name, "main")) {
3698 if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
3699 /* restore stack frame */
3700 if(STACK_MODEL_LARGE)
3701 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2h ));
3702 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3703 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2l ));
3704 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3710 if (IFFUNC_ISISR(sym->type)) {
3711 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3712 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3713 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3714 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3716 if(!(_G.interruptvector == 1)) {
3717 /* do not restore interrupt vector for WREG,STATUS,BSR
3718 * for high priority interrupt, see genFunction */
3719 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3720 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3721 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3723 _G.interruptvector = 0; /* sanity check */
3726 /* if debug then send end of function */
3727 /* if (options.debug && currFunc) */
3729 debugFile->writeEndFunction (currFunc, ic, 1);
3732 if(_G.usefastretfie)
3733 pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
3735 pic16_emitpcodeNULLop(POC_RETFIE);
3737 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3739 _G.usefastretfie = 0;
3743 if (IFFUNC_ISCRITICAL(sym->type)) {
3744 pic16_emitcode("setb","ea");
3747 /* if debug then send end of function */
3749 debugFile->writeEndFunction (currFunc, ic, 1);
3752 /* insert code to restore stack frame, if user enabled it
3753 * and function is not main() */
3756 pic16_emitpcodeNULLop(POC_RETURN);
3758 /* Mark the end of a function */
3759 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3763 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3766 unsigned long lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
3768 pic16_emitpcode(POC_CLRF, dest);
3770 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
3771 if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
3774 if(dest->type == PO_WREG && (offset == 0)) {
3775 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3778 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
3782 /*-----------------------------------------------------------------*/
3783 /* genRet - generate code for return statement */
3784 /*-----------------------------------------------------------------*/
3785 static void genRet (iCode *ic)
3790 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3791 /* if we have no return value then
3792 * just generate the "ret" */
3797 /* we have something to return then
3798 * move the return value into place */
3799 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3800 size = AOP_SIZE(IC_LEFT(ic));
3804 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3805 // pic16_emitpcode(POC_MOVFF,
3806 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3809 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3810 // pic16_emitpcode(POC_MOVFF,
3811 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3814 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3815 // pic16_emitpcode(POC_MOVFF,
3816 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3819 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3821 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3822 // pic16_emitpcode(POC_MOVFF,
3823 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3826 /* >32-bits, setup stack and FSR0 */
3828 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3829 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3831 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3833 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3838 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3839 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3841 if(STACK_MODEL_LARGE) {
3842 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3843 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3845 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3850 /* old code, left here for reference -- VR */
3854 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3856 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3857 pic16_emitpcomment("push %s",l);
3860 DEBUGpic16_emitcode(";", "%d", __LINE__);
3861 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3862 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3864 if (strcmp(fReturn[offset],l)) {
3865 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3866 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3867 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3869 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3873 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3883 if (strcmp(fReturn[pushed],"a"))
3884 pic16_emitcode("pop",fReturn[pushed]);
3886 pic16_emitcode("pop","acc");
3892 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3895 /* generate a jump to the return label
3896 * if the next is not the return statement */
3897 if (!(ic->next && ic->next->op == LABEL
3898 && IC_LABEL(ic->next) == returnLabel)) {
3900 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3901 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
3905 /*-----------------------------------------------------------------*/
3906 /* genLabel - generates a label */
3907 /*-----------------------------------------------------------------*/
3908 static void genLabel (iCode *ic)
3912 /* special case never generate */
3913 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3914 if (IC_LABEL(ic) == entryLabel)
3917 pic16_emitpLabel(IC_LABEL(ic)->key);
3918 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset));
3921 /*-----------------------------------------------------------------*/
3922 /* genGoto - generates a goto */
3923 /*-----------------------------------------------------------------*/
3925 static void genGoto (iCode *ic)
3927 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3928 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset);
3932 /*-----------------------------------------------------------------*/
3933 /* genMultbits :- multiplication of bits */
3934 /*-----------------------------------------------------------------*/
3935 static void genMultbits (operand *left,
3939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3941 if(!pic16_sameRegs(AOP(result),AOP(right)))
3942 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3944 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3945 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3946 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3951 /*-----------------------------------------------------------------*/
3952 /* genMultOneByte : 8 bit multiplication & division */
3953 /*-----------------------------------------------------------------*/
3954 static void genMultOneByte (operand *left,
3959 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3960 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3961 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3963 /* (if two literals, the value is computed before) */
3964 /* if one literal, literal on the right */
3965 if (AOP_TYPE(left) == AOP_LIT){
3971 /* size is already checked in genMult == 1 */
3972 // size = AOP_SIZE(result);
3974 if (AOP_TYPE(right) == AOP_LIT){
3975 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3976 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3977 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3978 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3980 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3981 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3982 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3983 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3986 pic16_genMult8X8_8 (left, right,result);
3989 /*-----------------------------------------------------------------*/
3990 /* genMultOneWord : 16 bit multiplication */
3991 /*-----------------------------------------------------------------*/
3992 static void genMultOneWord (operand *left,
3997 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3998 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3999 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4001 /* (if two literals, the value is computed before)
4002 * if one literal, literal on the right */
4003 if (AOP_TYPE(left) == AOP_LIT){
4009 /* size is checked already == 2 */
4010 // size = AOP_SIZE(result);
4012 if (AOP_TYPE(right) == AOP_LIT) {
4013 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4014 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4015 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4016 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4018 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4019 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4020 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4021 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4024 pic16_genMult16X16_16(left, right,result);
4027 /*-----------------------------------------------------------------*/
4028 /* genMultOneLong : 32 bit multiplication */
4029 /*-----------------------------------------------------------------*/
4030 static void genMultOneLong (operand *left,
4035 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4036 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4037 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4039 /* (if two literals, the value is computed before)
4040 * if one literal, literal on the right */
4041 if (AOP_TYPE(left) == AOP_LIT){
4047 /* size is checked already == 4 */
4048 // size = AOP_SIZE(result);
4050 if (AOP_TYPE(right) == AOP_LIT) {
4051 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4052 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4053 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4054 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4056 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4057 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4058 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4059 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4062 pic16_genMult32X32_32(left, right,result);
4067 /*-----------------------------------------------------------------*/
4068 /* genMult - generates code for multiplication */
4069 /*-----------------------------------------------------------------*/
4070 static void genMult (iCode *ic)
4072 operand *left = IC_LEFT(ic);
4073 operand *right = IC_RIGHT(ic);
4074 operand *result= IC_RESULT(ic);
4076 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4077 /* assign the amsops */
4078 pic16_aopOp (left,ic,FALSE);
4079 pic16_aopOp (right,ic,FALSE);
4080 pic16_aopOp (result,ic,TRUE);
4082 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4084 /* special cases first *
4086 if (AOP_TYPE(left) == AOP_CRY
4087 && AOP_TYPE(right)== AOP_CRY) {
4088 genMultbits(left,right,result);
4092 /* if both are of size == 1 */
4093 if(AOP_SIZE(left) == 1
4094 && AOP_SIZE(right) == 1) {
4095 genMultOneByte(left,right,result);
4099 /* if both are of size == 2 */
4100 if(AOP_SIZE(left) == 2
4101 && AOP_SIZE(right) == 2) {
4102 genMultOneWord(left, right, result);
4106 /* if both are of size == 4 */
4107 if(AOP_SIZE(left) == 4
4108 && AOP_SIZE(right) == 4) {
4109 genMultOneLong(left, right, result);
4113 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
4116 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
4117 /* should have been converted to function call */
4121 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4122 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4123 pic16_freeAsmop(result,NULL,ic,TRUE);
4126 /*-----------------------------------------------------------------*/
4127 /* genDivbits :- division of bits */
4128 /*-----------------------------------------------------------------*/
4129 static void genDivbits (operand *left,
4136 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4137 /* the result must be bit */
4138 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4139 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4143 pic16_emitcode("div","ab");
4144 pic16_emitcode("rrc","a");
4145 pic16_aopPut(AOP(result),"c",0);
4148 /*-----------------------------------------------------------------*/
4149 /* genDivOneByte : 8 bit division */
4150 /*-----------------------------------------------------------------*/
4151 static void genDivOneByte (operand *left,
4155 sym_link *opetype = operandType(result);
4160 /* result = divident / divisor
4161 * - divident may be a register or a literal,
4162 * - divisor may be a register or a literal,
4163 * so there are 3 cases (literal / literal is optimized
4164 * by the front-end) to handle.
4165 * In addition we must handle signed and unsigned, which
4166 * result in 6 final different cases -- VR */
4168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4169 size = AOP_SIZE(result) - 1;
4171 /* signed or unsigned */
4172 if (SPEC_USIGN(opetype)) {
4173 pCodeOp *pct1, /* count */
4176 symbol *label1, *label2, *label3;;
4179 /* unsigned is easy */
4181 pct1 = pic16_popGetTempReg(1);
4182 pct2 = pic16_popGetTempReg(1);
4183 pct3 = pic16_popGetTempReg(1);
4185 label1 = newiTempLabel(NULL);
4186 label2 = newiTempLabel(NULL);
4187 label3 = newiTempLabel(NULL);
4189 /* the following algorithm is extracted from divuint.c */
4191 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
4192 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
4194 pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
4196 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
4198 pic16_emitpLabel(label1->key);
4201 pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
4205 pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
4209 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
4211 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
4212 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
4214 pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
4215 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
4216 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
4218 pic16_emitpLabel( label3->key );
4219 pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
4220 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
4224 pic16_emitpLabel(label2->key);
4225 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
4226 pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
4227 pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
4229 /* result is in wreg */
4230 if(AOP_TYPE(result) != AOP_ACC)
4231 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
4233 pic16_popReleaseTempReg( pct3, 1);
4234 pic16_popReleaseTempReg( pct2, 1);
4235 pic16_popReleaseTempReg( pct1, 1);
4240 /* signed is a little bit more difficult */
4242 /* save the signs of the operands */
4243 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4245 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4246 pic16_emitcode("push","acc"); /* save it on the stack */
4248 /* now sign adjust for both left & right */
4249 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4251 lbl = newiTempLabel(NULL);
4252 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4253 pic16_emitcode("cpl","a");
4254 pic16_emitcode("inc","a");
4255 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4256 pic16_emitcode("mov","b,a");
4258 /* sign adjust left side */
4259 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4262 lbl = newiTempLabel(NULL);
4263 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4264 pic16_emitcode("cpl","a");
4265 pic16_emitcode("inc","a");
4266 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4268 /* now the division */
4269 pic16_emitcode("div","ab");
4270 /* we are interested in the lower order
4272 pic16_emitcode("mov","b,a");
4273 lbl = newiTempLabel(NULL);
4274 pic16_emitcode("pop","acc");
4275 /* if there was an over flow we don't
4276 adjust the sign of the result */
4277 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4278 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4280 pic16_emitcode("clr","a");
4281 pic16_emitcode("subb","a,b");
4282 pic16_emitcode("mov","b,a");
4283 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4285 /* now we are done */
4286 pic16_aopPut(AOP(result),"b",0);
4288 pic16_emitcode("mov","c,b.7");
4289 pic16_emitcode("subb","a,acc");
4292 pic16_aopPut(AOP(result),"a",offset++);
4296 /*-----------------------------------------------------------------*/
4297 /* genDiv - generates code for division */
4298 /*-----------------------------------------------------------------*/
4299 static void genDiv (iCode *ic)
4301 operand *left = IC_LEFT(ic);
4302 operand *right = IC_RIGHT(ic);
4303 operand *result= IC_RESULT(ic);
4306 /* Division is a very lengthy algorithm, so it is better
4307 * to call support routines than inlining algorithm.
4308 * Division functions written here just in case someone
4309 * wants to inline and not use the support libraries -- VR */
4311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4312 /* assign the amsops */
4313 pic16_aopOp (left,ic,FALSE);
4314 pic16_aopOp (right,ic,FALSE);
4315 pic16_aopOp (result,ic,TRUE);
4317 /* special cases first */
4319 if (AOP_TYPE(left) == AOP_CRY &&
4320 AOP_TYPE(right)== AOP_CRY) {
4321 genDivbits(left,right,result);
4325 /* if both are of size == 1 */
4326 if (AOP_SIZE(left) == 1 &&
4327 AOP_SIZE(right) == 1 ) {
4328 genDivOneByte(left,right,result);
4332 /* should have been converted to function call */
4335 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4336 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4337 pic16_freeAsmop(result,NULL,ic,TRUE);
4340 /*-----------------------------------------------------------------*/
4341 /* genModbits :- modulus of bits */
4342 /*-----------------------------------------------------------------*/
4343 static void genModbits (operand *left,
4350 /* the result must be bit */
4351 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4352 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4356 pic16_emitcode("div","ab");
4357 pic16_emitcode("mov","a,b");
4358 pic16_emitcode("rrc","a");
4359 pic16_aopPut(AOP(result),"c",0);
4362 /*-----------------------------------------------------------------*/
4363 /* genModOneByte : 8 bit modulus */
4364 /*-----------------------------------------------------------------*/
4365 static void genModOneByte (operand *left,
4369 sym_link *opetype = operandType(result);
4373 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4374 /* signed or unsigned */
4375 if (SPEC_USIGN(opetype)) {
4376 /* unsigned is easy */
4377 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4378 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4380 pic16_emitcode("div","ab");
4381 pic16_aopPut(AOP(result),"b",0);
4385 /* signed is a little bit more difficult */
4387 /* save the signs of the operands */
4388 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4391 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4392 pic16_emitcode("push","acc"); /* save it on the stack */
4394 /* now sign adjust for both left & right */
4395 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4398 lbl = newiTempLabel(NULL);
4399 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4400 pic16_emitcode("cpl","a");
4401 pic16_emitcode("inc","a");
4402 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4403 pic16_emitcode("mov","b,a");
4405 /* sign adjust left side */
4406 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4409 lbl = newiTempLabel(NULL);
4410 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4411 pic16_emitcode("cpl","a");
4412 pic16_emitcode("inc","a");
4413 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4415 /* now the multiplication */
4416 pic16_emitcode("div","ab");
4417 /* we are interested in the lower order
4419 lbl = newiTempLabel(NULL);
4420 pic16_emitcode("pop","acc");
4421 /* if there was an over flow we don't
4422 adjust the sign of the result */
4423 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4424 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4426 pic16_emitcode("clr","a");
4427 pic16_emitcode("subb","a,b");
4428 pic16_emitcode("mov","b,a");
4429 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4431 /* now we are done */
4432 pic16_aopPut(AOP(result),"b",0);
4436 /*-----------------------------------------------------------------*/
4437 /* genMod - generates code for division */
4438 /*-----------------------------------------------------------------*/
4439 static void genMod (iCode *ic)
4441 operand *left = IC_LEFT(ic);
4442 operand *right = IC_RIGHT(ic);
4443 operand *result= IC_RESULT(ic);
4445 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4446 /* assign the amsops */
4447 pic16_aopOp (left,ic,FALSE);
4448 pic16_aopOp (right,ic,FALSE);
4449 pic16_aopOp (result,ic,TRUE);
4451 /* special cases first */
4453 if (AOP_TYPE(left) == AOP_CRY &&
4454 AOP_TYPE(right)== AOP_CRY) {
4455 genModbits(left,right,result);
4459 /* if both are of size == 1 */
4460 if (AOP_SIZE(left) == 1 &&
4461 AOP_SIZE(right) == 1 ) {
4462 genModOneByte(left,right,result);
4466 /* should have been converted to function call */
4470 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4472 pic16_freeAsmop(result,NULL,ic,TRUE);
4475 /*-----------------------------------------------------------------*/
4476 /* genIfxJump :- will create a jump depending on the ifx */
4477 /*-----------------------------------------------------------------*/
4479 note: May need to add parameter to indicate when a variable is in bit space.
4481 static void genIfxJump (iCode *ic, char *jval)
4484 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4485 /* if true label then we jump if condition
4487 if ( IC_TRUE(ic) ) {
4489 if(strcmp(jval,"a") == 0)
4491 else if (strcmp(jval,"c") == 0)
4494 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4495 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4498 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4499 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
4503 /* false label is present */
4504 if(strcmp(jval,"a") == 0)
4506 else if (strcmp(jval,"c") == 0)
4509 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4510 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4513 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4514 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
4519 /* mark the icode as generated */
4526 /*-----------------------------------------------------------------*/
4528 /*-----------------------------------------------------------------*/
4529 static void genSkip(iCode *ifx,int status_bit)
4531 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4535 if ( IC_TRUE(ifx) ) {
4536 switch(status_bit) {
4551 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4552 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4556 switch(status_bit) {
4570 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4571 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4578 /*-----------------------------------------------------------------*/
4580 /*-----------------------------------------------------------------*/
4581 static void genSkipc(resolvedIfx *rifx)
4583 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4593 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4594 rifx->generated = 1;
4597 /*-----------------------------------------------------------------*/
4599 /*-----------------------------------------------------------------*/
4600 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4602 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4607 if( (rifx->condition ^ invert_condition) & 1)
4612 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4613 rifx->generated = 1;
4617 /*-----------------------------------------------------------------*/
4619 /*-----------------------------------------------------------------*/
4620 static void genSkipz(iCode *ifx, int condition)
4631 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4633 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4636 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4638 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4643 /*-----------------------------------------------------------------*/
4645 /*-----------------------------------------------------------------*/
4646 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4652 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4654 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4657 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4658 rifx->generated = 1;
4662 /*-----------------------------------------------------------------*/
4663 /* genChkZeroes :- greater or less than comparison */
4664 /* For each byte in a literal that is zero, inclusive or the */
4665 /* the corresponding byte in the operand with W */
4666 /* returns true if any of the bytes are zero */
4667 /*-----------------------------------------------------------------*/
4668 static int genChkZeroes(operand *op, int lit, int size)
4675 i = (lit >> (size*8)) & 0xff;
4679 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4681 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4690 /*-----------------------------------------------------------------*/
4691 /* genCmp :- greater or less than comparison */
4692 /*-----------------------------------------------------------------*/
4696 static void genCmp (operand *left,operand *right,
4697 operand *result, iCode *ifx, int sign)
4699 int size; //, offset = 0 ;
4700 unsigned long lit = 0L,i = 0;
4701 resolvedIfx rFalseIfx;
4702 // resolvedIfx rTrueIfx;
4704 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4707 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4708 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4712 resolveIfx(&rFalseIfx,ifx);
4713 truelbl = newiTempLabel(NULL);
4714 size = max(AOP_SIZE(left),AOP_SIZE(right));
4716 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4720 /* if literal is on the right then swap with left */
4721 if ((AOP_TYPE(right) == AOP_LIT)) {
4722 operand *tmp = right ;
4723 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4724 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4727 lit = (lit - 1) & mask;
4730 rFalseIfx.condition ^= 1;
4733 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4734 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4738 //if(IC_TRUE(ifx) == NULL)
4739 /* if left & right are bit variables */
4740 if (AOP_TYPE(left) == AOP_CRY &&
4741 AOP_TYPE(right) == AOP_CRY ) {
4742 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4743 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4745 /* subtract right from left if at the
4746 end the carry flag is set then we know that
4747 left is greater than right */
4749 symbol *lbl = newiTempLabel(NULL);
4752 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4753 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
4757 if(AOP_TYPE(right) == AOP_LIT) {
4759 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4761 DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
4768 genSkipCond(&rFalseIfx,left,size-1,7);
4770 /* no need to compare to 0...*/
4771 /* NOTE: this is a de-generate compare that most certainly
4772 * creates some dead code. */
4773 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4775 if(ifx) ifx->generated = 1;
4782 //i = (lit >> (size*8)) & 0xff;
4783 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4785 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4787 i = ((0-lit) & 0xff);
4790 /* lit is 0x7f, all signed chars are less than
4791 * this except for 0x7f itself */
4792 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4793 genSkipz2(&rFalseIfx,0);
4795 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4796 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4797 genSkipc(&rFalseIfx);
4802 genSkipz2(&rFalseIfx,1);
4804 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4805 genSkipc(&rFalseIfx);
4809 if(ifx) ifx->generated = 1;
4813 /* chars are out of the way. now do ints and longs */
4816 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4823 genSkipCond(&rFalseIfx,left,size,7);
4824 if(ifx) ifx->generated = 1;
4829 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4831 //rFalseIfx.condition ^= 1;
4832 //genSkipCond(&rFalseIfx,left,size,7);
4833 //rFalseIfx.condition ^= 1;
4835 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4836 if(rFalseIfx.condition)
4837 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4839 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4841 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4842 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4843 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4846 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4848 if(rFalseIfx.condition) {
4850 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4856 genSkipc(&rFalseIfx);
4857 pic16_emitpLabel(truelbl->key);
4858 if(ifx) ifx->generated = 1;
4865 if( (lit & 0xff) == 0) {
4866 /* lower byte is zero */
4867 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4868 i = ((lit >> 8) & 0xff) ^0x80;
4869 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4870 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4871 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4872 genSkipc(&rFalseIfx);
4875 if(ifx) ifx->generated = 1;
4880 /* Special cases for signed longs */
4881 if( (lit & 0xffffff) == 0) {
4882 /* lower byte is zero */
4883 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4884 i = ((lit >> 8*3) & 0xff) ^0x80;
4885 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4886 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4887 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4888 genSkipc(&rFalseIfx);
4891 if(ifx) ifx->generated = 1;
4899 if(lit & (0x80 << (size*8))) {
4900 /* lit is negative */
4901 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4903 //genSkipCond(&rFalseIfx,left,size,7);
4905 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4907 if(rFalseIfx.condition)
4908 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4910 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4914 /* lit is positive */
4915 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4916 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4917 if(rFalseIfx.condition)
4918 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4920 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4925 This works, but is only good for ints.
4926 It also requires a "known zero" register.
4927 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4928 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4929 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4930 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4931 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4932 genSkipc(&rFalseIfx);
4934 pic16_emitpLabel(truelbl->key);
4935 if(ifx) ifx->generated = 1;
4939 /* There are no more special cases, so perform a general compare */
4941 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4942 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4946 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4948 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4950 //rFalseIfx.condition ^= 1;
4951 genSkipc(&rFalseIfx);
4953 pic16_emitpLabel(truelbl->key);
4955 if(ifx) ifx->generated = 1;
4962 /* sign is out of the way. So now do an unsigned compare */
4963 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4966 /* General case - compare to an unsigned literal on the right.*/
4968 i = (lit >> (size*8)) & 0xff;
4969 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4970 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4972 i = (lit >> (size*8)) & 0xff;
4975 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4977 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4979 /* this byte of the lit is zero,
4980 *if it's not the last then OR in the variable */
4982 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4987 pic16_emitpLabel(lbl->key);
4988 // pic16_emitpLabel(truelbl->key);
4989 //if(emitFinalCheck)
4990 genSkipc(&rFalseIfx);
4992 pic16_emitpLabel(truelbl->key);
4994 if(ifx) ifx->generated = 1;
5001 if(AOP_TYPE(left) == AOP_LIT) {
5002 //symbol *lbl = newiTempLabel(NULL);
5004 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
5007 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
5010 if((lit == 0) && (sign == 0)){
5013 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5015 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
5017 genSkipz2(&rFalseIfx,0);
5018 if(ifx) ifx->generated = 1;
5025 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
5026 /* degenerate compare can never be true */
5027 if(rFalseIfx.condition == 0)
5028 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
5030 if(ifx) ifx->generated = 1;
5035 /* signed comparisons to a literal byte */
5037 int lp1 = (lit+1) & 0xff;
5039 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
5042 rFalseIfx.condition ^= 1;
5043 genSkipCond(&rFalseIfx,right,0,7);
5046 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5047 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5048 genSkipz2(&rFalseIfx,1);
5051 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5052 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5053 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5054 rFalseIfx.condition ^= 1;
5055 genSkipc(&rFalseIfx);
5059 /* unsigned comparisons to a literal byte */
5061 switch(lit & 0xff ) {
5063 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5064 genSkipz2(&rFalseIfx,0);
5067 rFalseIfx.condition ^= 1;
5068 genSkipCond(&rFalseIfx,right,0,7);
5072 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5073 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5074 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5075 rFalseIfx.condition ^= 1;
5076 if (AOP_TYPE(result) == AOP_CRY)
5077 genSkipc(&rFalseIfx);
5079 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5080 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5086 if(ifx) ifx->generated = 1;
5087 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5093 /* Size is greater than 1 */
5101 /* this means lit = 0xffffffff, or -1 */
5104 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5105 rFalseIfx.condition ^= 1;
5106 genSkipCond(&rFalseIfx,right,size,7);
5107 if(ifx) ifx->generated = 1;
5109 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5118 if(rFalseIfx.condition) {
5119 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5120 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5123 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5125 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5129 if(rFalseIfx.condition) {
5130 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5131 pic16_emitpLabel(truelbl->key);
5133 rFalseIfx.condition ^= 1;
5134 genSkipCond(&rFalseIfx,right,s,7);
5137 if(ifx) ifx->generated = 1;
5139 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5145 if((size == 1) && (0 == (lp1&0xff))) {
5146 /* lower byte of signed word is zero */
5147 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5148 i = ((lp1 >> 8) & 0xff) ^0x80;
5149 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5150 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5151 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5152 rFalseIfx.condition ^= 1;
5153 genSkipc(&rFalseIfx);
5156 if(ifx) ifx->generated = 1;
5158 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5164 if(lit & (0x80 << (size*8))) {
5165 /* Lit is less than zero */
5166 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5167 //rFalseIfx.condition ^= 1;
5168 //genSkipCond(&rFalseIfx,left,size,7);
5169 //rFalseIfx.condition ^= 1;
5170 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5171 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5173 if(rFalseIfx.condition)
5174 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5176 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5180 /* Lit is greater than or equal to zero */
5181 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5182 //rFalseIfx.condition ^= 1;
5183 //genSkipCond(&rFalseIfx,right,size,7);
5184 //rFalseIfx.condition ^= 1;
5186 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5187 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5189 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5190 if(rFalseIfx.condition)
5191 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5193 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5197 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5198 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5202 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5204 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5206 rFalseIfx.condition ^= 1;
5207 //rFalseIfx.condition = 1;
5208 genSkipc(&rFalseIfx);
5210 pic16_emitpLabel(truelbl->key);
5212 if(ifx) ifx->generated = 1;
5215 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5222 /* compare word or long to an unsigned literal on the right.*/
5227 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5230 break; /* handled above */
5233 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5235 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5236 genSkipz2(&rFalseIfx,0);
5240 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5242 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5245 if(rFalseIfx.condition)
5246 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5248 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5251 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5252 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5254 rFalseIfx.condition ^= 1;
5255 genSkipc(&rFalseIfx);
5258 pic16_emitpLabel(truelbl->key);
5260 if(ifx) ifx->generated = 1;
5262 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5270 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5271 i = (lit >> (size*8)) & 0xff;
5273 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5274 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5277 i = (lit >> (size*8)) & 0xff;
5280 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5282 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5284 /* this byte of the lit is zero,
5285 * if it's not the last then OR in the variable */
5287 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5292 pic16_emitpLabel(lbl->key);
5294 rFalseIfx.condition ^= 1;
5296 genSkipc(&rFalseIfx);
5300 pic16_emitpLabel(truelbl->key);
5301 if(ifx) ifx->generated = 1;
5303 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5309 /* Compare two variables */
5311 DEBUGpic16_emitcode(";sign","%d",sign);
5315 /* Sigh. thus sucks... */
5319 pctemp = pic16_popGetTempReg(1);
5320 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5321 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5322 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5323 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5324 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5325 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5326 pic16_popReleaseTempReg(pctemp, 1);
5328 /* Signed char comparison */
5329 /* Special thanks to Nikolai Golovchenko for this snippet */
5330 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5331 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5332 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5333 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5334 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5335 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5337 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5338 genSkipc(&rFalseIfx);
5340 if(ifx) ifx->generated = 1;
5342 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5350 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5351 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5355 /* The rest of the bytes of a multi-byte compare */
5359 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5362 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5363 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5368 pic16_emitpLabel(lbl->key);
5370 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5371 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5372 (AOP_TYPE(result) == AOP_REG)) {
5373 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5374 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5376 genSkipc(&rFalseIfx);
5378 //genSkipc(&rFalseIfx);
5379 if(ifx) ifx->generated = 1;
5382 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5390 if ((AOP_TYPE(result) != AOP_CRY)
5391 && AOP_SIZE(result)) {
5392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5394 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5396 pic16_outBitC(result);
5398 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5399 /* if the result is used in the next
5400 ifx conditional branch then generate
5401 code a little differently */
5403 genIfxJump (ifx,"c");
5405 pic16_outBitC(result);
5406 /* leave the result in acc */
5411 #else /* old version of genCmp() */ /* } else { */
5413 /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
5414 static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
5415 operand *result, int offset, int invert_op)
5419 /* check condition, > or < ?? */
5420 if(rIfx->condition != 0)invert_op ^= 1;
5422 if(ifx && IC_FALSE(ifx))invert_op ^= 1;
5424 if(!ifx)invert_op ^= 1;
5426 DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
5427 __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
5430 if(!invert_op)return POC_CPFSGT;
5431 else return POC_CPFSLT;
5434 static int compareAopfirstpass=1;
5436 static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl,
5437 operand *oper, int offset, operand *result,
5438 int sign, int invert_op, pCodeOp *pcop, pCodeOp *pcop2,
5444 /* invert if there is a result to be loaded, in order to fit,
5445 * SETC/CLRC sequence */
5446 if(AOP_SIZE(result))invert_op ^= 1;
5448 // if(sign && !offset)invert_op ^= 1;
5450 // if(sign)invert_op ^= 1;
5452 op = selectCompareOp(resIfx, ifx, result, offset, invert_op);
5454 if(AOP_SIZE(result) && compareAopfirstpass) {
5457 pic16_emitpcode(POC_SETF, pcop2);
5462 pic16_emitpcode(POC_CLRF, pcop2);
5468 compareAopfirstpass = 0;
5470 /* there is a bug when comparing operands with size > 1,
5471 * because higher bytes can be equal and test should be performed
5472 * to the next lower byte, current algorithm, considers operands
5473 * inequal in these cases! -- VR 20041107 */
5477 pic16_emitpcode(op, pcop);
5479 pic16_emitpcode(op, pic16_popGet(AOP(oper), offset));
5482 if((!sign || !offset) && AOP_SIZE(result)) {
5485 pic16_emitpcode(POC_CLRF, pcop2);
5490 pic16_emitpcode(POC_SETF, pcop2);
5495 /* don't emit final branch (offset == 0) */
5499 pic16_emitpcode(POC_RRCF, pcop2);
5501 pic16_emitpcode(POC_BNC, pic16_popGetLabel(falselbl->key));
5504 if((ifx && (IC_TRUE(ifx)!=NULL)) || (sign && !offset)) {
5505 DEBUGpic16_emitcode ("; +++","%s: %d: ifx = %p, IC_TRUE(ifx) = %d, sign = %d, offset = %d",
5506 __FUNCTION__, __LINE__, ifx, (ifx&&IC_TRUE(ifx)), sign, offset);
5508 truelbl = newiTempLabel( NULL );
5509 pic16_emitpcode(POC_BRA, pic16_popGetLabel(truelbl->key));
5510 if((!ifx || !IC_TRUE(ifx)) && (sign && !offset))
5511 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
5513 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(resIfx->lbl->key));
5514 pic16_emitpLabel(truelbl->key);
5516 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(resIfx->lbl->key));
5525 static void genCmp (operand *left, operand *right,
5526 operand *result, iCode *ifx, int sign)
5530 resolvedIfx rFalseIfx;
5531 symbol *falselbl, *tlbl;
5533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5534 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5536 resolveIfx(&rFalseIfx, ifx);
5537 size = max(AOP_SIZE(left), AOP_SIZE(right));
5539 /* if left & right are bit variables */
5540 if(AOP_TYPE(left) == AOP_CRY
5541 && AOP_TYPE(right) == AOP_CRY ) {
5543 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5544 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
5546 werror(W_POSSBUG2, __FILE__, __LINE__);
5550 /* if literal is on the right then swap with left */
5551 if((AOP_TYPE(right) == AOP_LIT)) {
5552 operand *tmp = right ;
5553 // unsigned long mask = (0x100 << (8*(size-1))) - 1;
5555 lit = /*(unsigned long)*/floatFromVal(AOP(right)->aopu.aop_lit);
5557 // lit = (lit - 1) & mask;
5560 rFalseIfx.condition ^= 1; /* reverse compare */
5562 if ((AOP_TYPE(left) == AOP_LIT)) {
5563 /* float compares are handled by support functions */
5564 lit = /*(unsigned long)*/floatFromVal(AOP(left)->aopu.aop_lit);
5567 /* actual comparing algorithm */
5568 // size = AOP_SIZE( right );
5570 falselbl = newiTempLabel( NULL );
5571 if(AOP_TYPE(left) == AOP_LIT) {
5572 /* compare to literal */
5573 DEBUGpic16_emitcode ("; ***","%s: %d: compare to literal", __FUNCTION__, __LINE__);
5576 pCodeOp *pct, *pct2;
5579 /* signed compare */
5580 DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
5582 pct = pic16_popCopyReg(&pic16_pc_prodl);
5583 pct2 = pic16_popCopyReg(&pic16_pc_prodh);
5584 tlbl = newiTempLabel( NULL );
5586 /* first compare signs:
5587 * a. if both are positive, compare just like unsigned
5588 * b. if both are negative, invert cmpop, compare just like unsigned
5589 * c. if different signs, determine the result directly */
5595 tlbl1 = newiTempLabel( NULL );
5596 // pic16_emitpcode(POC_RLCFW, pic16_popGet( AOP(right), size)); /* move sign to carry */
5600 /* literal is zero or positive:
5601 * a. if carry is zero, too, continue compare,
5602 * b. if carry is set, then continue depending on cmpop ^ condition:
5603 * 1. '<' return false (literal < variable),
5604 * 2. '>' return true (literal > variable) */
5605 // pic16_emitpcode(POC_BNC, pic16_popGetLabel( tlbl1->key ));
5606 pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
5609 if(cmpop ^ rFalseIfx.condition)pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
5610 else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key ));
5614 /* literal is negative:
5615 * a. if carry is set, too, continue compare,
5616 * b. if carry is zero, then continue depending on cmpop ^ condition:
5617 * 1. '<' return true (literal < variable),
5618 * 2. '>' return false (literal > variable) */
5619 // pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key ));
5620 pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
5622 if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
5623 else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
5628 pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
5630 if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
5631 else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
5636 pic16_emitpLabel( tlbl1->key );
5639 compareAopfirstpass=1;
5640 // pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5641 // pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
5642 // pic16_emitpcode(POC_MOVWF, pct);
5644 // pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
5645 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
5646 // compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
5647 compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
5651 // pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5652 // pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0));
5653 // pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
5654 // pic16_emitpcode(POC_MOVWF, pct);
5656 // pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
5657 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0));
5658 compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
5659 // compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
5660 // compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
5664 if(ifx)ifx->generated = 1;
5666 if(AOP_SIZE(result)) {
5667 pic16_emitpLabel(tlbl->key);
5668 pic16_emitpLabel(falselbl->key);
5669 pic16_outBitOp( result, pct2 );
5671 pic16_emitpLabel(tlbl->key);
5676 /* unsigned compare */
5677 DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
5679 compareAopfirstpass=1;
5682 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
5683 compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
5687 if(ifx)ifx->generated = 1;
5690 if(AOP_SIZE(result)) {
5691 pic16_emitpLabel(falselbl->key);
5692 pic16_outBitC( result );
5697 /* compare registers */
5698 DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
5702 pCodeOp *pct, *pct2;
5704 /* signed compare */
5705 DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
5707 pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */
5708 pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */
5709 tlbl = newiTempLabel( NULL );
5711 compareAopfirstpass=1;
5714 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
5715 // pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5716 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
5717 pic16_emitpcode(POC_MOVWF, pct);
5719 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
5720 // pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5721 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
5723 /* WREG already holds left + 0x80 */
5724 compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
5727 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
5728 // pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5729 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
5730 pic16_emitpcode(POC_MOVWF, pct);
5732 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
5733 // pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5734 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
5736 /* WREG already holds left + 0x80 */
5737 compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
5738 // compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
5741 if(ifx)ifx->generated = 1;
5743 if(AOP_SIZE(result)) {
5744 pic16_emitpLabel(tlbl->key);
5745 pic16_emitpLabel(falselbl->key);
5746 pic16_outBitOp( result, pct2 );
5748 pic16_emitpLabel(tlbl->key);
5752 /* unsigned compare */
5753 DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
5755 compareAopfirstpass=1;
5758 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
5759 compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
5763 if(ifx)ifx->generated = 1;
5764 if(AOP_SIZE(result)) {
5766 pic16_emitpLabel(falselbl->key);
5767 pic16_outBitC( result );
5774 #else /* } else { */
5776 /* new version of genCmp -- VR 20041012 */
5777 static void genCmp (operand *left,operand *right,
5778 operand *result, iCode *ifx, int sign)
5780 int size; //, offset = 0 ;
5781 unsigned long lit = 0L,i = 0;
5782 resolvedIfx rFalseIfx;
5783 int willCheckCarry=0;
5784 // resolvedIfx rTrueIfx;
5786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5790 * subtract right from left if at the end the carry flag is set then we
5791 * know that left is greater than right */
5793 resolveIfx(&rFalseIfx,ifx);
5794 truelbl = newiTempLabel(NULL);
5795 size = max(AOP_SIZE(left),AOP_SIZE(right));
5797 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5799 /* POC_CPFSGT compare f, wreg, skip if f greater than wreg
5800 * POC_CPFSLT compare f, wreg, skip if f less then wreg */
5803 /* if literal is on the right then swap with left */
5804 if ((AOP_TYPE(right) == AOP_LIT)) {
5805 operand *tmp = right ;
5806 unsigned long mask = (0x100 << (8*(size-1))) - 1;
5808 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5810 // lit = (lit - 1) & mask;
5813 rFalseIfx.condition ^= 1; /* reverse compare */
5815 if ((AOP_TYPE(left) == AOP_LIT)) {
5816 /* float compares are handled by support functions */
5817 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
5821 //if(IC_TRUE(ifx) == NULL)
5822 /* if left & right are bit variables */
5823 if (AOP_TYPE(left) == AOP_CRY &&
5824 AOP_TYPE(right) == AOP_CRY ) {
5826 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5827 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
5830 symbol *lbl = newiTempLabel(NULL);
5832 if(AOP_TYPE(left) == AOP_LIT) {
5833 DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
5835 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5837 else willCheckCarry = 0;
5840 if((lit == 0) && (sign == 0)) {
5841 /* unsigned compare to 0 */
5842 DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign);
5845 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5847 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
5849 genSkipz2(&rFalseIfx,0);
5850 if(ifx)ifx->generated = 1;
5857 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
5858 /* degenerate compare can never be true */
5859 if(rFalseIfx.condition == 0)
5860 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
5862 if(ifx) ifx->generated = 1;
5867 /* signed comparisons to a literal byte */
5868 DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
5870 int lp1 = (lit+1) & 0xff;
5872 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1);
5875 rFalseIfx.condition ^= 1;
5876 genSkipCond(&rFalseIfx,right,0,7);
5879 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5880 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5881 genSkipz2(&rFalseIfx,1);
5884 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
5886 if(rFalseIfx.condition)
5887 pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
5889 pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
5891 if(willCheckCarry) {
5892 if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
5893 else { emitSETC; emitCLRC; }
5896 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5899 /* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5900 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5901 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5902 rFalseIfx.condition ^= 1;
5903 genSkipc(&rFalseIfx);
5908 /* unsigned comparisons to a literal byte */
5909 DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
5911 switch(lit & 0xff ) {
5914 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5915 genSkipz2(&rFalseIfx,0);
5918 rFalseIfx.condition ^= 1;
5919 genSkipCond(&rFalseIfx,right,0,7);
5922 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5923 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5924 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5925 rFalseIfx.condition ^= 1;
5926 if (AOP_TYPE(result) == AOP_CRY)
5927 genSkipc(&rFalseIfx);
5929 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5930 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5936 if(ifx) ifx->generated = 1;
5937 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5943 /* Size is greater than 1 */
5951 /* this means lit = 0xffffffff, or -1 */
5954 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5955 rFalseIfx.condition ^= 1;
5956 genSkipCond(&rFalseIfx,right,size,7);
5957 if(ifx) ifx->generated = 1;
5964 if(rFalseIfx.condition) {
5965 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5966 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5969 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5971 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5975 if(rFalseIfx.condition) {
5976 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5977 pic16_emitpLabel(truelbl->key);
5979 rFalseIfx.condition ^= 1;
5980 genSkipCond(&rFalseIfx,right,s,7);
5983 if(ifx) ifx->generated = 1;
5987 if((size == 1) && (0 == (lp1&0xff))) {
5988 /* lower byte of signed word is zero */
5989 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5990 i = ((lp1 >> 8) & 0xff) ^0x80;
5991 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5992 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5993 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5994 rFalseIfx.condition ^= 1;
5995 genSkipc(&rFalseIfx);
5998 if(ifx) ifx->generated = 1;
6002 if(lit & (0x80 << (size*8))) {
6003 /* Lit is less than zero */
6004 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
6005 //rFalseIfx.condition ^= 1;
6006 //genSkipCond(&rFalseIfx,left,size,7);
6007 //rFalseIfx.condition ^= 1;
6008 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
6009 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
6011 if(rFalseIfx.condition)
6012 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
6014 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
6018 /* Lit is greater than or equal to zero */
6019 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
6020 //rFalseIfx.condition ^= 1;
6021 //genSkipCond(&rFalseIfx,right,size,7);
6022 //rFalseIfx.condition ^= 1;
6024 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
6025 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
6027 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
6028 if(rFalseIfx.condition)
6029 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
6031 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
6036 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
6037 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
6041 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
6043 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
6045 rFalseIfx.condition ^= 1;
6046 //rFalseIfx.condition = 1;
6047 genSkipc(&rFalseIfx);
6049 pic16_emitpLabel(truelbl->key);
6051 if(ifx) ifx->generated = 1;
6056 /* compare word or long to an unsigned literal on the right.*/
6061 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
6064 break; /* handled above */
6067 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
6069 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
6070 genSkipz2(&rFalseIfx,0);
6074 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
6076 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
6079 if(rFalseIfx.condition)
6080 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
6082 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
6085 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
6086 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
6088 rFalseIfx.condition ^= 1;
6089 genSkipc(&rFalseIfx);
6092 pic16_emitpLabel(truelbl->key);
6094 if(ifx) ifx->generated = 1;
6100 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
6101 i = (lit >> (size*8)) & 0xff;
6103 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
6104 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
6107 i = (lit >> (size*8)) & 0xff;
6110 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
6112 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
6114 /* this byte of the lit is zero,
6115 * if it's not the last then OR in the variable */
6117 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
6122 pic16_emitpLabel(lbl->key);
6124 rFalseIfx.condition ^= 1;
6126 genSkipc(&rFalseIfx);
6130 pic16_emitpLabel(truelbl->key);
6131 if(ifx) ifx->generated = 1;
6135 /* Compare two variables */
6137 DEBUGpic16_emitcode(";sign","%d",sign);
6141 /* Sigh. thus sucks... */
6145 pctemp = pic16_popGetTempReg(1);
6146 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
6147 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
6148 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
6149 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
6150 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
6151 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
6152 pic16_popReleaseTempReg(pctemp, 1);
6154 /* Signed char comparison */
6155 /* Special thanks to Nikolai Golovchenko for this snippet */
6156 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
6157 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
6158 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
6159 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
6160 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
6161 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
6163 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6164 genSkipc(&rFalseIfx);
6166 if(ifx) ifx->generated = 1;
6172 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
6173 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
6177 /* The rest of the bytes of a multi-byte compare */
6181 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
6184 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
6185 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
6190 pic16_emitpLabel(lbl->key);
6192 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6193 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
6194 (AOP_TYPE(result) == AOP_REG)) {
6195 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
6196 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
6198 genSkipc(&rFalseIfx);
6200 //genSkipc(&rFalseIfx);
6201 if(ifx) ifx->generated = 1;
6208 if ((AOP_TYPE(result) != AOP_CRY)
6209 && AOP_SIZE(result)) {
6210 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6212 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
6214 pic16_outBitC(result);
6216 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6217 /* if the result is used in the next
6218 ifx conditional branch then generate
6219 code a little differently */
6221 genIfxJump (ifx,"c");
6223 pic16_outBitC(result);
6224 /* leave the result in acc */
6235 /*-----------------------------------------------------------------*/
6236 /* genCmpGt :- greater than comparison */
6237 /*-----------------------------------------------------------------*/
6238 static void genCmpGt (iCode *ic, iCode *ifx)
6240 operand *left, *right, *result;
6241 sym_link *letype , *retype;
6244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6246 right= IC_RIGHT(ic);
6247 result = IC_RESULT(ic);
6249 letype = getSpec(operandType(left));
6250 retype =getSpec(operandType(right));
6251 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
6252 /* assign the amsops */
6253 pic16_aopOp (left,ic,FALSE);
6254 pic16_aopOp (right,ic,FALSE);
6255 pic16_aopOp (result,ic,TRUE);
6257 genCmp(right, left, result, ifx, sign);
6259 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6260 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6261 pic16_freeAsmop(result,NULL,ic,TRUE);
6264 /*-----------------------------------------------------------------*/
6265 /* genCmpLt - less than comparisons */
6266 /*-----------------------------------------------------------------*/
6267 static void genCmpLt (iCode *ic, iCode *ifx)
6269 operand *left, *right, *result;
6270 sym_link *letype , *retype;
6273 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6275 right= IC_RIGHT(ic);
6276 result = IC_RESULT(ic);
6278 letype = getSpec(operandType(left));
6279 retype =getSpec(operandType(right));
6280 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
6282 /* assign the amsops */
6283 pic16_aopOp (left,ic,FALSE);
6284 pic16_aopOp (right,ic,FALSE);
6285 pic16_aopOp (result,ic,TRUE);
6287 genCmp(left, right, result, ifx, sign);
6289 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6290 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6291 pic16_freeAsmop(result,NULL,ic,TRUE);
6296 // FIXME reenable literal optimisation when the pic16 port is stable
6298 /*-----------------------------------------------------------------*/
6299 /* genc16bit2lit - compare a 16 bit value to a literal */
6300 /*-----------------------------------------------------------------*/
6301 static void genc16bit2lit(operand *op, int lit, int offset)
6305 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
6306 if( (lit&0xff) == 0)
6311 switch( BYTEofLONG(lit,i)) {
6313 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
6316 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
6319 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
6322 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
6323 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
6328 switch( BYTEofLONG(lit,i)) {
6330 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
6334 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
6338 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
6341 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
6343 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
6352 /*-----------------------------------------------------------------*/
6353 /* gencjneshort - compare and jump if not equal */
6354 /*-----------------------------------------------------------------*/
6355 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
6357 int size = max(AOP_SIZE(left),AOP_SIZE(right));
6359 int res_offset = 0; /* the result may be a different size then left or right */
6360 int res_size = AOP_SIZE(result);
6362 symbol *lbl, *lbl_done;
6364 unsigned long lit = 0L;
6365 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
6367 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6368 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6370 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
6371 resolveIfx(&rIfx,ifx);
6372 lbl = newiTempLabel(NULL);
6373 lbl_done = newiTempLabel(NULL);
6376 /* if the left side is a literal or
6377 if the right is in a pointer register and left
6379 if ((AOP_TYPE(left) == AOP_LIT) ||
6380 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
6385 if(AOP_TYPE(right) == AOP_LIT)
6386 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6388 if ( regsInCommon(left, result) || regsInCommon(right, result) )
6389 preserve_result = 1;
6391 if(result && !preserve_result)
6394 for(i = 0; i < AOP_SIZE(result); i++)
6395 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6399 /* if the right side is a literal then anything goes */
6400 if (AOP_TYPE(right) == AOP_LIT &&
6401 AOP_TYPE(left) != AOP_DIR ) {
6404 genc16bit2lit(left, lit, 0);
6406 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6409 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6412 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6413 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6415 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6419 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6421 if(res_offset < res_size-1)
6429 /* if the right side is in a register or in direct space or
6430 if the left is a pointer register & right is not */
6431 else if (AOP_TYPE(right) == AOP_REG ||
6432 AOP_TYPE(right) == AOP_DIR ||
6433 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
6434 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
6435 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
6436 int lbl_key = lbl->key;
6439 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
6440 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6442 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6443 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
6444 __FUNCTION__,__LINE__);
6448 /* switch(size) { */
6450 /* genc16bit2lit(left, lit, 0); */
6452 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
6457 if((AOP_TYPE(left) == AOP_DIR) &&
6458 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
6460 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6461 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6463 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
6465 switch (lit & 0xff) {
6467 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6470 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6471 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6472 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
6476 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6477 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6478 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6479 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6483 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6484 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6489 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
6492 if(AOP_TYPE(result) == AOP_CRY) {
6493 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6498 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6500 /* fix me. probably need to check result size too */
6501 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
6506 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
6507 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
6514 if(res_offset < res_size-1)
6519 } else if(AOP_TYPE(right) == AOP_REG &&
6520 AOP_TYPE(left) != AOP_DIR){
6523 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6524 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6525 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
6530 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6532 if(res_offset < res_size-1)
6537 /* right is a pointer reg need both a & b */
6539 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
6541 pic16_emitcode("mov","b,%s",l);
6542 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6543 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
6548 if(result && preserve_result)
6551 for(i = 0; i < AOP_SIZE(result); i++)
6552 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6555 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
6557 if(result && preserve_result)
6558 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
6561 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6563 pic16_emitpLabel(lbl->key);
6565 if(result && preserve_result)
6568 for(i = 0; i < AOP_SIZE(result); i++)
6569 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6571 pic16_emitpLabel(lbl_done->key);
6574 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6582 /*-----------------------------------------------------------------*/
6583 /* gencjne - compare and jump if not equal */
6584 /*-----------------------------------------------------------------*/
6585 static void gencjne(operand *left, operand *right, iCode *ifx)
6587 symbol *tlbl = newiTempLabel(NULL);
6589 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6590 gencjneshort(left, right, lbl);
6592 pic16_emitcode("mov","a,%s",one);
6593 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
6594 pic16_emitcode("","%05d_DS_:",lbl->key+100);
6595 pic16_emitcode("clr","a");
6596 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6598 pic16_emitpLabel(lbl->key);
6599 pic16_emitpLabel(tlbl->key);
6605 /*-----------------------------------------------------------------*/
6606 /* is_LitOp - check if operand has to be treated as literal */
6607 /*-----------------------------------------------------------------*/
6608 static bool is_LitOp(operand *op)
6610 return ((AOP_TYPE(op) == AOP_LIT)
6611 || ( (AOP_TYPE(op) == AOP_PCODE)
6612 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
6613 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) )));
6616 /*-----------------------------------------------------------------*/
6617 /* is_LitAOp - check if operand has to be treated as literal */
6618 /*-----------------------------------------------------------------*/
6619 static bool is_LitAOp(asmop *aop)
6621 return ((aop->type == AOP_LIT)
6622 || ( (aop->type == AOP_PCODE)
6623 && ( (aop->aopu.pcop->type == PO_LITERAL)
6624 || (aop->aopu.pcop->type == PO_IMMEDIATE) )));
6629 /*-----------------------------------------------------------------*/
6630 /* genCmpEq - generates code for equal to */
6631 /*-----------------------------------------------------------------*/
6632 static void genCmpEq (iCode *ic, iCode *ifx)
6634 operand *left, *right, *result;
6635 symbol *falselbl = newiTempLabel(NULL);
6636 symbol *donelbl = newiTempLabel(NULL);
6638 int preserve_result = 0;
6639 int generate_result = 0;
6642 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6643 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6644 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6646 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6647 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6649 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
6651 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
6652 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
6656 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
6658 operand *tmp = right ;
6663 if ( regsInCommon(left, result) || regsInCommon(right, result) )
6664 preserve_result = 1;
6666 if(result && AOP_SIZE(result))
6667 generate_result = 1;
6669 if(generate_result && !preserve_result)
6671 for(i = 0; i < AOP_SIZE(result); i++)
6672 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6675 for(i=0; i < AOP_SIZE(left); i++)
6677 if(AOP_TYPE(left) != AOP_ACC)
6680 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
6682 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
6685 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
6687 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
6689 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
6694 if(generate_result && preserve_result)
6696 for(i = 0; i < AOP_SIZE(result); i++)
6697 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6701 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
6703 if(generate_result && preserve_result)
6704 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6706 if(ifx && IC_TRUE(ifx))
6707 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6709 if(ifx && IC_FALSE(ifx))
6710 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
6712 pic16_emitpLabel(falselbl->key);
6716 if(ifx && IC_FALSE(ifx))
6717 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6719 if(generate_result && preserve_result)
6721 for(i = 0; i < AOP_SIZE(result); i++)
6722 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
6725 pic16_emitpLabel(donelbl->key);
6731 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6732 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6733 pic16_freeAsmop(result,NULL,ic,TRUE);
6739 // old version kept for reference
6741 /*-----------------------------------------------------------------*/
6742 /* genCmpEq - generates code for equal to */
6743 /*-----------------------------------------------------------------*/
6744 static void genCmpEq (iCode *ic, iCode *ifx)
6746 operand *left, *right, *result;
6747 unsigned long lit = 0L;
6749 symbol *falselbl = newiTempLabel(NULL);
6752 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6755 DEBUGpic16_emitcode ("; ifx is non-null","");
6757 DEBUGpic16_emitcode ("; ifx is null","");
6759 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6760 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6761 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6763 size = max(AOP_SIZE(left),AOP_SIZE(right));
6765 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6767 /* if literal, literal on the right or
6768 if the right is in a pointer register and left
6770 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
6771 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
6772 operand *tmp = right ;
6778 if(ifx && !AOP_SIZE(result)){
6780 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
6781 /* if they are both bit variables */
6782 if (AOP_TYPE(left) == AOP_CRY &&
6783 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6784 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
6785 if(AOP_TYPE(right) == AOP_LIT){
6786 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6788 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6789 pic16_emitcode("cpl","c");
6790 } else if(lit == 1L) {
6791 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6793 pic16_emitcode("clr","c");
6795 /* AOP_TYPE(right) == AOP_CRY */
6797 symbol *lbl = newiTempLabel(NULL);
6798 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6799 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6800 pic16_emitcode("cpl","c");
6801 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6803 /* if true label then we jump if condition
6805 tlbl = newiTempLabel(NULL);
6806 if ( IC_TRUE(ifx) ) {
6807 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
6808 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
6810 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
6811 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
6813 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6816 /* left and right are both bit variables, result is carry */
6819 resolveIfx(&rIfx,ifx);
6821 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
6822 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
6823 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
6824 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
6829 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
6831 /* They're not both bit variables. Is the right a literal? */
6832 if(AOP_TYPE(right) == AOP_LIT) {
6833 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6838 switch(lit & 0xff) {
6840 if ( IC_TRUE(ifx) ) {
6841 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
6843 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6845 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6846 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6850 if ( IC_TRUE(ifx) ) {
6851 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
6853 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6855 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6856 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6860 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6862 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6867 /* end of size == 1 */
6871 genc16bit2lit(left,lit,offset);
6874 /* end of size == 2 */
6879 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6880 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
6881 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6882 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6885 /* search for patterns that can be optimized */
6887 genc16bit2lit(left,lit,0);
6891 emitSKPZ; // if hi word unequal
6893 emitSKPNZ; // if hi word equal
6895 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
6896 genc16bit2lit(left,lit,2);
6899 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6900 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6904 pic16_emitpLabel(falselbl->key);
6913 } else if(AOP_TYPE(right) == AOP_CRY ) {
6914 /* we know the left is not a bit, but that the right is */
6915 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6916 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
6917 pic16_popGet(AOP(right),offset));
6918 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
6920 /* if the two are equal, then W will be 0 and the Z bit is set
6921 * we could test Z now, or go ahead and check the high order bytes if
6922 * the variable we're comparing is larger than a byte. */
6925 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
6927 if ( IC_TRUE(ifx) ) {
6929 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6930 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6933 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6934 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6938 /* They're both variables that are larger than bits */
6941 tlbl = newiTempLabel(NULL);
6944 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6945 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6947 if ( IC_TRUE(ifx) ) {
6951 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
6953 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
6954 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
6958 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
6961 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6962 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6967 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
6969 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6970 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6974 if(s>1 && IC_TRUE(ifx)) {
6975 pic16_emitpLabel(tlbl->key);
6976 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6980 /* mark the icode as generated */
6985 /* if they are both bit variables */
6986 if (AOP_TYPE(left) == AOP_CRY &&
6987 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6988 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
6989 if(AOP_TYPE(right) == AOP_LIT){
6990 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6992 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6993 pic16_emitcode("cpl","c");
6994 } else if(lit == 1L) {
6995 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6997 pic16_emitcode("clr","c");
6999 /* AOP_TYPE(right) == AOP_CRY */
7001 symbol *lbl = newiTempLabel(NULL);
7002 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7003 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
7004 pic16_emitcode("cpl","c");
7005 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
7008 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
7009 pic16_outBitC(result);
7013 genIfxJump (ifx,"c");
7016 /* if the result is used in an arithmetic operation
7017 then put the result in place */
7018 pic16_outBitC(result);
7021 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
7022 gencjne(left,right,result,ifx);
7025 gencjne(left,right,newiTempLabel(NULL));
7027 if(IC_TRUE(ifx)->key)
7028 gencjne(left,right,IC_TRUE(ifx)->key);
7030 gencjne(left,right,IC_FALSE(ifx)->key);
7034 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
7035 pic16_aopPut(AOP(result),"a",0);
7040 genIfxJump (ifx,"a");
7044 /* if the result is used in an arithmetic operation
7045 then put the result in place */
7047 if (AOP_TYPE(result) != AOP_CRY)
7048 pic16_outAcc(result);
7050 /* leave the result in acc */
7054 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7055 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7056 pic16_freeAsmop(result,NULL,ic,TRUE);
7060 /*-----------------------------------------------------------------*/
7061 /* ifxForOp - returns the icode containing the ifx for operand */
7062 /*-----------------------------------------------------------------*/
7063 static iCode *ifxForOp ( operand *op, iCode *ic )
7065 /* if true symbol then needs to be assigned */
7066 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7067 if (IS_TRUE_SYMOP(op))
7070 /* if this has register type condition and
7071 the next instruction is ifx with the same operand
7072 and live to of the operand is upto the ifx only then */
7074 && ic->next->op == IFX
7075 && IC_COND(ic->next)->key == op->key
7076 && OP_SYMBOL(op)->liveTo <= ic->next->seq
7078 DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
7083 ic->next->op == IFX &&
7084 IC_COND(ic->next)->key == op->key) {
7085 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
7089 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
7091 ic->next->op == IFX)
7092 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
7095 ic->next->op == IFX &&
7096 IC_COND(ic->next)->key == op->key) {
7097 DEBUGpic16_emitcode ("; "," key is okay");
7098 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
7099 OP_SYMBOL(op)->liveTo,
7104 /* the code below is completely untested
7105 * it just allows ulong2fs.c compile -- VR */
7108 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
7109 __FILE__, __FUNCTION__, __LINE__);
7111 /* if this has register type condition and
7112 the next instruction is ifx with the same operand
7113 and live to of the operand is upto the ifx only then */
7115 ic->next->op == IFX &&
7116 IC_COND(ic->next)->key == op->key &&
7117 OP_SYMBOL(op)->liveTo <= ic->next->seq )
7121 ic->next->op == IFX &&
7122 IC_COND(ic->next)->key == op->key) {
7123 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
7127 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
7128 __FILE__, __FUNCTION__, __LINE__);
7130 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
7135 /*-----------------------------------------------------------------*/
7136 /* genAndOp - for && operation */
7137 /*-----------------------------------------------------------------*/
7138 static void genAndOp (iCode *ic)
7140 operand *left,*right, *result;
7143 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7144 /* note here that && operations that are in an
7145 if statement are taken away by backPatchLabels
7146 only those used in arthmetic operations remain */
7147 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
7148 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
7149 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
7151 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7153 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
7154 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
7155 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
7157 /* if both are bit variables */
7158 /* if (AOP_TYPE(left) == AOP_CRY && */
7159 /* AOP_TYPE(right) == AOP_CRY ) { */
7160 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
7161 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
7162 /* pic16_outBitC(result); */
7164 /* tlbl = newiTempLabel(NULL); */
7165 /* pic16_toBoolean(left); */
7166 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
7167 /* pic16_toBoolean(right); */
7168 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
7169 /* pic16_outBitAcc(result); */
7172 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7173 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7174 pic16_freeAsmop(result,NULL,ic,TRUE);
7178 /*-----------------------------------------------------------------*/
7179 /* genOrOp - for || operation */
7180 /*-----------------------------------------------------------------*/
7183 modified this code, but it doesn't appear to ever get called
7186 static void genOrOp (iCode *ic)
7188 operand *left,*right, *result;
7191 /* note here that || operations that are in an
7192 if statement are taken away by backPatchLabels
7193 only those used in arthmetic operations remain */
7194 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7195 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
7196 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
7197 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
7199 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7201 /* if both are bit variables */
7202 if (AOP_TYPE(left) == AOP_CRY &&
7203 AOP_TYPE(right) == AOP_CRY ) {
7204 pic16_emitcode("clrc","");
7205 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
7206 AOP(left)->aopu.aop_dir,
7207 AOP(left)->aopu.aop_dir);
7208 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7209 AOP(right)->aopu.aop_dir,
7210 AOP(right)->aopu.aop_dir);
7211 pic16_emitcode("setc","");
7214 tlbl = newiTempLabel(NULL);
7215 pic16_toBoolean(left);
7217 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
7218 pic16_toBoolean(right);
7219 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
7221 pic16_outBitAcc(result);
7224 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7225 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7226 pic16_freeAsmop(result,NULL,ic,TRUE);
7229 /*-----------------------------------------------------------------*/
7230 /* isLiteralBit - test if lit == 2^n */
7231 /*-----------------------------------------------------------------*/
7232 static int isLiteralBit(unsigned long lit)
7234 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
7235 0x100L,0x200L,0x400L,0x800L,
7236 0x1000L,0x2000L,0x4000L,0x8000L,
7237 0x10000L,0x20000L,0x40000L,0x80000L,
7238 0x100000L,0x200000L,0x400000L,0x800000L,
7239 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
7240 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
7243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7244 for(idx = 0; idx < 32; idx++)
7250 /*-----------------------------------------------------------------*/
7251 /* continueIfTrue - */
7252 /*-----------------------------------------------------------------*/
7253 static void continueIfTrue (iCode *ic)
7255 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7257 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
7261 /*-----------------------------------------------------------------*/
7263 /*-----------------------------------------------------------------*/
7264 static void jumpIfTrue (iCode *ic)
7266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7268 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
7272 /*-----------------------------------------------------------------*/
7273 /* jmpTrueOrFalse - */
7274 /*-----------------------------------------------------------------*/
7275 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
7277 // ugly but optimized by peephole
7278 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7280 symbol *nlbl = newiTempLabel(NULL);
7281 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
7282 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7283 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
7284 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
7287 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
7288 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7293 /*-----------------------------------------------------------------*/
7294 /* genAnd - code for and */
7295 /*-----------------------------------------------------------------*/
7296 static void genAnd (iCode *ic, iCode *ifx)
7298 operand *left, *right, *result;
7300 unsigned long lit = 0L;
7305 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7306 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7307 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7308 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7310 resolveIfx(&rIfx,ifx);
7312 /* if left is a literal & right is not then exchange them */
7313 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7314 AOP_NEEDSACC(left)) {
7315 operand *tmp = right ;
7320 /* if result = right then exchange them */
7321 if(pic16_sameRegs(AOP(result),AOP(right))){
7322 operand *tmp = right ;
7327 /* if right is bit then exchange them */
7328 if (AOP_TYPE(right) == AOP_CRY &&
7329 AOP_TYPE(left) != AOP_CRY){
7330 operand *tmp = right ;
7334 if(AOP_TYPE(right) == AOP_LIT)
7335 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7337 size = AOP_SIZE(result);
7339 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7342 // result = bit & yy;
7343 if (AOP_TYPE(left) == AOP_CRY){
7344 // c = bit & literal;
7345 if(AOP_TYPE(right) == AOP_LIT){
7347 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7350 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7353 if(size && (AOP_TYPE(result) == AOP_CRY)){
7354 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
7357 if((AOP_TYPE(result) == AOP_CRY) && ifx){
7361 pic16_emitcode("clr","c");
7364 if (AOP_TYPE(right) == AOP_CRY){
7366 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
7367 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
7370 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
7372 pic16_emitcode("rrc","a");
7373 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
7379 pic16_outBitC(result);
7381 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7382 genIfxJump(ifx, "c");
7386 // if(val & 0xZZ) - size = 0, ifx != FALSE -
7387 // bit = val & 0xZZ - size = 1, ifx = FALSE -
7388 if((AOP_TYPE(right) == AOP_LIT) &&
7389 (AOP_TYPE(result) == AOP_CRY) &&
7390 (AOP_TYPE(left) != AOP_CRY)){
7391 int posbit = isLiteralBit(lit);
7395 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
7398 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
7404 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7405 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
7407 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7408 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
7411 DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
7412 size = AOP_SIZE(left);
7415 int bp = posbit, ofs=0;
7422 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
7423 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
7427 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
7428 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
7430 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
7437 symbol *tlbl = newiTempLabel(NULL);
7438 int sizel = AOP_SIZE(left);
7444 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
7446 /* patch provided by Aaron Colwell */
7447 if((posbit = isLiteralBit(bytelit)) != 0) {
7448 pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
7449 pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
7450 (posbit-1),0, PO_GPR_REGISTER));
7452 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
7453 // pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7455 if (bytelit == 0xff) {
7456 /* Aaron had a MOVF instruction here, changed to MOVFW cause
7457 * a peephole could optimize it out -- VR */
7458 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7460 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
7461 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
7464 pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
7465 pic16_popGetLabel(tlbl->key));
7469 /* old code, left here for reference -- VR 09/2004 */
7470 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7472 if((posbit = isLiteralBit(bytelit)) != 0)
7473 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
7475 if(bytelit != 0x0FFL)
7476 pic16_emitcode("anl","a,%s",
7477 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
7478 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7484 // bit = left & literal
7487 pic16_emitpLabel(tlbl->key);
7489 // if(left & literal)
7492 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
7493 pic16_emitpLabel(tlbl->key);
7500 pic16_outBitC(result);
7504 /* if left is same as result */
7505 if(pic16_sameRegs(AOP(result),AOP(left))){
7507 for(;size--; offset++,lit>>=8) {
7508 if(AOP_TYPE(right) == AOP_LIT){
7509 switch(lit & 0xff) {
7511 /* and'ing with 0 has clears the result */
7512 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7513 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7516 /* and'ing with 0xff is a nop when the result and left are the same */
7521 int p = my_powof2( (~lit) & 0xff );
7523 /* only one bit is set in the literal, so use a bcf instruction */
7524 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
7525 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7528 pic16_emitcode("movlw","0x%x", (lit & 0xff));
7529 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7530 if(know_W != (lit&0xff))
7531 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7533 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7538 if (AOP_TYPE(left) == AOP_ACC) {
7539 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7541 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7542 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
7549 // left & result in different registers
7550 if(AOP_TYPE(result) == AOP_CRY){
7552 // if(size), result in bit
7553 // if(!size && ifx), conditional oper: if(left & right)
7554 symbol *tlbl = newiTempLabel(NULL);
7555 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
7557 pic16_emitcode("setb","c");
7559 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7560 pic16_emitcode("anl","a,%s",
7561 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7562 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7567 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7568 pic16_outBitC(result);
7570 jmpTrueOrFalse(ifx, tlbl);
7572 for(;(size--);offset++) {
7574 // result = left & right
7575 if(AOP_TYPE(right) == AOP_LIT){
7576 int t = (lit >> (offset*8)) & 0x0FFL;
7579 pic16_emitcode("clrf","%s",
7580 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7581 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
7584 pic16_emitcode("movf","%s,w",
7585 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7586 pic16_emitcode("movwf","%s",
7587 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7588 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7589 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7592 pic16_emitcode("movlw","0x%x",t);
7593 pic16_emitcode("andwf","%s,w",
7594 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7595 pic16_emitcode("movwf","%s",
7596 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7598 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7599 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7600 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7605 if (AOP_TYPE(left) == AOP_ACC) {
7606 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7607 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
7609 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7610 pic16_emitcode("andwf","%s,w",
7611 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7612 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7613 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
7615 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7616 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7622 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7623 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7624 pic16_freeAsmop(result,NULL,ic,TRUE);
7627 /*-----------------------------------------------------------------*/
7628 /* genOr - code for or */
7629 /*-----------------------------------------------------------------*/
7630 static void genOr (iCode *ic, iCode *ifx)
7632 operand *left, *right, *result;
7634 unsigned long lit = 0L;
7636 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7638 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7639 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7640 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7642 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7644 /* if left is a literal & right is not then exchange them */
7645 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7646 AOP_NEEDSACC(left)) {
7647 operand *tmp = right ;
7652 /* if result = right then exchange them */
7653 if(pic16_sameRegs(AOP(result),AOP(right))){
7654 operand *tmp = right ;
7659 /* if right is bit then exchange them */
7660 if (AOP_TYPE(right) == AOP_CRY &&
7661 AOP_TYPE(left) != AOP_CRY){
7662 operand *tmp = right ;
7667 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
7669 if(AOP_TYPE(right) == AOP_LIT)
7670 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7672 size = AOP_SIZE(result);
7676 if (AOP_TYPE(left) == AOP_CRY){
7677 if(AOP_TYPE(right) == AOP_LIT){
7678 // c = bit & literal;
7680 // lit != 0 => result = 1
7681 if(AOP_TYPE(result) == AOP_CRY){
7683 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7684 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7685 // AOP(result)->aopu.aop_dir,
7686 // AOP(result)->aopu.aop_dir);
7688 continueIfTrue(ifx);
7692 // lit == 0 => result = left
7693 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7695 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
7698 if (AOP_TYPE(right) == AOP_CRY){
7699 if(pic16_sameRegs(AOP(result),AOP(left))){
7701 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7702 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
7703 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7705 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7706 AOP(result)->aopu.aop_dir,
7707 AOP(result)->aopu.aop_dir);
7708 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7709 AOP(right)->aopu.aop_dir,
7710 AOP(right)->aopu.aop_dir);
7711 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7712 AOP(result)->aopu.aop_dir,
7713 AOP(result)->aopu.aop_dir);
7715 if( AOP_TYPE(result) == AOP_ACC) {
7716 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7717 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7718 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
7723 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7724 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
7725 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7726 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7728 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
7729 AOP(result)->aopu.aop_dir,
7730 AOP(result)->aopu.aop_dir);
7731 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
7732 AOP(right)->aopu.aop_dir,
7733 AOP(right)->aopu.aop_dir);
7734 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
7735 AOP(left)->aopu.aop_dir,
7736 AOP(left)->aopu.aop_dir);
7737 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
7738 AOP(result)->aopu.aop_dir,
7739 AOP(result)->aopu.aop_dir);
7744 symbol *tlbl = newiTempLabel(NULL);
7745 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7748 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
7749 if( AOP_TYPE(right) == AOP_ACC) {
7750 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
7752 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
7753 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
7758 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
7759 pic16_emitcode(";XXX setb","c");
7760 pic16_emitcode(";XXX jb","%s,%05d_DS_",
7761 AOP(left)->aopu.aop_dir,tlbl->key+100);
7762 pic16_toBoolean(right);
7763 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7764 if((AOP_TYPE(result) == AOP_CRY) && ifx){
7765 jmpTrueOrFalse(ifx, tlbl);
7769 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7776 pic16_outBitC(result);
7778 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7779 genIfxJump(ifx, "c");
7783 // if(val | 0xZZ) - size = 0, ifx != FALSE -
7784 // bit = val | 0xZZ - size = 1, ifx = FALSE -
7785 if((AOP_TYPE(right) == AOP_LIT) &&
7786 (AOP_TYPE(result) == AOP_CRY) &&
7787 (AOP_TYPE(left) != AOP_CRY)){
7789 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7792 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
7794 continueIfTrue(ifx);
7797 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7798 // lit = 0, result = boolean(left)
7800 pic16_emitcode(";XXX setb","c");
7801 pic16_toBoolean(right);
7803 symbol *tlbl = newiTempLabel(NULL);
7804 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7806 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7808 genIfxJump (ifx,"a");
7812 pic16_outBitC(result);
7816 /* if left is same as result */
7817 if(pic16_sameRegs(AOP(result),AOP(left))){
7819 for(;size--; offset++,lit>>=8) {
7820 if(AOP_TYPE(right) == AOP_LIT){
7821 if((lit & 0xff) == 0)
7822 /* or'ing with 0 has no effect */
7825 int p = my_powof2(lit & 0xff);
7827 /* only one bit is set in the literal, so use a bsf instruction */
7828 pic16_emitpcode(POC_BSF,
7829 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7831 if(know_W != (lit & 0xff))
7832 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7833 know_W = lit & 0xff;
7834 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7839 if (AOP_TYPE(left) == AOP_ACC) {
7840 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
7841 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7843 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7844 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7846 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7847 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7853 // left & result in different registers
7854 if(AOP_TYPE(result) == AOP_CRY){
7856 // if(size), result in bit
7857 // if(!size && ifx), conditional oper: if(left | right)
7858 symbol *tlbl = newiTempLabel(NULL);
7859 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7860 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7864 pic16_emitcode(";XXX setb","c");
7866 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7867 pic16_emitcode(";XXX orl","a,%s",
7868 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7869 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7874 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7875 pic16_outBitC(result);
7877 jmpTrueOrFalse(ifx, tlbl);
7878 } else for(;(size--);offset++){
7880 // result = left & right
7881 if(AOP_TYPE(right) == AOP_LIT){
7882 int t = (lit >> (offset*8)) & 0x0FFL;
7885 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7886 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7888 pic16_emitcode("movf","%s,w",
7889 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7890 pic16_emitcode("movwf","%s",
7891 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7894 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7895 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7896 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7898 pic16_emitcode("movlw","0x%x",t);
7899 pic16_emitcode("iorwf","%s,w",
7900 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7901 pic16_emitcode("movwf","%s",
7902 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7908 // faster than result <- left, anl result,right
7909 // and better if result is SFR
7910 if (AOP_TYPE(left) == AOP_ACC) {
7911 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
7912 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7914 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7915 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7917 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7918 pic16_emitcode("iorwf","%s,w",
7919 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7921 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7922 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7927 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7928 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7929 pic16_freeAsmop(result,NULL,ic,TRUE);
7932 /*-----------------------------------------------------------------*/
7933 /* genXor - code for xclusive or */
7934 /*-----------------------------------------------------------------*/
7935 static void genXor (iCode *ic, iCode *ifx)
7937 operand *left, *right, *result;
7939 unsigned long lit = 0L;
7941 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7943 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7944 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7945 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7947 /* if left is a literal & right is not ||
7948 if left needs acc & right does not */
7949 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7950 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
7951 operand *tmp = right ;
7956 /* if result = right then exchange them */
7957 if(pic16_sameRegs(AOP(result),AOP(right))){
7958 operand *tmp = right ;
7963 /* if right is bit then exchange them */
7964 if (AOP_TYPE(right) == AOP_CRY &&
7965 AOP_TYPE(left) != AOP_CRY){
7966 operand *tmp = right ;
7970 if(AOP_TYPE(right) == AOP_LIT)
7971 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7973 size = AOP_SIZE(result);
7977 if (AOP_TYPE(left) == AOP_CRY){
7978 if(AOP_TYPE(right) == AOP_LIT){
7979 // c = bit & literal;
7981 // lit>>1 != 0 => result = 1
7982 if(AOP_TYPE(result) == AOP_CRY){
7984 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
7985 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
7987 continueIfTrue(ifx);
7990 pic16_emitcode("setb","c");
7994 // lit == 0, result = left
7995 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7997 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7999 // lit == 1, result = not(left)
8000 if(size && pic16_sameRegs(AOP(result),AOP(left))){
8001 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
8002 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
8003 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
8006 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
8007 pic16_emitcode("cpl","c");
8014 symbol *tlbl = newiTempLabel(NULL);
8015 if (AOP_TYPE(right) == AOP_CRY){
8017 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
8020 int sizer = AOP_SIZE(right);
8022 // if val>>1 != 0, result = 1
8023 pic16_emitcode("setb","c");
8025 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
8027 // test the msb of the lsb
8028 pic16_emitcode("anl","a,#0xfe");
8029 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
8033 pic16_emitcode("rrc","a");
8035 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
8036 pic16_emitcode("cpl","c");
8037 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
8042 pic16_outBitC(result);
8044 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
8045 genIfxJump(ifx, "c");
8049 if(pic16_sameRegs(AOP(result),AOP(left))){
8050 /* if left is same as result */
8051 for(;size--; offset++) {
8052 if(AOP_TYPE(right) == AOP_LIT){
8053 int t = (lit >> (offset*8)) & 0x0FFL;
8057 if (IS_AOP_PREG(left)) {
8058 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8059 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
8060 pic16_aopPut(AOP(result),"a",offset);
8062 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
8063 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
8064 pic16_emitcode("xrl","%s,%s",
8065 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
8066 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8069 if (AOP_TYPE(left) == AOP_ACC)
8070 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8072 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
8073 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
8075 if (IS_AOP_PREG(left)) {
8076 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
8077 pic16_aopPut(AOP(result),"a",offset);
8079 pic16_emitcode("xrl","%s,a",
8080 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
8086 // left & result in different registers
8087 if(AOP_TYPE(result) == AOP_CRY){
8089 // if(size), result in bit
8090 // if(!size && ifx), conditional oper: if(left ^ right)
8091 symbol *tlbl = newiTempLabel(NULL);
8092 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
8094 pic16_emitcode("setb","c");
8096 if((AOP_TYPE(right) == AOP_LIT) &&
8097 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
8098 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8100 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8101 pic16_emitcode("xrl","a,%s",
8102 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8104 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
8109 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8110 pic16_outBitC(result);
8112 jmpTrueOrFalse(ifx, tlbl);
8113 } else for(;(size--);offset++){
8115 // result = left & right
8116 if(AOP_TYPE(right) == AOP_LIT){
8117 int t = (lit >> (offset*8)) & 0x0FFL;
8120 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
8121 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
8122 pic16_emitcode("movf","%s,w",
8123 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8124 pic16_emitcode("movwf","%s",
8125 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
8128 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
8129 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
8130 pic16_emitcode("comf","%s,w",
8131 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8132 pic16_emitcode("movwf","%s",
8133 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
8136 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
8137 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
8138 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
8139 pic16_emitcode("movlw","0x%x",t);
8140 pic16_emitcode("xorwf","%s,w",
8141 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8142 pic16_emitcode("movwf","%s",
8143 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
8149 // faster than result <- left, anl result,right
8150 // and better if result is SFR
8151 if (AOP_TYPE(left) == AOP_ACC) {
8152 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
8153 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8155 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
8156 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
8157 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8158 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8160 if ( AOP_TYPE(result) != AOP_ACC){
8161 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
8162 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
8168 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
8169 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
8170 pic16_freeAsmop(result,NULL,ic,TRUE);
8173 /*-----------------------------------------------------------------*/
8174 /* genInline - write the inline code out */
8175 /*-----------------------------------------------------------------*/
8176 static void genInline (iCode *ic)
8178 char *buffer, *bp, *bp1;
8180 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8182 _G.inLine += (!options.asmpeep);
8184 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
8185 strcpy(buffer,IC_INLINE(ic));
8187 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
8189 /* emit each line as a code */
8195 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
8203 /* print label, use this special format with NULL directive
8204 * to denote that the argument should not be indented with tab */
8205 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
8212 if ((bp1 != bp) && *bp1)
8213 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
8218 _G.inLine -= (!options.asmpeep);
8221 /*-----------------------------------------------------------------*/
8222 /* genRRC - rotate right with carry */
8223 /*-----------------------------------------------------------------*/
8224 static void genRRC (iCode *ic)
8226 operand *left , *result ;
8227 int size, offset = 0, same;
8229 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8231 /* rotate right with carry */
8233 result=IC_RESULT(ic);
8234 pic16_aopOp (left,ic,FALSE);
8235 pic16_aopOp (result,ic,FALSE);
8237 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8239 same = pic16_sameRegs(AOP(result),AOP(left));
8241 size = AOP_SIZE(result);
8243 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
8245 /* get the lsb and put it into the carry */
8246 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
8253 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
8255 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
8256 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8262 pic16_freeAsmop(left,NULL,ic,TRUE);
8263 pic16_freeAsmop(result,NULL,ic,TRUE);
8266 /*-----------------------------------------------------------------*/
8267 /* genRLC - generate code for rotate left with carry */
8268 /*-----------------------------------------------------------------*/
8269 static void genRLC (iCode *ic)
8271 operand *left , *result ;
8272 int size, offset = 0;
8275 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8276 /* rotate right with carry */
8278 result=IC_RESULT(ic);
8279 pic16_aopOp (left,ic,FALSE);
8280 pic16_aopOp (result,ic,FALSE);
8282 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8284 same = pic16_sameRegs(AOP(result),AOP(left));
8286 /* move it to the result */
8287 size = AOP_SIZE(result);
8289 /* get the msb and put it into the carry */
8290 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
8297 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
8299 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
8300 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8307 pic16_freeAsmop(left,NULL,ic,TRUE);
8308 pic16_freeAsmop(result,NULL,ic,TRUE);
8312 /* gpasm can get the highest order bit with HIGH/UPPER
8313 * so the following probably is not needed -- VR */
8315 /*-----------------------------------------------------------------*/
8316 /* genGetHbit - generates code get highest order bit */
8317 /*-----------------------------------------------------------------*/
8318 static void genGetHbit (iCode *ic)
8320 operand *left, *result;
8322 result=IC_RESULT(ic);
8323 pic16_aopOp (left,ic,FALSE);
8324 pic16_aopOp (result,ic,FALSE);
8326 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8327 /* get the highest order byte into a */
8328 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
8329 if(AOP_TYPE(result) == AOP_CRY){
8330 pic16_emitcode("rlc","a");
8331 pic16_outBitC(result);
8334 pic16_emitcode("rl","a");
8335 pic16_emitcode("anl","a,#0x01");
8336 pic16_outAcc(result);
8340 pic16_freeAsmop(left,NULL,ic,TRUE);
8341 pic16_freeAsmop(result,NULL,ic,TRUE);
8345 /*-----------------------------------------------------------------*/
8346 /* AccRol - rotate left accumulator by known count */
8347 /*-----------------------------------------------------------------*/
8348 static void AccRol (int shCount)
8350 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8351 shCount &= 0x0007; // shCount : 0..7
8356 pic16_emitcode("rl","a");
8359 pic16_emitcode("rl","a");
8360 pic16_emitcode("rl","a");
8363 pic16_emitcode("swap","a");
8364 pic16_emitcode("rr","a");
8367 pic16_emitcode("swap","a");
8370 pic16_emitcode("swap","a");
8371 pic16_emitcode("rl","a");
8374 pic16_emitcode("rr","a");
8375 pic16_emitcode("rr","a");
8378 pic16_emitcode("rr","a");
8384 /*-----------------------------------------------------------------*/
8385 /* AccLsh - left shift accumulator by known count */
8386 /*-----------------------------------------------------------------*/
8387 static void AccLsh (int shCount)
8389 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8395 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8398 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8399 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8402 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8403 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8406 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8409 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8410 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8413 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8414 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8417 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8421 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
8424 /*-----------------------------------------------------------------*/
8425 /* AccRsh - right shift accumulator by known count */
8426 /*-----------------------------------------------------------------*/
8427 static void AccRsh (int shCount, int andmask)
8429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8434 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8437 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8438 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8441 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8442 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8445 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8448 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
8449 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8452 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8453 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8456 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
8461 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
8463 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
8467 /*-----------------------------------------------------------------*/
8468 /* AccSRsh - signed right shift accumulator by known count */
8469 /*-----------------------------------------------------------------*/
8470 static void AccSRsh (int shCount)
8473 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8476 pic16_emitcode("mov","c,acc.7");
8477 pic16_emitcode("rrc","a");
8478 } else if(shCount == 2){
8479 pic16_emitcode("mov","c,acc.7");
8480 pic16_emitcode("rrc","a");
8481 pic16_emitcode("mov","c,acc.7");
8482 pic16_emitcode("rrc","a");
8484 tlbl = newiTempLabel(NULL);
8485 /* rotate right accumulator */
8486 AccRol(8 - shCount);
8487 /* and kill the higher order bits */
8488 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
8489 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
8490 pic16_emitcode("orl","a,#0x%02x",
8491 (unsigned char)~SRMask[shCount]);
8492 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8498 /*-----------------------------------------------------------------*/
8499 /* shiftR1Left2Result - shift right one byte from left to result */
8500 /*-----------------------------------------------------------------*/
8501 static void shiftR1Left2ResultSigned (operand *left, int offl,
8502 operand *result, int offr,
8507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8509 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8513 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8515 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8517 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8518 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8524 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8526 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8528 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8529 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8531 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8532 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8538 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8540 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8541 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8544 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8545 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8546 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8548 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8549 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
8551 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8555 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8556 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8557 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8558 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
8559 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8563 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8565 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8566 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8568 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8569 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
8570 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
8571 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
8572 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8577 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8578 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8579 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
8580 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8581 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
8582 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8584 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8585 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8586 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8587 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
8588 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8594 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
8595 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8596 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8597 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8599 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8600 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8601 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
8609 /*-----------------------------------------------------------------*/
8610 /* shiftR1Left2Result - shift right one byte from left to result */
8611 /*-----------------------------------------------------------------*/
8612 static void shiftR1Left2Result (operand *left, int offl,
8613 operand *result, int offr,
8614 int shCount, int sign)
8618 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8620 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8622 /* Copy the msb into the carry if signed. */
8624 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
8634 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8636 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8637 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8643 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8645 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8646 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8649 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8654 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8656 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8657 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8660 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr));
8661 //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8662 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
8663 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8667 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8668 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8669 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8673 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
8674 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0e));
8675 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8677 pic16_emitpcode(POC_RRNCF, pic16_popGet(AOP(result),offr));
8682 pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left),offl));
8683 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x81));
8684 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8685 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8686 pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(result),offr));
8691 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8692 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8693 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8702 /*-----------------------------------------------------------------*/
8703 /* shiftL1Left2Result - shift left one byte from left to result */
8704 /*-----------------------------------------------------------------*/
8705 static void shiftL1Left2Result (operand *left, int offl,
8706 operand *result, int offr, int shCount)
8711 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8713 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
8714 DEBUGpic16_emitcode ("; ***","same = %d",same);
8715 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8717 /* shift left accumulator */
8718 //AccLsh(shCount); // don't comment out just yet...
8719 // pic16_aopPut(AOP(result),"a",offr);
8723 /* Shift left 1 bit position */
8724 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8726 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
8728 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
8729 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8733 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8734 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
8735 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8736 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8739 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8740 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
8741 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8742 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8743 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8746 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8747 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8748 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8751 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8752 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8753 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8754 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8757 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8758 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
8759 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8760 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8761 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8764 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8765 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8766 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8770 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
8775 /*-----------------------------------------------------------------*/
8776 /* movLeft2Result - move byte from left to result */
8777 /*-----------------------------------------------------------------*/
8778 static void movLeft2Result (operand *left, int offl,
8779 operand *result, int offr)
8782 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8783 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
8784 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
8786 if (*l == '@' && (IS_AOP_PREG(result))) {
8787 pic16_emitcode("mov","a,%s",l);
8788 pic16_aopPut(AOP(result),"a",offr);
8790 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8791 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8796 /*-----------------------------------------------------------------*/
8797 /* shiftL2Left2Result - shift left two bytes from left to result */
8798 /*-----------------------------------------------------------------*/
8799 static void shiftL2Left2Result (operand *left, int offl,
8800 operand *result, int offr, int shCount)
8802 int same = pic16_sameRegs(AOP(result), AOP(left));
8805 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
8807 if (same && (offl != offr)) { // shift bytes
8810 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8811 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8813 } else { // just treat as different later on
8826 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
8827 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8828 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8832 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8833 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8839 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
8840 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
8841 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8842 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8843 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
8844 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8845 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8847 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8848 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8852 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8853 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8854 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8855 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8856 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8857 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8858 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8859 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8860 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8861 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8864 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8865 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8866 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8867 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8868 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8878 /* note, use a mov/add for the shift since the mov has a
8879 chance of getting optimized out */
8880 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8881 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8882 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8883 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8884 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8888 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8889 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8895 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8896 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
8897 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8898 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8899 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8900 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0F));
8901 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8902 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8906 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8907 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8911 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8912 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8913 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
8914 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8916 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8917 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8918 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8919 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8920 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8921 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8922 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8923 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8926 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8927 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8928 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8929 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8930 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8935 /*-----------------------------------------------------------------*/
8936 /* shiftR2Left2Result - shift right two bytes from left to result */
8937 /*-----------------------------------------------------------------*/
8938 static void shiftR2Left2Result (operand *left, int offl,
8939 operand *result, int offr,
8940 int shCount, int sign)
8942 int same = pic16_sameRegs(AOP(result), AOP(left));
8944 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
8946 if (same && (offl != offr)) { // shift right bytes
8949 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8950 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8952 } else { // just treat as different later on
8964 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8969 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8970 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8972 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8973 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8974 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8975 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8980 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8983 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8984 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8991 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
8992 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
8993 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8995 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8996 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
8997 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8998 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
9000 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
9001 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
9002 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
9004 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
9005 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
9006 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9007 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
9008 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
9012 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
9013 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
9017 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
9018 pic16_emitpcode(POC_BTFSC,
9019 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
9020 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
9028 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
9029 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
9031 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
9032 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
9033 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
9034 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
9036 pic16_emitpcode(POC_BTFSC,
9037 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9038 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
9040 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
9041 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
9042 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
9043 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
9045 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
9046 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
9047 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
9048 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
9049 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
9050 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
9051 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
9052 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
9054 pic16_emitpcode(POC_BTFSC,
9055 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9056 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
9058 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
9059 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
9066 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
9067 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
9068 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
9069 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
9072 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
9074 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
9079 /*-----------------------------------------------------------------*/
9080 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
9081 /*-----------------------------------------------------------------*/
9082 static void shiftLLeftOrResult (operand *left, int offl,
9083 operand *result, int offr, int shCount)
9085 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9087 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
9088 /* shift left accumulator */
9090 /* or with result */
9091 /* back to result */
9092 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
9095 /*-----------------------------------------------------------------*/
9096 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
9097 /*-----------------------------------------------------------------*/
9098 static void shiftRLeftOrResult (operand *left, int offl,
9099 operand *result, int offr, int shCount)
9101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9103 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
9104 /* shift right accumulator */
9106 /* or with result */
9107 /* back to result */
9108 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
9111 /*-----------------------------------------------------------------*/
9112 /* genlshOne - left shift a one byte quantity by known count */
9113 /*-----------------------------------------------------------------*/
9114 static void genlshOne (operand *result, operand *left, int shCount)
9116 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9117 shiftL1Left2Result(left, LSB, result, LSB, shCount);
9120 /*-----------------------------------------------------------------*/
9121 /* genlshTwo - left shift two bytes by known amount != 0 */
9122 /*-----------------------------------------------------------------*/
9123 static void genlshTwo (operand *result,operand *left, int shCount)
9127 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
9128 size = pic16_getDataSize(result);
9130 /* if shCount >= 8 */
9136 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
9138 movLeft2Result(left, LSB, result, MSB16);
9140 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
9143 /* 1 <= shCount <= 7 */
9146 shiftL1Left2Result(left, LSB, result, LSB, shCount);
9148 shiftL2Left2Result(left, LSB, result, LSB, shCount);
9152 /*-----------------------------------------------------------------*/
9153 /* shiftLLong - shift left one long from left to result */
9154 /* offr = LSB or MSB16 */
9155 /*-----------------------------------------------------------------*/
9156 static void shiftLLong (operand *left, operand *result, int offr )
9158 int size = AOP_SIZE(result);
9159 int same = pic16_sameRegs(AOP(left),AOP(result));
9162 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
9164 if (same && (offr == MSB16)) { //shift one byte
9165 for(i=size-1;i>=MSB16;i--) {
9166 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
9167 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
9170 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
9173 if (size > LSB+offr ){
9175 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
9177 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
9178 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
9182 if(size > MSB16+offr){
9184 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
9186 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
9187 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
9191 if(size > MSB24+offr){
9193 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
9195 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
9196 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
9200 if(size > MSB32+offr){
9202 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
9204 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
9205 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
9209 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
9213 /*-----------------------------------------------------------------*/
9214 /* genlshFour - shift four byte by a known amount != 0 */
9215 /*-----------------------------------------------------------------*/
9216 static void genlshFour (operand *result, operand *left, int shCount)
9220 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9221 size = AOP_SIZE(result);
9223 /* if shifting more that 3 bytes */
9224 if (shCount >= 24 ) {
9227 /* lowest order of left goes to the highest
9228 order of the destination */
9229 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
9231 movLeft2Result(left, LSB, result, MSB32);
9233 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
9234 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
9235 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
9240 /* more than two bytes */
9241 else if ( shCount >= 16 ) {
9242 /* lower order two bytes goes to higher order two bytes */
9244 /* if some more remaining */
9246 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
9248 movLeft2Result(left, MSB16, result, MSB32);
9249 movLeft2Result(left, LSB, result, MSB24);
9251 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
9252 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
9256 /* if more than 1 byte */
9257 else if ( shCount >= 8 ) {
9258 /* lower order three bytes goes to higher order three bytes */
9262 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
9264 movLeft2Result(left, LSB, result, MSB16);
9266 else{ /* size = 4 */
9268 movLeft2Result(left, MSB24, result, MSB32);
9269 movLeft2Result(left, MSB16, result, MSB24);
9270 movLeft2Result(left, LSB, result, MSB16);
9271 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
9273 else if(shCount == 1)
9274 shiftLLong(left, result, MSB16);
9276 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
9277 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
9278 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
9279 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
9284 /* 1 <= shCount <= 7 */
9285 else if(shCount <= 3)
9287 shiftLLong(left, result, LSB);
9288 while(--shCount >= 1)
9289 shiftLLong(result, result, LSB);
9291 /* 3 <= shCount <= 7, optimize */
9293 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
9294 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
9295 shiftL2Left2Result(left, LSB, result, LSB, shCount);
9299 /*-----------------------------------------------------------------*/
9300 /* genLeftShiftLiteral - left shifting by known count */
9301 /*-----------------------------------------------------------------*/
9302 static void genLeftShiftLiteral (operand *left,
9307 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
9310 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
9311 pic16_freeAsmop(right,NULL,ic,TRUE);
9313 pic16_aopOp(left,ic,FALSE);
9314 pic16_aopOp(result,ic,FALSE);
9316 size = getSize(operandType(result));
9319 pic16_emitcode("; shift left ","result %d, left %d",size,
9323 /* I suppose that the left size >= result size */
9326 movLeft2Result(left, size, result, size);
9330 else if(shCount >= (size * 8))
9332 pic16_aopPut(AOP(result),zero,size);
9336 genlshOne (result,left,shCount);
9341 genlshTwo (result,left,shCount);
9345 genlshFour (result,left,shCount);
9349 pic16_freeAsmop(left,NULL,ic,TRUE);
9350 pic16_freeAsmop(result,NULL,ic,TRUE);
9353 /*-----------------------------------------------------------------*
9354 * genMultiAsm - repeat assembly instruction for size of register.
9355 * if endian == 1, then the high byte (i.e base address + size of
9356 * register) is used first else the low byte is used first;
9357 *-----------------------------------------------------------------*/
9358 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
9363 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9376 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
9381 /*-----------------------------------------------------------------*/
9382 /* genLeftShift - generates code for left shifting */
9383 /*-----------------------------------------------------------------*/
9384 static void genLeftShift (iCode *ic)
9386 operand *left,*right, *result;
9389 symbol *tlbl , *tlbl1;
9392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9394 right = IC_RIGHT(ic);
9396 result = IC_RESULT(ic);
9398 pic16_aopOp(right,ic,FALSE);
9400 /* if the shift count is known then do it
9401 as efficiently as possible */
9402 if (AOP_TYPE(right) == AOP_LIT) {
9403 genLeftShiftLiteral (left,right,result,ic);
9407 /* shift count is unknown then we have to form
9408 * a loop. Get the loop count in WREG : Note: we take
9409 * only the lower order byte since shifting
9410 * more than 32 bits make no sense anyway, ( the
9411 * largest size of an object can be only 32 bits ) */
9413 pic16_aopOp(left,ic,FALSE);
9414 pic16_aopOp(result,ic,FALSE);
9416 /* now move the left to the result if they are not the
9417 * same, and if size > 1,
9418 * and if right is not same to result (!!!) -- VR */
9419 if (!pic16_sameRegs(AOP(left),AOP(result))
9420 && (AOP_SIZE(result) > 1)) {
9422 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9424 size = AOP_SIZE(result);
9429 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9430 if (*l == '@' && (IS_AOP_PREG(result))) {
9432 pic16_emitcode("mov","a,%s",l);
9433 pic16_aopPut(AOP(result),"a",offset);
9437 /* we don't know if left is a literal or a register, take care -- VR */
9438 mov2f(AOP(result), AOP(left), offset);
9444 size = AOP_SIZE(result);
9446 /* if it is only one byte then */
9448 if(optimized_for_speed) {
9449 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9450 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9451 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9452 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9453 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9454 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9455 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9456 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9457 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9458 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9459 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9460 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9463 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9465 tlbl = newiTempLabel(NULL);
9468 /* this is already done, why change it? */
9469 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9470 mov2f(AOP(result), AOP(left), 0);
9474 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9475 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9476 pic16_emitpLabel(tlbl->key);
9477 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9478 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9480 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9485 if (pic16_sameRegs(AOP(left),AOP(result))) {
9487 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9489 tlbl = newiTempLabel(NULL);
9490 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9491 genMultiAsm(POC_RRCF, result, size,1);
9492 pic16_emitpLabel(tlbl->key);
9493 genMultiAsm(POC_RLCF, result, size,0);
9494 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9496 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9500 //tlbl = newiTempLabel(NULL);
9502 //tlbl1 = newiTempLabel(NULL);
9504 //reAdjustPreg(AOP(result));
9506 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9507 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9508 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9510 //pic16_emitcode("add","a,acc");
9511 //pic16_aopPut(AOP(result),"a",offset++);
9513 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9515 // pic16_emitcode("rlc","a");
9516 // pic16_aopPut(AOP(result),"a",offset++);
9518 //reAdjustPreg(AOP(result));
9520 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9521 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9524 tlbl = newiTempLabel(NULL);
9525 tlbl1= newiTempLabel(NULL);
9527 size = AOP_SIZE(result);
9530 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9532 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9534 /* offset should be 0, 1 or 3 */
9536 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9538 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9540 pic16_emitpcode(POC_MOVWF, pctemp);
9543 pic16_emitpLabel(tlbl->key);
9546 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9548 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9550 pic16_emitpcode(POC_DECFSZ, pctemp);
9551 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9552 pic16_emitpLabel(tlbl1->key);
9554 pic16_popReleaseTempReg(pctemp,1);
9558 pic16_freeAsmop (right,NULL,ic,TRUE);
9559 pic16_freeAsmop(left,NULL,ic,TRUE);
9560 pic16_freeAsmop(result,NULL,ic,TRUE);
9566 #error old code (left here for reference)
9567 /*-----------------------------------------------------------------*/
9568 /* genLeftShift - generates code for left shifting */
9569 /*-----------------------------------------------------------------*/
9570 static void genLeftShift (iCode *ic)
9572 operand *left,*right, *result;
9575 symbol *tlbl , *tlbl1;
9578 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9580 right = IC_RIGHT(ic);
9582 result = IC_RESULT(ic);
9584 pic16_aopOp(right,ic,FALSE);
9586 /* if the shift count is known then do it
9587 as efficiently as possible */
9588 if (AOP_TYPE(right) == AOP_LIT) {
9589 genLeftShiftLiteral (left,right,result,ic);
9593 /* shift count is unknown then we have to form
9594 a loop get the loop count in B : Note: we take
9595 only the lower order byte since shifting
9596 more that 32 bits make no sense anyway, ( the
9597 largest size of an object can be only 32 bits ) */
9600 pic16_aopOp(left,ic,FALSE);
9601 pic16_aopOp(result,ic,FALSE);
9603 /* now move the left to the result if they are not the
9605 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9606 AOP_SIZE(result) > 1) {
9608 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9610 size = AOP_SIZE(result);
9613 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9614 if (*l == '@' && (IS_AOP_PREG(result))) {
9616 pic16_emitcode("mov","a,%s",l);
9617 pic16_aopPut(AOP(result),"a",offset);
9620 /* we don't know if left is a literal or a register, take care -- VR */
9621 mov2f(AOP(result), AOP(left), offset);
9627 size = AOP_SIZE(result);
9629 /* if it is only one byte then */
9631 if(optimized_for_speed) {
9632 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
9633 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
9634 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
9635 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9636 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9637 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
9638 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9639 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
9640 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
9641 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
9642 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
9643 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
9646 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9648 tlbl = newiTempLabel(NULL);
9649 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9650 mov2f(AOP(result), AOP(left), 0);
9652 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9653 // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9656 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9657 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9658 pic16_emitpLabel(tlbl->key);
9659 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9660 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9662 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9667 if (pic16_sameRegs(AOP(left),AOP(result))) {
9669 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9671 tlbl = newiTempLabel(NULL);
9672 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9673 genMultiAsm(POC_RRCF, result, size,1);
9674 pic16_emitpLabel(tlbl->key);
9675 genMultiAsm(POC_RLCF, result, size,0);
9676 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9678 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9682 //tlbl = newiTempLabel(NULL);
9684 //tlbl1 = newiTempLabel(NULL);
9686 //reAdjustPreg(AOP(result));
9688 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9689 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9690 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9692 //pic16_emitcode("add","a,acc");
9693 //pic16_aopPut(AOP(result),"a",offset++);
9695 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9697 // pic16_emitcode("rlc","a");
9698 // pic16_aopPut(AOP(result),"a",offset++);
9700 //reAdjustPreg(AOP(result));
9702 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9703 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9706 tlbl = newiTempLabel(NULL);
9707 tlbl1= newiTempLabel(NULL);
9709 size = AOP_SIZE(result);
9712 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
9714 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9716 /* offset should be 0, 1 or 3 */
9718 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
9720 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9722 pic16_emitpcode(POC_MOVWF, pctemp);
9725 pic16_emitpLabel(tlbl->key);
9728 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9730 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
9732 pic16_emitpcode(POC_DECFSZ, pctemp);
9733 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9734 pic16_emitpLabel(tlbl1->key);
9736 pic16_popReleaseTempReg(pctemp,1);
9740 pic16_freeAsmop (right,NULL,ic,TRUE);
9741 pic16_freeAsmop(left,NULL,ic,TRUE);
9742 pic16_freeAsmop(result,NULL,ic,TRUE);
9746 /*-----------------------------------------------------------------*/
9747 /* genrshOne - right shift a one byte quantity by known count */
9748 /*-----------------------------------------------------------------*/
9749 static void genrshOne (operand *result, operand *left,
9750 int shCount, int sign)
9752 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9753 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
9756 /*-----------------------------------------------------------------*/
9757 /* genrshTwo - right shift two bytes by known amount != 0 */
9758 /*-----------------------------------------------------------------*/
9759 static void genrshTwo (operand *result,operand *left,
9760 int shCount, int sign)
9762 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
9763 /* if shCount >= 8 */
9767 shiftR1Left2Result(left, MSB16, result, LSB,
9770 movLeft2Result(left, MSB16, result, LSB);
9772 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
9775 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9776 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
9780 /* 1 <= shCount <= 7 */
9782 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
9785 /*-----------------------------------------------------------------*/
9786 /* shiftRLong - shift right one long from left to result */
9787 /* offl = LSB or MSB16 */
9788 /*-----------------------------------------------------------------*/
9789 static void shiftRLong (operand *left, int offl,
9790 operand *result, int sign)
9792 int size = AOP_SIZE(result);
9793 int same = pic16_sameRegs(AOP(left),AOP(result));
9795 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
9797 if (same && (offl == MSB16)) { //shift one byte right
9798 for(i=MSB16;i<size;i++) {
9799 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
9800 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
9805 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
9811 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
9813 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
9814 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
9818 /* add sign of "a" */
9819 pic16_addSign(result, MSB32, sign);
9823 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
9825 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
9826 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
9830 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
9832 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
9833 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
9837 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
9840 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
9841 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
9846 /*-----------------------------------------------------------------*/
9847 /* genrshFour - shift four byte by a known amount != 0 */
9848 /*-----------------------------------------------------------------*/
9849 static void genrshFour (operand *result, operand *left,
9850 int shCount, int sign)
9852 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9853 /* if shifting more that 3 bytes */
9854 if(shCount >= 24 ) {
9857 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
9859 movLeft2Result(left, MSB32, result, LSB);
9861 pic16_addSign(result, MSB16, sign);
9863 else if(shCount >= 16){
9866 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
9868 movLeft2Result(left, MSB24, result, LSB);
9869 movLeft2Result(left, MSB32, result, MSB16);
9871 pic16_addSign(result, MSB24, sign);
9873 else if(shCount >= 8){
9876 shiftRLong(left, MSB16, result, sign);
9877 else if(shCount == 0){
9878 movLeft2Result(left, MSB16, result, LSB);
9879 movLeft2Result(left, MSB24, result, MSB16);
9880 movLeft2Result(left, MSB32, result, MSB24);
9881 pic16_addSign(result, MSB32, sign);
9883 else{ //shcount >= 2
9884 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
9885 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
9886 /* the last shift is signed */
9887 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
9888 pic16_addSign(result, MSB32, sign);
9891 else{ /* 1 <= shCount <= 7 */
9893 shiftRLong(left, LSB, result, sign);
9895 shiftRLong(result, LSB, result, sign);
9898 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
9899 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
9900 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
9905 /*-----------------------------------------------------------------*/
9906 /* genRightShiftLiteral - right shifting by known count */
9907 /*-----------------------------------------------------------------*/
9908 static void genRightShiftLiteral (operand *left,
9914 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
9917 pic16_freeAsmop(right,NULL,ic,TRUE);
9919 pic16_aopOp(left,ic,FALSE);
9920 pic16_aopOp(result,ic,FALSE);
9922 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
9925 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
9929 lsize = pic16_getDataSize(left);
9930 res_size = pic16_getDataSize(result);
9931 /* test the LEFT size !!! */
9933 /* I suppose that the left size >= result size */
9936 movLeft2Result(left, lsize, result, res_size);
9939 else if(shCount >= (lsize * 8)){
9942 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
9944 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9945 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
9950 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
9951 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9952 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9954 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
9959 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
9966 genrshOne (result,left,shCount,sign);
9970 genrshTwo (result,left,shCount,sign);
9974 genrshFour (result,left,shCount,sign);
9982 pic16_freeAsmop(left,NULL,ic,TRUE);
9983 pic16_freeAsmop(result,NULL,ic,TRUE);
9986 /*-----------------------------------------------------------------*/
9987 /* genSignedRightShift - right shift of signed number */
9988 /*-----------------------------------------------------------------*/
9989 static void genSignedRightShift (iCode *ic)
9991 operand *right, *left, *result;
9994 symbol *tlbl, *tlbl1 ;
9997 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
9999 /* we do it the hard way put the shift count in b
10000 and loop thru preserving the sign */
10001 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10003 right = IC_RIGHT(ic);
10004 left = IC_LEFT(ic);
10005 result = IC_RESULT(ic);
10007 pic16_aopOp(right,ic,FALSE);
10008 pic16_aopOp(left,ic,FALSE);
10009 pic16_aopOp(result,ic,FALSE);
10012 if ( AOP_TYPE(right) == AOP_LIT) {
10013 genRightShiftLiteral (left,right,result,ic,1);
10016 /* shift count is unknown then we have to form
10017 a loop get the loop count in B : Note: we take
10018 only the lower order byte since shifting
10019 more that 32 bits make no sense anyway, ( the
10020 largest size of an object can be only 32 bits ) */
10022 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
10023 //pic16_emitcode("inc","b");
10024 //pic16_freeAsmop (right,NULL,ic,TRUE);
10025 //pic16_aopOp(left,ic,FALSE);
10026 //pic16_aopOp(result,ic,FALSE);
10028 /* now move the left to the result if they are not the
10030 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
10031 AOP_SIZE(result) > 1) {
10033 size = AOP_SIZE(result);
10037 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
10038 if (*l == '@' && IS_AOP_PREG(result)) {
10040 pic16_emitcode("mov","a,%s",l);
10041 pic16_aopPut(AOP(result),"a",offset);
10043 pic16_aopPut(AOP(result),l,offset);
10045 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
10046 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10052 /* mov the highest order bit to OVR */
10053 tlbl = newiTempLabel(NULL);
10054 tlbl1= newiTempLabel(NULL);
10056 size = AOP_SIZE(result);
10059 pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */
10061 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
10063 /* offset should be 0, 1 or 3 */
10064 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
10066 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
10068 pic16_emitpcode(POC_MOVWF, pctemp);
10071 pic16_emitpLabel(tlbl->key);
10073 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
10074 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
10077 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
10080 pic16_emitpcode(POC_DECFSZ, pctemp);
10081 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
10082 pic16_emitpLabel(tlbl1->key);
10084 pic16_popReleaseTempReg(pctemp,1);
10086 size = AOP_SIZE(result);
10088 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
10089 pic16_emitcode("rlc","a");
10090 pic16_emitcode("mov","ov,c");
10091 /* if it is only one byte then */
10093 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10095 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
10096 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
10097 pic16_emitcode("mov","c,ov");
10098 pic16_emitcode("rrc","a");
10099 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
10100 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
10101 pic16_aopPut(AOP(result),"a",0);
10105 reAdjustPreg(AOP(result));
10106 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
10107 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
10108 pic16_emitcode("mov","c,ov");
10110 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
10112 pic16_emitcode("rrc","a");
10113 pic16_aopPut(AOP(result),"a",offset--);
10115 reAdjustPreg(AOP(result));
10116 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
10117 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
10122 pic16_freeAsmop(left,NULL,ic,TRUE);
10123 pic16_freeAsmop(result,NULL,ic,TRUE);
10124 pic16_freeAsmop(right,NULL,ic,TRUE);
10127 /*-----------------------------------------------------------------*/
10128 /* genRightShift - generate code for right shifting */
10129 /*-----------------------------------------------------------------*/
10130 static void genRightShift (iCode *ic)
10132 operand *right, *left, *result;
10136 symbol *tlbl, *tlbl1 ;
10138 /* if signed then we do it the hard way preserve the
10139 sign bit moving it inwards */
10140 letype = getSpec(operandType(IC_LEFT(ic)));
10141 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10143 if (!SPEC_USIGN(letype)) {
10144 genSignedRightShift (ic);
10148 /* signed & unsigned types are treated the same : i.e. the
10149 signed is NOT propagated inwards : quoting from the
10150 ANSI - standard : "for E1 >> E2, is equivalent to division
10151 by 2**E2 if unsigned or if it has a non-negative value,
10152 otherwise the result is implementation defined ", MY definition
10153 is that the sign does not get propagated */
10155 right = IC_RIGHT(ic);
10156 left = IC_LEFT(ic);
10157 result = IC_RESULT(ic);
10159 pic16_aopOp(right,ic,FALSE);
10161 /* if the shift count is known then do it
10162 as efficiently as possible */
10163 if (AOP_TYPE(right) == AOP_LIT) {
10164 genRightShiftLiteral (left,right,result,ic, 0);
10168 /* shift count is unknown then we have to form
10169 a loop get the loop count in B : Note: we take
10170 only the lower order byte since shifting
10171 more that 32 bits make no sense anyway, ( the
10172 largest size of an object can be only 32 bits ) */
10174 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
10175 pic16_emitcode("inc","b");
10176 pic16_aopOp(left,ic,FALSE);
10177 pic16_aopOp(result,ic,FALSE);
10179 /* now move the left to the result if they are not the
10181 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
10182 AOP_SIZE(result) > 1) {
10184 size = AOP_SIZE(result);
10187 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
10188 if (*l == '@' && IS_AOP_PREG(result)) {
10190 pic16_emitcode("mov","a,%s",l);
10191 pic16_aopPut(AOP(result),"a",offset);
10193 pic16_aopPut(AOP(result),l,offset);
10198 tlbl = newiTempLabel(NULL);
10199 tlbl1= newiTempLabel(NULL);
10200 size = AOP_SIZE(result);
10203 /* if it is only one byte then */
10206 tlbl = newiTempLabel(NULL);
10207 if (!pic16_sameRegs(AOP(left),AOP(result))) {
10208 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
10209 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10212 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
10213 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
10214 pic16_emitpLabel(tlbl->key);
10215 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
10216 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
10218 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
10223 reAdjustPreg(AOP(result));
10224 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
10225 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
10228 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
10230 pic16_emitcode("rrc","a");
10231 pic16_aopPut(AOP(result),"a",offset--);
10233 reAdjustPreg(AOP(result));
10235 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
10236 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
10239 pic16_freeAsmop(left,NULL,ic,TRUE);
10240 pic16_freeAsmop (right,NULL,ic,TRUE);
10241 pic16_freeAsmop(result,NULL,ic,TRUE);
10245 void pic16_loadFSR0(operand *op)
10247 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
10250 /*-----------------------------------------------------------------*/
10251 /* genUnpackBits - generates code for unpacking bits */
10252 /*-----------------------------------------------------------------*/
10253 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
10257 sym_link *etype, *letype;
10258 int blen=0, bstr=0;
10262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10263 etype = getSpec(operandType(result));
10264 letype = getSpec(operandType(left));
10266 // if(IS_BITFIELD(etype)) {
10267 blen = SPEC_BLEN(etype);
10268 bstr = SPEC_BSTR(etype);
10271 lbstr = SPEC_BSTR( letype );
10274 if((blen == 1) && (bstr < 8)) {
10275 /* it is a single bit, so use the appropriate bit instructions */
10276 DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__);
10278 if(IS_BITFIELD(etype)/* && !IS_ITEMP(left)*/) {
10279 pic16_emitpcode(POC_MOVFW, pic16_popGet( AOP(result), 0 ));
10280 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
10282 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
10285 if((ptype == POINTER) && (result)) {
10286 /* workaround to reduce the extra lfsr instruction */
10287 pic16_emitpcode(POC_BTFSC,
10288 pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
10290 pic16_emitpcode(POC_BTFSC,
10291 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10295 if(IS_BITFIELD(etype)) {
10296 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
10298 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
10301 pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));
10307 /* the following call to pic16_loadFSR0 is temporary until
10308 * optimization to handle single bit assignments is added
10309 * to the function. Until then use the old safe way! -- VR */
10310 pic16_loadFSR0( left );
10312 /* read the first byte */
10319 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10322 pic16_emitcode("clr","a");
10323 pic16_emitcode("movc","a","@a+dptr");
10328 /* if we have bitdisplacement then it fits */
10329 /* into this byte completely or if length is */
10330 /* less than a byte */
10331 if ((shCnt = SPEC_BSTR(etype)) ||
10332 (SPEC_BLEN(etype) <= 8)) {
10334 /* shift right acc */
10337 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
10338 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
10340 /* VR -- normally I would use the following, but since we use the hack,
10341 * to avoid the masking from AccRsh, why not mask it right now? */
10344 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
10347 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10353 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
10354 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
10357 /* bit field did not fit in a byte */
10358 rlen = SPEC_BLEN(etype) - 8;
10359 pic16_aopPut(AOP(result),"a",offset++);
10366 pic16_emitcode("inc","%s",rname);
10367 pic16_emitcode("mov","a,@%s",rname);
10371 pic16_emitcode("inc","%s",rname);
10372 pic16_emitcode("movx","a,@%s",rname);
10376 pic16_emitcode("inc","dptr");
10377 pic16_emitcode("movx","a,@dptr");
10381 pic16_emitcode("clr","a");
10382 pic16_emitcode("inc","dptr");
10383 pic16_emitcode("movc","a","@a+dptr");
10387 pic16_emitcode("inc","dptr");
10388 pic16_emitcode("lcall","__gptrget");
10393 /* if we are done */
10397 pic16_aopPut(AOP(result),"a",offset++);
10402 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
10403 pic16_aopPut(AOP(result),"a",offset);
10410 static void genDataPointerGet(operand *left,
10414 int size, offset = 0, leoffset=0 ;
10416 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10417 pic16_aopOp(result, ic, FALSE);
10419 size = AOP_SIZE(result);
10420 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
10424 /* The following tests may save a redudant movff instruction when
10425 * accessing unions */
10427 /* if they are the same */
10428 if (operandsEqu (left, result)) {
10429 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
10435 /* if they are the same registers */
10436 if (pic16_sameRegs(AOP(left),AOP(result))) {
10437 DEBUGpic16_emitcode("; ***", "left and result registers are same");
10443 if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
10444 pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
10445 DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
10452 if ( AOP_TYPE(left) == AOP_PCODE) {
10453 fprintf(stderr,"genDataPointerGet %s, %d\n",
10454 AOP(left)->aopu.pcop->name,
10455 (AOP(left)->aopu.pcop->type == PO_DIR)?
10456 PCOR(AOP(left)->aopu.pcop)->instance:
10457 PCOI(AOP(left)->aopu.pcop)->offset);
10461 if(AOP(left)->aopu.pcop->type == PO_DIR)
10462 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
10464 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10467 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
10469 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
10470 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
10471 mov2w(AOP(left), offset); // patch 8
10472 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
10474 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
10475 pic16_popGet(AOP(left), offset), //patch 8
10476 pic16_popGet(AOP(result), offset)));
10484 pic16_freeAsmop(result,NULL,ic,TRUE);
10489 /*-----------------------------------------------------------------*/
10490 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
10491 /*-----------------------------------------------------------------*/
10492 static void genNearPointerGet (operand *left,
10497 //regs *preg = NULL ;
10498 sym_link *rtype, *retype;
10499 sym_link *ltype = operandType(left);
10501 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10502 rtype = operandType(result);
10503 retype= getSpec(rtype);
10505 pic16_aopOp(left,ic,FALSE);
10507 // pic16_DumpOp("(left)",left);
10508 // pic16_DumpOp("(result)",result);
10510 /* if left is rematerialisable and
10511 * result is not bit variable type and
10512 * the left is pointer to data space i.e
10513 * lower 128 bytes of space */
10514 if (AOP_TYPE(left) == AOP_PCODE
10515 && !IS_BITFIELD(retype)
10516 && DCL_TYPE(ltype) == POINTER) {
10518 genDataPointerGet (left,result,ic);
10519 pic16_freeAsmop(left, NULL, ic, TRUE);
10523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10525 /* if the value is already in a pointer register
10526 * then don't need anything more */
10527 if (!AOP_INPREG(AOP(left))) {
10528 /* otherwise get a free pointer register */
10529 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10531 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
10532 if( (AOP_TYPE(left) == AOP_PCODE)
10533 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10534 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
10536 if(!IS_BITFIELD(retype))
10537 pic16_loadFSR0( left ); // patch 10
10539 if(!IS_BITFIELD(retype)) {
10540 // set up FSR0 with address from left
10541 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10542 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10547 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10549 pic16_aopOp (result,ic,FALSE);
10551 DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result);
10553 /* if bitfield then unpack the bits */
10554 if (IS_BITFIELD(retype))
10555 genUnpackBits (result, left, NULL, POINTER);
10557 /* we have can just get the values */
10558 int size = AOP_SIZE(result);
10561 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10564 /* fsr0 is loaded already -- VR */
10565 // pic16_loadFSR0( left );
10567 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
10568 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
10572 pic16_emitpcode(POC_MOVFF,
10573 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
10574 pic16_popGet(AOP(result), offset++)));
10576 pic16_emitpcode(POC_MOVFF,
10577 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
10578 pic16_popGet(AOP(result), offset++)));
10582 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
10583 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
10585 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
10589 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
10591 pic16_emitcode("mov","a,@%s",rname);
10592 pic16_aopPut(AOP(result),"a",offset);
10594 sprintf(buffer,"@%s",rname);
10595 pic16_aopPut(AOP(result),buffer,offset);
10599 pic16_emitcode("inc","%s",rname);
10604 /* now some housekeeping stuff */
10606 /* we had to allocate for this iCode */
10607 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10608 pic16_freeAsmop(NULL,aop,ic,TRUE);
10610 /* we did not allocate which means left
10611 already in a pointer register, then
10612 if size > 0 && this could be used again
10613 we have to point it back to where it
10615 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10616 if (AOP_SIZE(result) > 1 &&
10617 !OP_SYMBOL(left)->remat &&
10618 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10620 // int size = AOP_SIZE(result) - 1;
10622 // pic16_emitcode("dec","%s",rname);
10627 pic16_freeAsmop(left,NULL,ic,TRUE);
10628 pic16_freeAsmop(result,NULL,ic,TRUE);
10632 /*-----------------------------------------------------------------*/
10633 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
10634 /*-----------------------------------------------------------------*/
10635 static void genPagedPointerGet (operand *left,
10640 regs *preg = NULL ;
10642 sym_link *rtype, *retype;
10644 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10646 rtype = operandType(result);
10647 retype= getSpec(rtype);
10649 pic16_aopOp(left,ic,FALSE);
10651 /* if the value is already in a pointer register
10652 then don't need anything more */
10653 if (!AOP_INPREG(AOP(left))) {
10654 /* otherwise get a free pointer register */
10656 preg = getFreePtr(ic,&aop,FALSE);
10657 pic16_emitcode("mov","%s,%s",
10659 pic16_aopGet(AOP(left),0,FALSE,TRUE));
10660 rname = preg->name ;
10662 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
10664 pic16_freeAsmop(left,NULL,ic,TRUE);
10665 pic16_aopOp (result,ic,FALSE);
10667 /* if bitfield then unpack the bits */
10668 if (IS_BITFIELD(retype))
10669 genUnpackBits (result,left,rname,PPOINTER);
10671 /* we have can just get the values */
10672 int size = AOP_SIZE(result);
10677 pic16_emitcode("movx","a,@%s",rname);
10678 pic16_aopPut(AOP(result),"a",offset);
10683 pic16_emitcode("inc","%s",rname);
10687 /* now some housekeeping stuff */
10689 /* we had to allocate for this iCode */
10690 pic16_freeAsmop(NULL,aop,ic,TRUE);
10692 /* we did not allocate which means left
10693 already in a pointer register, then
10694 if size > 0 && this could be used again
10695 we have to point it back to where it
10697 if (AOP_SIZE(result) > 1 &&
10698 !OP_SYMBOL(left)->remat &&
10699 ( OP_SYMBOL(left)->liveTo > ic->seq ||
10701 int size = AOP_SIZE(result) - 1;
10703 pic16_emitcode("dec","%s",rname);
10708 pic16_freeAsmop(result,NULL,ic,TRUE);
10713 /*-----------------------------------------------------------------*/
10714 /* genFarPointerGet - gget value from far space */
10715 /*-----------------------------------------------------------------*/
10716 static void genFarPointerGet (operand *left,
10717 operand *result, iCode *ic)
10720 sym_link *retype = getSpec(operandType(result));
10722 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10724 pic16_aopOp(left,ic,FALSE);
10726 /* if the operand is already in dptr
10727 then we do nothing else we move the value to dptr */
10728 if (AOP_TYPE(left) != AOP_STR) {
10729 /* if this is remateriazable */
10730 if (AOP_TYPE(left) == AOP_IMMD)
10731 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10732 else { /* we need to get it byte by byte */
10733 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10734 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10735 if (options.model == MODEL_FLAT24)
10737 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10741 /* so dptr know contains the address */
10742 pic16_freeAsmop(left,NULL,ic,TRUE);
10743 pic16_aopOp(result,ic,FALSE);
10745 /* if bit then unpack */
10746 if (IS_BITFIELD(retype))
10747 genUnpackBits(result,left,"dptr",FPOINTER);
10749 size = AOP_SIZE(result);
10753 pic16_emitcode("movx","a,@dptr");
10754 pic16_aopPut(AOP(result),"a",offset++);
10756 pic16_emitcode("inc","dptr");
10760 pic16_freeAsmop(result,NULL,ic,TRUE);
10763 /*-----------------------------------------------------------------*/
10764 /* genCodePointerGet - get value from code space */
10765 /*-----------------------------------------------------------------*/
10766 static void genCodePointerGet (operand *left,
10767 operand *result, iCode *ic)
10770 sym_link *retype = getSpec(operandType(result));
10772 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10774 pic16_aopOp(left,ic,FALSE);
10776 /* if the operand is already in dptr
10777 then we do nothing else we move the value to dptr */
10778 if (AOP_TYPE(left) != AOP_STR) {
10779 /* if this is remateriazable */
10780 if (AOP_TYPE(left) == AOP_IMMD)
10781 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
10782 else { /* we need to get it byte by byte */
10783 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
10784 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
10785 if (options.model == MODEL_FLAT24)
10787 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
10791 /* so dptr know contains the address */
10792 pic16_freeAsmop(left,NULL,ic,TRUE);
10793 pic16_aopOp(result,ic,FALSE);
10795 /* if bit then unpack */
10796 if (IS_BITFIELD(retype))
10797 genUnpackBits(result,left,"dptr",CPOINTER);
10799 size = AOP_SIZE(result);
10803 pic16_emitcode("clr","a");
10804 pic16_emitcode("movc","a,@a+dptr");
10805 pic16_aopPut(AOP(result),"a",offset++);
10807 pic16_emitcode("inc","dptr");
10811 pic16_freeAsmop(result,NULL,ic,TRUE);
10815 /*-----------------------------------------------------------------*/
10816 /* genGenPointerGet - gget value from generic pointer space */
10817 /*-----------------------------------------------------------------*/
10818 static void genGenPointerGet (operand *left,
10819 operand *result, iCode *ic)
10821 int size, offset, lit;
10822 sym_link *retype = getSpec(operandType(result));
10824 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10825 pic16_aopOp(left,ic,FALSE);
10826 pic16_aopOp(result,ic,FALSE);
10827 size = AOP_SIZE(result);
10829 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10831 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10833 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10834 // load FSR0 from immediate
10835 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10837 // pic16_loadFSR0( left );
10842 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10844 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10851 else { /* we need to get it byte by byte */
10852 // set up FSR0 with address from left
10853 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10854 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10860 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10862 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10869 /* if bit then unpack */
10870 if (IS_BITFIELD(retype))
10871 genUnpackBits(result,left,"BAD",GPOINTER);
10874 pic16_freeAsmop(left,NULL,ic,TRUE);
10875 pic16_freeAsmop(result,NULL,ic,TRUE);
10881 /*-----------------------------------------------------------------*/
10882 /* genGenPointerGet - gget value from generic pointer space */
10883 /*-----------------------------------------------------------------*/
10884 static void genGenPointerGet (operand *left,
10885 operand *result, iCode *ic)
10887 int size, offset, lit;
10888 sym_link *retype = getSpec(operandType(result));
10891 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10892 pic16_aopOp(left,ic,FALSE);
10893 pic16_aopOp(result,ic,FALSE);
10894 size = AOP_SIZE(result);
10896 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10898 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
10900 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
10901 // load FSR0 from immediate
10902 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10904 werror(W_POSSBUG2, __FILE__, __LINE__);
10909 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
10911 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10918 } else { /* we need to get it byte by byte */
10920 /* set up WREG:PRODL:FSR0L with address from left */
10921 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10922 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl)));
10923 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2));
10926 case 1: strcpy(fgptrget, "__gptrget1"); break;
10927 case 2: strcpy(fgptrget, "__gptrget2"); break;
10928 case 3: strcpy(fgptrget, "__gptrget3"); break;
10929 case 4: strcpy(fgptrget, "__gptrget4"); break;
10931 werror(W_POSSBUG2, __FILE__, __LINE__);
10935 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget ));
10937 assignResultValue(result, 1);
10942 sym = newSymbol( fgptrget, 0 );
10943 strcpy(sym->rname, fgptrget);
10944 checkAddSym(&externs, sym);
10946 // fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
10952 /* if bit then unpack */
10953 if (IS_BITFIELD(retype))
10954 genUnpackBits(result,left,"BAD",GPOINTER);
10957 pic16_freeAsmop(left,NULL,ic,TRUE);
10958 pic16_freeAsmop(result,NULL,ic,TRUE);
10961 /*-----------------------------------------------------------------*/
10962 /* genConstPointerGet - get value from const generic pointer space */
10963 /*-----------------------------------------------------------------*/
10964 static void genConstPointerGet (operand *left,
10965 operand *result, iCode *ic)
10967 //sym_link *retype = getSpec(operandType(result));
10968 // symbol *albl = newiTempLabel(NULL); // patch 15
10969 // symbol *blbl = newiTempLabel(NULL); //
10970 // PIC_OPCODE poc; // patch 15
10974 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10975 pic16_aopOp(left,ic,FALSE);
10976 pic16_aopOp(result,ic,TRUE);
10977 size = AOP_SIZE(result);
10979 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10981 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
10983 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
10984 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
10985 pic16_emitpLabel(albl->key);
10987 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
10989 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
10990 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
10991 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
10992 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
10993 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
10995 pic16_emitpLabel(blbl->key);
10997 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
11001 // set up table pointer
11002 if( (AOP_TYPE(left) == AOP_PCODE)
11003 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
11004 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
11006 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
11007 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
11008 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
11009 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
11010 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
11011 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
11015 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
11016 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
11017 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
11023 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
11024 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
11028 pic16_freeAsmop(left,NULL,ic,TRUE);
11029 pic16_freeAsmop(result,NULL,ic,TRUE);
11034 /*-----------------------------------------------------------------*/
11035 /* genPointerGet - generate code for pointer get */
11036 /*-----------------------------------------------------------------*/
11037 static void genPointerGet (iCode *ic)
11039 operand *left, *result ;
11040 sym_link *type, *etype;
11043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11045 left = IC_LEFT(ic);
11046 result = IC_RESULT(ic) ;
11048 /* depending on the type of pointer we need to
11049 move it to the correct pointer register */
11050 type = operandType(left);
11051 etype = getSpec(type);
11054 if (IS_PTR_CONST(type))
11056 if (IS_CODEPTR(type))
11058 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
11060 /* if left is of type of pointer then it is simple */
11061 if (IS_PTR(type) && !IS_FUNC(type->next))
11062 p_type = DCL_TYPE(type);
11064 /* we have to go by the storage class */
11065 p_type = PTR_TYPE(SPEC_OCLS(etype));
11067 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
11069 if (SPEC_OCLS(etype)->codesp ) {
11070 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
11071 //p_type = CPOINTER ;
11074 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
11075 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
11076 /*p_type = FPOINTER ;*/
11078 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
11079 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
11080 /* p_type = PPOINTER; */
11082 if (SPEC_OCLS(etype) == idata )
11083 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
11084 /* p_type = IPOINTER; */
11086 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
11087 /* p_type = POINTER ; */
11090 /* now that we have the pointer type we assign
11091 the pointer values */
11096 genNearPointerGet (left,result,ic);
11100 genPagedPointerGet(left,result,ic);
11104 genFarPointerGet (left,result,ic);
11108 genConstPointerGet (left,result,ic);
11109 //pic16_emitcodePointerGet (left,result,ic);
11114 if (IS_PTR_CONST(type))
11115 genConstPointerGet (left,result,ic);
11118 genGenPointerGet (left,result,ic);
11122 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
11123 "genPointerGet: illegal pointer type");
11129 /*-----------------------------------------------------------------*/
11130 /* genPackBits - generates code for packed bit storage */
11131 /*-----------------------------------------------------------------*/
11132 static void genPackBits (sym_link *etype , operand *result,
11134 char *rname, int p_type)
11143 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11144 blen = SPEC_BLEN(etype);
11145 bstr = SPEC_BSTR(etype);
11147 retype = getSpec(operandType(right));
11149 if(AOP_TYPE(right) == AOP_LIT) {
11150 if((blen == 1) && (bstr < 8)) {
11152 /* it is a single bit, so use the appropriate bit instructions */
11154 DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
11156 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
11157 // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
11158 if((p_type == POINTER) && (result)) {
11159 /* workaround to reduce the extra lfsr instruction */
11161 pic16_emitpcode(POC_BSF,
11162 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
11164 pic16_emitpcode(POC_BCF,
11165 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
11170 pic16_emitpcode(POC_BSF,
11171 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
11173 pic16_emitpcode(POC_BCF,
11174 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
11181 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
11184 if(IS_BITFIELD(retype)
11185 && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
11189 rblen = SPEC_BLEN( retype );
11190 rbstr = SPEC_BSTR( retype );
11193 if(IS_BITFIELD(etype)) {
11194 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0));
11195 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
11197 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
11200 pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr));
11202 if(IS_BITFIELD(etype)) {
11203 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
11205 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
11208 pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0));
11212 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
11214 /* if the bit lenth is less than or */
11215 /* it exactly fits a byte then */
11216 if((shCnt=SPEC_BSTR(etype))
11217 || SPEC_BLEN(etype) <= 8 ) {
11219 /* shift left acc */
11222 /* using PRODL as a temporary register here */
11223 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
11228 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
11229 // pic16_emitcode ("mov","b,a");
11230 // pic16_emitcode("mov","a,@%s",rname);
11234 werror(W_POSSBUG2, __FILE__, __LINE__);
11239 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
11240 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
11241 (unsigned char)(0xff >> (8-bstr))) ));
11242 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
11243 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
11250 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
11251 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
11256 if ( SPEC_BLEN(etype) <= 8 )
11259 pic16_emitcode("inc","%s",rname);
11260 rLen = SPEC_BLEN(etype) ;
11264 /* now generate for lengths greater than one byte */
11267 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
11277 pic16_emitcode("mov","@%s,a",rname);
11279 pic16_emitcode("mov","@%s,%s",rname,l);
11284 pic16_emitcode("movx","@dptr,a");
11289 DEBUGpic16_emitcode(";lcall","__gptrput");
11292 pic16_emitcode ("inc","%s",rname);
11297 /* last last was not complete */
11299 /* save the byte & read byte */
11302 pic16_emitcode ("mov","b,a");
11303 pic16_emitcode("mov","a,@%s",rname);
11307 pic16_emitcode ("mov","b,a");
11308 pic16_emitcode("movx","a,@dptr");
11312 pic16_emitcode ("push","b");
11313 pic16_emitcode ("push","acc");
11314 pic16_emitcode ("lcall","__gptrget");
11315 pic16_emitcode ("pop","b");
11319 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
11320 pic16_emitcode ("orl","a,b");
11323 if (p_type == GPOINTER)
11324 pic16_emitcode("pop","b");
11329 pic16_emitcode("mov","@%s,a",rname);
11333 pic16_emitcode("movx","@dptr,a");
11337 DEBUGpic16_emitcode(";lcall","__gptrput");
11341 /*-----------------------------------------------------------------*/
11342 /* genDataPointerSet - remat pointer to data space */
11343 /*-----------------------------------------------------------------*/
11344 static void genDataPointerSet(operand *right,
11348 int size, offset = 0, resoffset=0 ;
11350 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11351 pic16_aopOp(right,ic,FALSE);
11353 size = AOP_SIZE(right);
11355 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
11358 if ( AOP_TYPE(result) == AOP_PCODE) {
11359 fprintf(stderr,"genDataPointerSet %s, %d\n",
11360 AOP(result)->aopu.pcop->name,
11361 (AOP(result)->aopu.pcop->type == PO_DIR)?
11362 PCOR(AOP(result)->aopu.pcop)->instance:
11363 PCOI(AOP(result)->aopu.pcop)->offset);
11367 if(AOP(result)->aopu.pcop->type == PO_DIR)
11368 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
11371 if (AOP_TYPE(right) == AOP_LIT) {
11374 if(!IS_FLOAT(operandType( right )))
11375 lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
11378 unsigned long lit_int;
11382 /* take care if literal is a float */
11383 info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
11384 lit = info.lit_int;
11387 lit = lit >> (8*offset);
11389 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
11390 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
11392 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
11395 mov2w(AOP(right), offset);
11396 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
11402 pic16_freeAsmop(right,NULL,ic,TRUE);
11407 /*-----------------------------------------------------------------*/
11408 /* genNearPointerSet - pic16_emitcode for near pointer put */
11409 /*-----------------------------------------------------------------*/
11410 static void genNearPointerSet (operand *right,
11417 sym_link *ptype = operandType(result);
11418 sym_link *resetype;
11420 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11421 retype= getSpec(operandType(right));
11422 resetype = getSpec(operandType(result));
11424 pic16_aopOp(result,ic,FALSE);
11426 /* if the result is rematerializable &
11427 * in data space & not a bit variable */
11429 /* and result is not a bit variable */
11430 if (AOP_TYPE(result) == AOP_PCODE
11431 // && AOP_TYPE(result) == AOP_IMMD
11432 && DCL_TYPE(ptype) == POINTER
11433 && !IS_BITFIELD(retype)
11434 && !IS_BITFIELD(resetype)) {
11436 genDataPointerSet (right,result,ic);
11437 pic16_freeAsmop(result,NULL,ic,TRUE);
11441 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11442 pic16_aopOp(right,ic,FALSE);
11443 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11445 /* if the value is already in a pointer register
11446 * then don't need anything more */
11447 if (!AOP_INPREG(AOP(result))) {
11448 /* otherwise get a free pointer register */
11449 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11451 // if( (AOP_TYPE(result) == AOP_PCODE)
11452 // && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
11453 // || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
11454 if(is_LitAOp( AOP(result) ))
11456 if(!IS_BITFIELD(resetype))
11457 pic16_loadFSR0( result ); // patch 10
11459 if(!IS_BITFIELD(resetype)) {
11460 // set up FSR0 with address of result
11461 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
11462 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
11468 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11470 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11472 // pic16_loadFSR0( result );
11474 /* if bitfield then unpack the bits */
11475 if (IS_BITFIELD(resetype)) {
11476 genPackBits (resetype, result, right, NULL, POINTER);
11478 /* we have can just get the values */
11479 int size = AOP_SIZE(right);
11482 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11484 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
11487 //pic16_emitcode("mov","@%s,a",rname);
11488 pic16_emitcode("movf","indf0,w ;1");
11491 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
11492 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
11494 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
11496 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
11498 } else { // no literal //
11500 pic16_emitpcode(POC_MOVFF, //
11501 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
11502 pic16_popCopyReg(&pic16_pc_postinc0))); //
11504 pic16_emitpcode(POC_MOVFF, //
11505 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
11506 pic16_popCopyReg(&pic16_pc_indf0))); //
11514 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11515 /* now some housekeeping stuff */
11517 /* we had to allocate for this iCode */
11518 pic16_freeAsmop(NULL,aop,ic,TRUE);
11520 /* we did not allocate which means left
11521 * already in a pointer register, then
11522 * if size > 0 && this could be used again
11523 * we have to point it back to where it
11525 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11526 if (AOP_SIZE(right) > 1
11527 && !OP_SYMBOL(result)->remat
11528 && ( OP_SYMBOL(result)->liveTo > ic->seq
11531 int size = AOP_SIZE(right) - 1;
11534 pic16_emitcode("decf","fsr0,f");
11535 //pic16_emitcode("dec","%s",rname);
11539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11542 pic16_freeAsmop(right,NULL,ic,TRUE);
11543 pic16_freeAsmop(result,NULL,ic,TRUE);
11546 /*-----------------------------------------------------------------*/
11547 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
11548 /*-----------------------------------------------------------------*/
11549 static void genPagedPointerSet (operand *right,
11554 regs *preg = NULL ;
11558 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11560 retype= getSpec(operandType(right));
11562 pic16_aopOp(result,ic,FALSE);
11564 /* if the value is already in a pointer register
11565 then don't need anything more */
11566 if (!AOP_INPREG(AOP(result))) {
11567 /* otherwise get a free pointer register */
11569 preg = getFreePtr(ic,&aop,FALSE);
11570 pic16_emitcode("mov","%s,%s",
11572 pic16_aopGet(AOP(result),0,FALSE,TRUE));
11573 rname = preg->name ;
11575 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11577 pic16_freeAsmop(result,NULL,ic,TRUE);
11578 pic16_aopOp (right,ic,FALSE);
11580 /* if bitfield then unpack the bits */
11581 if (IS_BITFIELD(retype))
11582 genPackBits (retype,result,right,rname,PPOINTER);
11584 /* we have can just get the values */
11585 int size = AOP_SIZE(right);
11589 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
11592 pic16_emitcode("movx","@%s,a",rname);
11595 pic16_emitcode("inc","%s",rname);
11601 /* now some housekeeping stuff */
11603 /* we had to allocate for this iCode */
11604 pic16_freeAsmop(NULL,aop,ic,TRUE);
11606 /* we did not allocate which means left
11607 already in a pointer register, then
11608 if size > 0 && this could be used again
11609 we have to point it back to where it
11611 if (AOP_SIZE(right) > 1 &&
11612 !OP_SYMBOL(result)->remat &&
11613 ( OP_SYMBOL(result)->liveTo > ic->seq ||
11615 int size = AOP_SIZE(right) - 1;
11617 pic16_emitcode("dec","%s",rname);
11622 pic16_freeAsmop(right,NULL,ic,TRUE);
11627 /*-----------------------------------------------------------------*/
11628 /* genFarPointerSet - set value from far space */
11629 /*-----------------------------------------------------------------*/
11630 static void genFarPointerSet (operand *right,
11631 operand *result, iCode *ic)
11634 sym_link *retype = getSpec(operandType(right));
11636 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11637 pic16_aopOp(result,ic,FALSE);
11639 /* if the operand is already in dptr
11640 then we do nothing else we move the value to dptr */
11641 if (AOP_TYPE(result) != AOP_STR) {
11642 /* if this is remateriazable */
11643 if (AOP_TYPE(result) == AOP_IMMD)
11644 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
11645 else { /* we need to get it byte by byte */
11646 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
11647 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
11648 if (options.model == MODEL_FLAT24)
11650 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
11654 /* so dptr know contains the address */
11655 pic16_freeAsmop(result,NULL,ic,TRUE);
11656 pic16_aopOp(right,ic,FALSE);
11658 /* if bit then unpack */
11659 if (IS_BITFIELD(retype))
11660 genPackBits(retype,result,right,"dptr",FPOINTER);
11662 size = AOP_SIZE(right);
11666 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
11668 pic16_emitcode("movx","@dptr,a");
11670 pic16_emitcode("inc","dptr");
11674 pic16_freeAsmop(right,NULL,ic,TRUE);
11677 /*-----------------------------------------------------------------*/
11678 /* genGenPointerSet - set value from generic pointer space */
11679 /*-----------------------------------------------------------------*/
11681 static void genGenPointerSet (operand *right,
11682 operand *result, iCode *ic)
11684 int i, size, offset, lit;
11685 sym_link *retype = getSpec(operandType(right));
11687 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11689 pic16_aopOp(result,ic,FALSE);
11690 pic16_aopOp(right,ic,FALSE);
11691 size = AOP_SIZE(right);
11694 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11696 /* if the operand is already in dptr
11697 then we do nothing else we move the value to dptr */
11698 if (AOP_TYPE(result) != AOP_STR) {
11699 /* if this is remateriazable */
11700 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11701 // WARNING: anythig until "else" is untested!
11702 if (AOP_TYPE(result) == AOP_IMMD) {
11703 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11704 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
11705 // load FSR0 from immediate
11706 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11710 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11712 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11718 else { /* we need to get it byte by byte */
11719 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11720 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
11722 // set up FSR0 with address of result
11723 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11724 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11726 /* hack hack! see if this the FSR. If so don't load W */
11727 if(AOP_TYPE(right) != AOP_ACC) {
11729 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11731 if(AOP_TYPE(right) == AOP_LIT)
11734 // note: pic16_popGet handles sign extension
11735 for(i=0;i<size;i++) {
11736 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
11738 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
11740 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
11745 for(i=0;i<size;i++) {
11747 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11748 pic16_popCopyReg(&pic16_pc_postinc0)));
11750 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
11751 pic16_popCopyReg(&pic16_pc_indf0)));
11757 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11758 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11760 } // if (AOP_TYPE(result) != AOP_IMMD)
11762 } // if (AOP_TYPE(result) != AOP_STR)
11763 /* so dptr know contains the address */
11766 /* if bit then unpack */
11767 if (IS_BITFIELD(retype))
11768 genPackBits(retype,result,right,"dptr",GPOINTER);
11770 size = AOP_SIZE(right);
11773 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11775 // set up FSR0 with address of result
11776 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
11777 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
11780 if (AOP_TYPE(right) == AOP_LIT) {
11781 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11783 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
11785 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
11787 } else { // no literal
11789 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
11791 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
11799 pic16_freeAsmop(right,NULL,ic,TRUE);
11800 pic16_freeAsmop(result,NULL,ic,TRUE);
11804 static void genGenPointerSet (operand *right,
11805 operand *result, iCode *ic)
11808 sym_link *retype = getSpec(operandType(right));
11811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11813 pic16_aopOp(result,ic,FALSE);
11814 pic16_aopOp(right,ic,FALSE);
11815 size = AOP_SIZE(right);
11817 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11820 /* if bit then unpack */
11821 if (IS_BITFIELD(retype)) {
11822 // pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
11823 genPackBits(retype,result,right,"dptr",GPOINTER);
11827 size = AOP_SIZE(right);
11829 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
11833 /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */
11835 /* value of right+0 is placed on stack, which will be retrieved
11836 * by the support function this restoring the stack. The important
11837 * thing is that there is no need to manually restore stack pointer
11839 pushaop(AOP(right), 0);
11840 // mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0);
11841 if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
11842 if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
11843 if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
11845 /* load address to write to in WREG:FSR0H:FSR0L */
11846 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
11847 pic16_popCopyReg(&pic16_pc_fsr0l)));
11848 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
11849 pic16_popCopyReg(&pic16_pc_prodl)));
11850 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
11853 /* put code here */
11855 case 1: strcpy(fgptrput, "__gptrput1"); break;
11856 case 2: strcpy(fgptrput, "__gptrput2"); break;
11857 case 3: strcpy(fgptrput, "__gptrput3"); break;
11858 case 4: strcpy(fgptrput, "__gptrput4"); break;
11860 werror(W_POSSBUG2, __FILE__, __LINE__);
11864 pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput ));
11869 sym = newSymbol( fgptrput, 0 );
11870 strcpy(sym->rname, fgptrput);
11871 checkAddSym(&externs, sym);
11875 pic16_freeAsmop(right,NULL,ic,TRUE);
11876 pic16_freeAsmop(result,NULL,ic,TRUE);
11879 /*-----------------------------------------------------------------*/
11880 /* genPointerSet - stores the value into a pointer location */
11881 /*-----------------------------------------------------------------*/
11882 static void genPointerSet (iCode *ic)
11884 operand *right, *result ;
11885 sym_link *type, *etype;
11888 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11890 right = IC_RIGHT(ic);
11891 result = IC_RESULT(ic) ;
11893 /* depending on the type of pointer we need to
11894 move it to the correct pointer register */
11895 type = operandType(result);
11896 etype = getSpec(type);
11897 /* if left is of type of pointer then it is simple */
11898 if (IS_PTR(type) && !IS_FUNC(type->next)) {
11899 p_type = DCL_TYPE(type);
11902 /* we have to go by the storage class */
11903 p_type = PTR_TYPE(SPEC_OCLS(etype));
11905 /* if (SPEC_OCLS(etype)->codesp ) { */
11906 /* p_type = CPOINTER ; */
11909 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
11910 /* p_type = FPOINTER ; */
11912 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
11913 /* p_type = PPOINTER ; */
11915 /* if (SPEC_OCLS(etype) == idata ) */
11916 /* p_type = IPOINTER ; */
11918 /* p_type = POINTER ; */
11921 /* now that we have the pointer type we assign
11922 the pointer values */
11927 genNearPointerSet (right,result,ic);
11931 genPagedPointerSet (right,result,ic);
11935 genFarPointerSet (right,result,ic);
11939 genGenPointerSet (right,result,ic);
11943 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
11944 "genPointerSet: illegal pointer type");
11948 /*-----------------------------------------------------------------*/
11949 /* genIfx - generate code for Ifx statement */
11950 /*-----------------------------------------------------------------*/
11951 static void genIfx (iCode *ic, iCode *popIc)
11953 operand *cond = IC_COND(ic);
11956 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11958 pic16_aopOp(cond,ic,FALSE);
11960 /* get the value into acc */
11961 if (AOP_TYPE(cond) != AOP_CRY)
11962 pic16_toBoolean(cond);
11965 /* the result is now in the accumulator */
11966 pic16_freeAsmop(cond,NULL,ic,TRUE);
11968 /* if there was something to be popped then do it */
11972 /* if the condition is a bit variable */
11973 if (isbit && IS_ITEMP(cond) &&
11975 genIfxJump(ic,SPIL_LOC(cond)->rname);
11976 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
11979 if (isbit && !IS_ITEMP(cond))
11980 genIfxJump(ic,OP_SYMBOL(cond)->rname);
11982 genIfxJump(ic,"a");
11988 /*-----------------------------------------------------------------*/
11989 /* genAddrOf - generates code for address of */
11990 /*-----------------------------------------------------------------*/
11991 static void genAddrOf (iCode *ic)
11993 operand *result, *left;
11995 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
11996 pCodeOp *pcop0, *pcop1, *pcop2;
11998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12000 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
12002 sym = OP_SYMBOL( IC_LEFT(ic) );
12005 /* get address of symbol on stack */
12006 DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
12008 fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__,
12009 OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack);
12012 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
12013 pic16_popCopyReg(&pic16_pc_fsr2l),
12014 pic16_popGet(AOP(result), 0)));
12015 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
12016 pic16_popCopyReg(&pic16_pc_fsr2h),
12017 pic16_popGet(AOP(result), 1)));
12019 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( OP_SYMBOL( IC_LEFT(ic))->stack ) /*+ _G.stack_lat*/);
12020 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 0));
12022 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 1));
12027 // if(pic16_debug_verbose) {
12028 // fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
12029 // __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
12032 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
12033 size = AOP_SIZE(IC_RESULT(ic));
12036 /* Assume that what we want the address of is in data space
12037 * since there is no stack on the PIC, yet! -- VR */
12039 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12040 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12041 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12044 pic16_emitpcode(POC_MOVLW, pcop0);
12045 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
12046 pic16_emitpcode(POC_MOVLW, pcop1);
12047 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
12048 pic16_emitpcode(POC_MOVLW, pcop2);
12049 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
12052 pic16_emitpcode(POC_MOVLW, pcop0);
12053 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12054 pic16_emitpcode(POC_MOVLW, pcop1);
12055 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12057 pic16_emitpcode(POC_MOVLW, pcop0);
12058 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12061 pic16_freeAsmop(left, NULL, ic, FALSE);
12063 pic16_freeAsmop(result,NULL,ic,TRUE);
12068 /*-----------------------------------------------------------------*/
12069 /* genFarFarAssign - assignment when both are in far space */
12070 /*-----------------------------------------------------------------*/
12071 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
12073 int size = AOP_SIZE(right);
12076 /* first push the right side on to the stack */
12078 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
12080 pic16_emitcode ("push","acc");
12083 pic16_freeAsmop(right,NULL,ic,FALSE);
12084 /* now assign DPTR to result */
12085 pic16_aopOp(result,ic,FALSE);
12086 size = AOP_SIZE(result);
12088 pic16_emitcode ("pop","acc");
12089 pic16_aopPut(AOP(result),"a",--offset);
12091 pic16_freeAsmop(result,NULL,ic,FALSE);
12096 /*-----------------------------------------------------------------*/
12097 /* genAssign - generate code for assignment */
12098 /*-----------------------------------------------------------------*/
12099 static void genAssign (iCode *ic)
12101 operand *result, *right;
12102 int size, offset,know_W;
12103 unsigned long lit = 0L;
12105 result = IC_RESULT(ic);
12106 right = IC_RIGHT(ic) ;
12108 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12110 /* if they are the same */
12111 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
12114 /* reversed order operands are aopOp'ed so that result operand
12115 * is effective in case right is a stack symbol. This maneauver
12116 * allows to use the _G.resDirect flag later */
12117 pic16_aopOp(result,ic,TRUE);
12118 pic16_aopOp(right,ic,FALSE);
12120 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
12122 /* if they are the same registers */
12123 if (pic16_sameRegs(AOP(right),AOP(result)))
12126 /* if the result is a bit */
12127 if (AOP_TYPE(result) == AOP_CRY) {
12128 /* if the right size is a literal then
12129 we know what the value is */
12130 if (AOP_TYPE(right) == AOP_LIT) {
12132 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
12133 pic16_popGet(AOP(result),0));
12135 if (((int) operandLitValue(right)))
12136 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
12137 AOP(result)->aopu.aop_dir,
12138 AOP(result)->aopu.aop_dir);
12140 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
12141 AOP(result)->aopu.aop_dir,
12142 AOP(result)->aopu.aop_dir);
12146 /* the right is also a bit variable */
12147 if (AOP_TYPE(right) == AOP_CRY) {
12148 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
12149 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12150 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
12152 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
12153 AOP(result)->aopu.aop_dir,
12154 AOP(result)->aopu.aop_dir);
12155 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
12156 AOP(right)->aopu.aop_dir,
12157 AOP(right)->aopu.aop_dir);
12158 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
12159 AOP(result)->aopu.aop_dir,
12160 AOP(result)->aopu.aop_dir);
12164 /* we need to or */
12165 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
12166 pic16_toBoolean(right);
12168 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
12169 //pic16_aopPut(AOP(result),"a",0);
12173 /* bit variables done */
12175 size = AOP_SIZE(result);
12178 if(AOP_TYPE(right) == AOP_LIT) {
12179 if(!IS_FLOAT(operandType( right )))
12180 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
12183 unsigned long lit_int;
12187 /* take care if literal is a float */
12188 info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
12189 lit = info.lit_int;
12193 // fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
12194 // sizeof(unsigned long int), sizeof(float));
12196 if(AOP_TYPE(right) != AOP_LIT
12197 && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
12198 && !IS_FUNC(OP_SYM_TYPE(right))
12200 DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
12201 // fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
12203 // set up table pointer
12204 if( (AOP_TYPE(right) == AOP_PCODE)
12205 && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
12206 // || (AOP(right)->aopu.pcop->type == PO_DIR)
12210 // fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
12211 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
12212 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
12213 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
12214 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
12215 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
12216 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
12218 // fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
12219 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
12220 pic16_popCopyReg(&pic16_pc_tblptrl)));
12221 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
12222 pic16_popCopyReg(&pic16_pc_tblptrh)));
12223 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
12224 pic16_popCopyReg(&pic16_pc_tblptru)));
12227 size = min(AOP_SIZE(right), AOP_SIZE(result));
12229 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
12230 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
12231 pic16_popGet(AOP(result),offset)));
12235 if(AOP_SIZE(result) > AOP_SIZE(right)) {
12236 size = AOP_SIZE(result) - AOP_SIZE(right);
12238 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
12248 /* VR - What is this?! */
12249 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
12250 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12251 if(aopIdx(AOP(result),0) == 4) {
12253 /* this is a workaround to save value of right into wreg too,
12254 * value of wreg is going to be used later */
12255 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12256 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
12257 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12261 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
12267 DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
12268 if(AOP_TYPE(right) == AOP_LIT) {
12270 if(know_W != (lit&0xff))
12271 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
12273 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12275 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
12279 } else if (AOP_TYPE(right) == AOP_CRY) {
12280 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
12282 // debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
12283 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
12284 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
12286 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
12287 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
12288 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12290 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12292 if(!_G.resDirect) /* use this aopForSym feature */
12293 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
12300 pic16_freeAsmop (right,NULL,ic,FALSE);
12301 pic16_freeAsmop (result,NULL,ic,TRUE);
12304 /*-----------------------------------------------------------------*/
12305 /* genJumpTab - generates code for jump table */
12306 /*-----------------------------------------------------------------*/
12307 static void genJumpTab (iCode *ic)
12312 pCodeOp *jt_offs_hi;
12315 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12317 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
12318 /* get the condition into accumulator */
12319 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
12321 /* multiply by three */
12322 pic16_emitcode("add","a,acc");
12323 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
12325 jtab = newiTempLabel(NULL);
12326 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
12327 pic16_emitcode("jmp","@a+dptr");
12328 pic16_emitcode("","%05d_DS_:",jtab->key+100);
12331 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
12332 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
12334 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
12335 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
12336 pic16_emitpLabel(jtab->key);
12340 jt_offs = pic16_popGetTempReg(0);
12341 jt_offs_hi = pic16_popGetTempReg(1);
12342 jt_label = pic16_popGetLabel (jtab->key);
12343 //fprintf (stderr, "Creating jump table...\n");
12345 // calculate offset into jump table (idx * sizeof (GOTO))
12346 pic16_emitpcode(POC_CLRF , jt_offs_hi);
12347 pic16_emitpcode(POC_RLCFW , pic16_popGet(AOP(IC_JTCOND(ic)),0));
12348 pic16_emitpcode(POC_RLCF , jt_offs_hi);
12349 pic16_emitpcode(POC_RLCFW , pic16_popCopyReg(&pic16_pc_wreg));
12350 pic16_emitpcode(POC_RLCF , jt_offs_hi);
12351 pic16_emitpcode(POC_ANDLW , pic16_popGetLit (0xFC));
12352 pic16_emitpcode(POC_MOVWF , jt_offs);
12354 // prepare PCLATx (set to first entry in jump table)
12355 pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 2, 0));
12356 pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pclatu));
12357 pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 1, 0));
12358 pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pclath));
12359 pic16_emitpcode(POC_MOVLW , pic16_popGetImmd(jt_label->name, 0, 0));
12361 // set PCLATx to selected entry (new PCL is stored in jt_offs)
12362 pic16_emitpcode(POC_ADDWF , jt_offs);
12363 pic16_emitpcode(POC_MOVFW , jt_offs_hi);
12364 pic16_emitpcode(POC_ADDWFC, pic16_popCopyReg(&pic16_pc_pclath));
12366 pic16_emitpcode(POC_INCF , pic16_popCopyReg(&pic16_pc_pclatu));
12368 // release temporaries and prepare jump into table (new PCL --> WREG)
12369 pic16_emitpcode(POC_MOVFW , jt_offs);
12370 pic16_popReleaseTempReg (jt_offs_hi, 1);
12371 pic16_popReleaseTempReg (jt_offs, 0);
12373 // jump into the table
12374 pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl));
12376 pic16_emitpLabelFORCE(jtab->key);
12379 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
12381 /* now generate the jump labels */
12382 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
12383 jtab = setNextItem(IC_JTLABELS(ic))) {
12384 // pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
12385 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
12391 /*-----------------------------------------------------------------*/
12392 /* genMixedOperation - gen code for operators between mixed types */
12393 /*-----------------------------------------------------------------*/
12395 TSD - Written for the PIC port - but this unfortunately is buggy.
12396 This routine is good in that it is able to efficiently promote
12397 types to different (larger) sizes. Unfortunately, the temporary
12398 variables that are optimized out by this routine are sometimes
12399 used in other places. So until I know how to really parse the
12400 iCode tree, I'm going to not be using this routine :(.
12402 static int genMixedOperation (iCode *ic)
12405 operand *result = IC_RESULT(ic);
12406 sym_link *ctype = operandType(IC_LEFT(ic));
12407 operand *right = IC_RIGHT(ic);
12413 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
12415 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12421 nextright = IC_RIGHT(nextic);
12422 nextleft = IC_LEFT(nextic);
12423 nextresult = IC_RESULT(nextic);
12425 pic16_aopOp(right,ic,FALSE);
12426 pic16_aopOp(result,ic,FALSE);
12427 pic16_aopOp(nextright, nextic, FALSE);
12428 pic16_aopOp(nextleft, nextic, FALSE);
12429 pic16_aopOp(nextresult, nextic, FALSE);
12431 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
12433 operand *t = right;
12437 pic16_emitcode(";remove right +","");
12439 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
12441 operand *t = right;
12445 pic16_emitcode(";remove left +","");
12449 big = AOP_SIZE(nextleft);
12450 small = AOP_SIZE(nextright);
12452 switch(nextic->op) {
12455 pic16_emitcode(";optimize a +","");
12456 /* if unsigned or not an integral type */
12457 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
12458 pic16_emitcode(";add a bit to something","");
12461 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
12463 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
12464 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
12465 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
12467 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
12475 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
12476 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
12477 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
12480 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
12482 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
12483 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
12484 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
12485 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
12486 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
12489 pic16_emitcode("rlf","known_zero,w");
12496 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
12497 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
12498 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
12500 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
12510 pic16_freeAsmop(right,NULL,ic,TRUE);
12511 pic16_freeAsmop(result,NULL,ic,TRUE);
12512 pic16_freeAsmop(nextright,NULL,ic,TRUE);
12513 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
12515 nextic->generated = 1;
12522 /*-----------------------------------------------------------------*/
12523 /* genCast - gen code for casting */
12524 /*-----------------------------------------------------------------*/
12525 static void genCast (iCode *ic)
12527 operand *result = IC_RESULT(ic);
12528 sym_link *ctype = operandType(IC_LEFT(ic));
12529 sym_link *rtype = operandType(IC_RIGHT(ic));
12530 sym_link *restype = operandType(IC_RESULT(ic));
12531 operand *right = IC_RIGHT(ic);
12534 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12537 /* if they are equivalent then do nothing */
12538 // if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
12541 pic16_aopOp(right,ic,FALSE) ;
12542 pic16_aopOp(result,ic,FALSE);
12544 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
12547 /* if the result is a bit */
12548 if (AOP_TYPE(result) == AOP_CRY) {
12550 /* if the right size is a literal then
12551 * we know what the value is */
12552 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12554 if (AOP_TYPE(right) == AOP_LIT) {
12555 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
12556 pic16_popGet(AOP(result),0));
12558 if (((int) operandLitValue(right)))
12559 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
12560 AOP(result)->aopu.aop_dir,
12561 AOP(result)->aopu.aop_dir);
12563 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
12564 AOP(result)->aopu.aop_dir,
12565 AOP(result)->aopu.aop_dir);
12569 /* the right is also a bit variable */
12570 if (AOP_TYPE(right) == AOP_CRY) {
12572 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12574 pic16_emitcode("clrc","");
12575 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
12576 AOP(right)->aopu.aop_dir,
12577 AOP(right)->aopu.aop_dir);
12578 pic16_aopPut(AOP(result),"c",0);
12582 /* we need to or */
12583 if (AOP_TYPE(right) == AOP_REG) {
12584 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
12585 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
12586 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
12588 pic16_toBoolean(right);
12589 pic16_aopPut(AOP(result),"a",0);
12593 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
12596 size = AOP_SIZE(result);
12598 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12600 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
12601 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
12602 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
12605 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12610 if(IS_BITFIELD(getSpec(restype))
12611 && IS_BITFIELD(getSpec(rtype))) {
12612 DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
12615 /* if they are the same size : or less */
12616 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
12618 /* if they are in the same place */
12619 if (pic16_sameRegs(AOP(right),AOP(result)))
12622 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12624 if (IS_PTR_CONST(rtype))
12626 if (IS_CODEPTR(rtype))
12628 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
12631 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
12633 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
12635 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
12638 if(AOP_TYPE(right) == AOP_IMMD) {
12639 pCodeOp *pcop0, *pcop1, *pcop2;
12640 symbol *sym = OP_SYMBOL( right );
12642 size = AOP_SIZE(result);
12644 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12646 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12648 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
12651 pic16_emitpcode(POC_MOVLW, pcop0);
12652 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
12653 pic16_emitpcode(POC_MOVLW, pcop1);
12654 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
12655 pic16_emitpcode(POC_MOVLW, pcop2);
12656 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
12659 pic16_emitpcode(POC_MOVLW, pcop0);
12660 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12661 pic16_emitpcode(POC_MOVLW, pcop1);
12662 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12664 pic16_emitpcode(POC_MOVLW, pcop0);
12665 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12669 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12670 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
12671 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
12672 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
12673 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
12674 if(AOP_SIZE(result) <2)
12675 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
12677 /* if they in different places then copy */
12678 size = AOP_SIZE(result);
12681 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
12682 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12689 /* if the result is of type pointer */
12690 if (IS_PTR(ctype)) {
12692 sym_link *type = operandType(right);
12693 sym_link *etype = getSpec(type);
12695 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
12697 /* pointer to generic pointer */
12698 if (IS_GENPTR(ctype)) {
12702 p_type = DCL_TYPE(type);
12704 /* we have to go by the storage class */
12705 p_type = PTR_TYPE(SPEC_OCLS(etype));
12707 /* if (SPEC_OCLS(etype)->codesp ) */
12708 /* p_type = CPOINTER ; */
12710 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
12711 /* p_type = FPOINTER ; */
12713 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
12714 /* p_type = PPOINTER; */
12716 /* if (SPEC_OCLS(etype) == idata ) */
12717 /* p_type = IPOINTER ; */
12719 /* p_type = POINTER ; */
12722 /* the first two bytes are known */
12723 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
12724 size = GPTRSIZE - 1;
12727 if(offset < AOP_SIZE(right)) {
12728 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
12729 mov2f(AOP(result), AOP(right), offset);
12731 if ((AOP_TYPE(right) == AOP_PCODE) &&
12732 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
12733 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
12734 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
12737 pic16_aopPut(AOP(result),
12738 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12743 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
12746 /* the last byte depending on type */
12750 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
12751 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1));
12752 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
12756 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12760 pic16_emitcode(";BUG!? ","%d",__LINE__);
12764 pic16_emitcode(";BUG!? ","%d",__LINE__);
12769 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
12773 /* this should never happen */
12774 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
12775 "got unknown pointer type");
12778 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
12782 /* just copy the pointers */
12783 size = AOP_SIZE(result);
12786 pic16_aopPut(AOP(result),
12787 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
12796 /* so we now know that the size of destination is greater
12797 than the size of the source.
12798 Now, if the next iCode is an operator then we might be
12799 able to optimize the operation without performing a cast.
12801 if(genMixedOperation(ic))
12804 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
12806 /* we move to result for the size of source */
12807 size = AOP_SIZE(right);
12810 mov2f(AOP(result), AOP(right), offset);
12814 /* now depending on the sign of the destination */
12815 size = AOP_SIZE(result) - AOP_SIZE(right);
12816 /* if unsigned or not an integral type */
12817 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
12819 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
12821 /* we need to extend the sign :( */
12824 /* Save one instruction of casting char to int */
12825 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
12826 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12827 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
12829 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
12832 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12834 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
12836 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
12839 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
12844 pic16_freeAsmop(right,NULL,ic,TRUE);
12845 pic16_freeAsmop(result,NULL,ic,TRUE);
12849 /*-----------------------------------------------------------------*/
12850 /* genDjnz - generate decrement & jump if not zero instrucion */
12851 /*-----------------------------------------------------------------*/
12852 static int genDjnz (iCode *ic, iCode *ifx)
12854 symbol *lbl, *lbl1;
12855 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12860 /* if the if condition has a false label
12861 then we cannot save */
12865 /* if the minus is not of the form
12867 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
12868 !IS_OP_LITERAL(IC_RIGHT(ic)))
12871 if (operandLitValue(IC_RIGHT(ic)) != 1)
12874 /* if the size of this greater than one then no
12876 if (getSize(operandType(IC_RESULT(ic))) > 1)
12879 /* otherwise we can save BIG */
12880 lbl = newiTempLabel(NULL);
12881 lbl1= newiTempLabel(NULL);
12883 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12885 if (IS_AOP_PREG(IC_RESULT(ic))) {
12886 pic16_emitcode("dec","%s",
12887 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12888 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12889 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
12893 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
12894 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
12896 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
12897 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
12901 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12902 ifx->generated = 1;
12906 /*-----------------------------------------------------------------*/
12907 /* genReceive - generate code for a receive iCode */
12908 /*-----------------------------------------------------------------*/
12909 static void genReceive (iCode *ic)
12911 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
12914 fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__,
12915 OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack);
12917 // pic16_DumpOp(__FUNCTION__, IC_RESULT(ic));
12919 if (isOperandInFarSpace(IC_RESULT(ic))
12920 && ( OP_SYMBOL(IC_RESULT(ic))->isspilt
12921 || IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
12923 int size = getSize(operandType(IC_RESULT(ic)));
12924 int offset = pic16_fReturnSizePic - size;
12928 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
12929 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
12933 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
12935 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12936 size = AOP_SIZE(IC_RESULT(ic));
12939 pic16_emitcode ("pop","acc");
12940 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
12943 DEBUGpic16_emitcode ("; ***","2 %s %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
12946 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
12948 assignResultValue(IC_RESULT(ic), 0);
12951 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
12954 /*-----------------------------------------------------------------*/
12955 /* genDummyRead - generate code for dummy read of volatiles */
12956 /*-----------------------------------------------------------------*/
12958 genDummyRead (iCode * ic)
12960 pic16_emitcode ("; genDummyRead","");
12961 pic16_emitcode ("; not implemented","");
12966 /*-----------------------------------------------------------------*/
12967 /* genpic16Code - generate code for pic16 based controllers */
12968 /*-----------------------------------------------------------------*/
12970 * At this point, ralloc.c has gone through the iCode and attempted
12971 * to optimize in a way suitable for a PIC. Now we've got to generate
12972 * PIC instructions that correspond to the iCode.
12974 * Once the instructions are generated, we'll pass through both the
12975 * peep hole optimizer and the pCode optimizer.
12976 *-----------------------------------------------------------------*/
12978 void genpic16Code (iCode *lic)
12983 lineHead = lineCurr = NULL;
12985 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
12986 pic16_addpBlock(pb);
12989 /* if debug information required */
12990 if (options.debug && currFunc) {
12992 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
12997 for (ic = lic ; ic ; ic = ic->next ) {
12999 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
13000 if ( cln != ic->lineno ) {
13001 if ( options.debug ) {
13002 debugFile->writeCLine (ic);
13005 if(!options.noCcodeInAsm) {
13006 pic16_addpCode2pBlock(pb,
13007 pic16_newpCodeCSource(ic->lineno, ic->filename,
13008 printCLine(ic->filename, ic->lineno)));
13014 if(options.iCodeInAsm) {
13016 /* insert here code to print iCode as comment */
13017 l = Safe_strdup(printILine(ic));
13018 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
13021 /* if the result is marked as
13022 spilt and rematerializable or code for
13023 this has already been generated then
13025 if (resultRemat(ic) || ic->generated )
13028 /* depending on the operation */
13047 /* IPOP happens only when trying to restore a
13048 spilt live range, if there is an ifx statement
13049 following this pop then the if statement might
13050 be using some of the registers being popped which
13051 would destroy the contents of the register so
13052 we need to check for this condition and handle it */
13054 ic->next->op == IFX &&
13055 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
13056 genIfx (ic->next,ic);
13074 genEndFunction (ic);
13090 pic16_genPlus (ic) ;
13094 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
13095 pic16_genMinus (ic);
13111 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
13115 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
13122 /* note these two are xlated by algebraic equivalence
13123 during parsing SDCC.y */
13124 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
13125 "got '>=' or '<=' shouldn't have come here");
13129 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
13141 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
13145 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
13149 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
13173 genRightShift (ic);
13176 case GET_VALUE_AT_ADDRESS:
13181 if (POINTER_SET(ic))
13208 addSet(&_G.sendSet,ic);
13209 /* create a reversed list of SEND iCodes */
13210 // addSetHead(&_G.sendSet, ic);
13213 case DUMMY_READ_VOLATILE:
13223 /* now we are ready to call the
13224 peep hole optimizer */
13225 if (!options.nopeep) {
13226 peepHole (&lineHead);
13228 /* now do the actual printing */
13229 printLine (lineHead, codeOutFile);
13232 DFPRINTF((stderr,"printing pBlock\n\n"));
13233 pic16_printpBlock(stdout,pb);