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 *dsr, asmop *src, int offset);
62 //static int aopIdx (asmop *aop, int offset);
64 int pic16_labelOffset=0;
65 extern int pic16_debug_verbose;
66 static int optimized_for_speed = 0;
72 /* max_key keeps track of the largest label number used in
73 a function. This is then used to adjust the label offset
74 for the next function.
77 static int GpsuedoStkPtr=0;
79 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
80 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
82 unsigned int pic16aopLiteral (value *val, int offset);
83 const char *pic16_AopType(short type);
84 static iCode *ifxForOp ( operand *op, iCode *ic );
86 void pic16_pushpCodeOp(pCodeOp *pcop);
87 void pic16_poppCodeOp(pCodeOp *pcop);
89 static bool is_LitOp(operand *op);
90 static bool is_LitAOp(asmop *aop);
93 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
95 /* this is the down and dirty file with all kinds of
96 kludgy & hacky stuff. This is what it is all about
97 CODE GENERATION for a specific MCU . some of the
98 routines may be reusable, will have to see */
100 static char *zero = "#0x00";
101 static char *one = "#0x01";
102 static char *spname = "sp";
106 * Function return value policy (MSB-->LSB):
108 * 16 bits -> PRODL:WREG
109 * 24 bits -> PRODH:PRODL:WREG
110 * 32 bits -> FSR0L:PRODH:PRODL:WREG
111 * >32 bits -> on stack, and FSR0 points to the beginning
116 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
117 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
118 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
119 static char **fReturn = fReturnpic16;
121 static char *accUse[] = {"WREG"};
123 //static short rbank = -1;
139 /* Resolved ifx structure. This structure stores information
140 about an iCode ifx that makes it easier to generate code.
142 typedef struct resolvedIfx {
143 symbol *lbl; /* pointer to a label */
144 int condition; /* true or false ifx */
145 int generated; /* set true when the code associated with the ifx
149 extern int pic16_ptrRegReq ;
150 extern int pic16_nRegs;
151 extern FILE *codeOutFile;
152 static void saverbank (int, iCode *,bool);
154 static lineNode *lineHead = NULL;
155 static lineNode *lineCurr = NULL;
157 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
158 0xE0, 0xC0, 0x80, 0x00};
159 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
160 0x07, 0x03, 0x01, 0x00};
164 /*-----------------------------------------------------------------*/
165 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
166 /* exponent of 2 is returned, otherwise -1 is */
168 /* note that this is similar to the function `powof2' in SDCCsymt */
172 /*-----------------------------------------------------------------*/
173 static int my_powof2 (unsigned long num)
176 if( (num & (num-1)) == 0) {
189 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
191 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
193 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
194 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
195 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
196 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
197 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
198 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
199 ((result) ? AOP_SIZE(result) : 0));
202 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
205 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
207 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
208 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
209 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
210 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
211 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
212 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
216 void pic16_emitpcomment (char *fmt, ...)
219 char lb[INITIAL_INLINEASM];
225 vsprintf(lb+1,fmt,ap);
227 while (isspace(*lbp)) lbp++;
230 lineCurr = (lineCurr ?
231 connectLine(lineCurr,newLineNode(lb)) :
232 (lineHead = newLineNode(lb)));
233 lineCurr->isInline = _G.inLine;
234 lineCurr->isDebug = _G.debugLine;
236 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
239 // fprintf(stderr, "%s\n", lb);
242 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
245 char lb[INITIAL_INLINEASM];
248 if(!pic16_debug_verbose)
255 sprintf(lb,"%s\t",inst);
257 sprintf(lb,"%s",inst);
258 vsprintf(lb+(strlen(lb)),fmt,ap);
262 while (isspace(*lbp)) lbp++;
265 lineCurr = (lineCurr ?
266 connectLine(lineCurr,newLineNode(lb)) :
267 (lineHead = newLineNode(lb)));
268 lineCurr->isInline = _G.inLine;
269 lineCurr->isDebug = _G.debugLine;
271 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
274 // fprintf(stderr, "%s\n", lb);
277 void pic16_emitpLabel(int key)
279 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset));
282 void pic16_emitpLabelFORCE(int key)
284 pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset));
287 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
291 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
293 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
295 // fprintf(stderr, "%s\n", pcop->name);
298 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
301 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
307 #define pic16_emitcode DEBUGpic16_emitcode
309 /*-----------------------------------------------------------------*/
310 /* pic16_emitcode - writes the code into a file : for now it is simple */
311 /*-----------------------------------------------------------------*/
312 void pic16_emitcode (char *inst,char *fmt, ...)
315 char lb[INITIAL_INLINEASM];
322 sprintf(lb,"%s\t",inst);
324 sprintf(lb,"%s",inst);
325 vsprintf(lb+(strlen(lb)),fmt,ap);
329 while (isspace(*lbp)) lbp++;
332 lineCurr = (lineCurr ?
333 connectLine(lineCurr,newLineNode(lb)) :
334 (lineHead = newLineNode(lb)));
335 lineCurr->isInline = _G.inLine;
336 lineCurr->isDebug = _G.debugLine;
338 // VR fprintf(stderr, "lb = <%s>\n", lbp);
340 // if(pic16_debug_verbose)
341 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
348 /*-----------------------------------------------------------------*/
349 /* pic16_emitDebuggerSymbol - associate the current code location */
350 /* with a debugger symbol */
351 /*-----------------------------------------------------------------*/
353 pic16_emitDebuggerSymbol (char * debugSym)
356 pic16_emitcode (";", "%s ==.", debugSym);
361 /*-----------------------------------------------------------------*/
362 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
363 /*-----------------------------------------------------------------*/
364 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
366 // bool r0iu = FALSE , r1iu = FALSE;
367 // bool r0ou = FALSE , r1ou = FALSE;
368 bool fsr0iu = FALSE, fsr0ou;
369 bool fsr2iu = FALSE, fsr2ou;
371 fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result);
374 fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
375 fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
377 fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
378 fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
380 if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
381 fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
382 DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
385 /* no usage of FSR2 */
386 if(!fsr2iu && !fsr2ou) {
387 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
388 (*aopp)->type = AOP_FSR2;
390 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
393 if(!fsr0iu && !fsr0ou) {
394 ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
395 (*aopp)->type = AOP_FSR0;
397 return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
400 /* now we know they both have usage */
401 /* if fsr0 not used in this instruction */
403 if (!_G.fsr0Pushed) {
404 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
405 pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
409 ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
410 (*aopp)->type = AOP_FSR0;
412 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
416 fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
421 /* the logic: if r0 & r1 used in the instruction
422 then we are in trouble otherwise */
424 /* first check if r0 & r1 are used by this
425 instruction, in which case we are in trouble */
426 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
427 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
432 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
433 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
435 /* if no usage of r0 then return it */
436 if (!r0iu && !r0ou) {
437 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
438 (*aopp)->type = AOP_R0;
440 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
443 /* if no usage of r1 then return it */
444 if (!r1iu && !r1ou) {
445 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
446 (*aopp)->type = AOP_R1;
448 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
451 /* now we know they both have usage */
452 /* if r0 not used in this instruction */
454 /* push it if not already pushed */
456 //pic16_emitcode ("push","%s",
457 // pic16_regWithIdx(R0_IDX)->dname);
461 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
462 (*aopp)->type = AOP_R0;
464 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
467 /* if r1 not used then */
470 /* push it if not already pushed */
472 //pic16_emitcode ("push","%s",
473 // pic16_regWithIdx(R1_IDX)->dname);
477 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
478 (*aopp)->type = AOP_R1;
479 return pic16_regWithIdx(R1_IDX);
483 /* I said end of world but not quite end of world yet */
484 /* if this is a result then we can push it on the stack*/
486 (*aopp)->type = AOP_STK;
490 /* other wise this is true end of the world */
491 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
492 "getFreePtr should never reach here");
497 /*-----------------------------------------------------------------*/
498 /* newAsmop - creates a new asmOp */
499 /*-----------------------------------------------------------------*/
500 static asmop *newAsmop (short type)
504 aop = Safe_calloc(1,sizeof(asmop));
509 static void genSetDPTR(int n)
513 pic16_emitcode(";", "Select standard DPTR");
514 pic16_emitcode("mov", "dps, #0x00");
518 pic16_emitcode(";", "Select alternate DPTR");
519 pic16_emitcode("mov", "dps, #0x01");
523 /*-----------------------------------------------------------------*/
524 /* resolveIfx - converts an iCode ifx into a form more useful for */
525 /* generating code */
526 /*-----------------------------------------------------------------*/
527 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
530 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
536 resIfx->condition = 1; /* assume that the ifx is true */
537 resIfx->generated = 0; /* indicate that the ifx has not been used */
540 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
543 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
544 __FUNCTION__,__LINE__,resIfx->lbl->key);
549 resIfx->lbl = IC_TRUE(ifx);
551 resIfx->lbl = IC_FALSE(ifx);
552 resIfx->condition = 0;
557 DEBUGpic16_emitcode("; ***","ifx true is non-null");
559 DEBUGpic16_emitcode("; ***","ifx false is non-null");
563 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset);
567 /*-----------------------------------------------------------------*/
568 /* pointerCode - returns the code for a pointer type */
569 /*-----------------------------------------------------------------*/
570 static int pointerCode (sym_link *etype)
573 return PTR_TYPE(SPEC_OCLS(etype));
578 /*-----------------------------------------------------------------*/
579 /* aopForSym - for a true symbol */
580 /*-----------------------------------------------------------------*/
581 static asmop *aopForSym (iCode *ic, operand *op, bool result)
583 symbol *sym=OP_SYMBOL(op);
585 memmap *space= SPEC_OCLS(sym->etype);
587 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
589 // sym = OP_SYMBOL(op);
591 /* if already has one */
593 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
597 /* if symbol was initially placed onStack then we must re-place it
598 * to direct memory, since pic16 does not have a specific stack */
600 fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
605 /* assign depending on the storage class */
606 /* if it is on the stack or indirectly addressable */
607 /* space we need to assign either r0 or r1 to it */
608 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
610 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
611 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
613 sym->aop = aop = newAsmop(0);
614 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
615 aop->size = getSize(sym->type);
617 fprintf(stderr, "%s:%d\t%s\n", __FILE__, __LINE__, __FUNCTION__);
620 // sym->aop = aop = newAsmop (AOP_REG);
621 // aop->aopu.aop_dir = sym->name; //sym->rname ;
622 // aop->aopu.aop_reg[0] = pic16_regWithIdx(IDX_PLUSW0); //pic16_pc_plusw2.r;
623 // aop->size = getSize(sym->type);
624 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
627 // pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
630 // pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_fsr2l), pic16_popCopyReg(&pic16_pc_fsr0l)));
631 // pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_fsr2h), pic16_popCopyReg(&pic16_pc_fsr0h)));
634 /* initialise for stack access via frame pointer */
635 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
637 // pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
638 // pic16_popCopyReg(&pic16_pc_plusw2), pic16_popCopyReg(&pic16_pc_kzero)));
641 // pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
648 /* now assign the address of the variable to
649 the pointer register */
650 if (aop->type != AOP_STK) {
654 pic16_emitcode("push","acc");
656 pic16_emitcode("mov","a,_bp");
657 pic16_emitcode("add","a,#0x%02x",
659 ((char)(sym->stack - _G.nRegsSaved )) :
660 ((char)sym->stack)) & 0xff);
661 pic16_emitcode("mov","%s,a",
662 aop->aopu.aop_ptr->name);
665 pic16_emitcode("pop","acc");
667 pic16_emitcode("mov","%s,#%s",
668 aop->aopu.aop_ptr->name,
670 aop->paged = space->paged;
672 aop->aopu.aop_stk = sym->stack;
680 if (sym->onStack && options.stack10bit)
682 /* It's on the 10 bit stack, which is located in
686 //DEBUGpic16_emitcode(";","%d",__LINE__);
689 pic16_emitcode("push","acc");
691 pic16_emitcode("mov","a,_bp");
692 pic16_emitcode("add","a,#0x%02x",
694 ((char)(sym->stack - _G.nRegsSaved )) :
695 ((char)sym->stack)) & 0xff);
698 pic16_emitcode ("mov","dpx1,#0x40");
699 pic16_emitcode ("mov","dph1,#0x00");
700 pic16_emitcode ("mov","dpl1, a");
704 pic16_emitcode("pop","acc");
706 sym->aop = aop = newAsmop(AOP_DPTR2);
707 aop->size = getSize(sym->type);
711 //DEBUGpic16_emitcode(";","%d",__LINE__);
712 /* if in bit space */
713 if (IN_BITSPACE(space)) {
714 sym->aop = aop = newAsmop (AOP_CRY);
715 aop->aopu.aop_dir = sym->rname ;
716 aop->size = getSize(sym->type);
717 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
720 /* if it is in direct space */
721 if (IN_DIRSPACE(space)) {
722 sym->aop = aop = newAsmop (AOP_DIR);
723 aop->aopu.aop_dir = sym->rname ;
724 aop->size = getSize(sym->type);
725 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
726 pic16_allocDirReg( IC_LEFT(ic) );
730 if (IN_FARSPACE(space)) {
731 sym->aop = aop = newAsmop (AOP_DIR);
732 aop->aopu.aop_dir = sym->rname ;
733 aop->size = getSize(sym->type);
734 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
735 pic16_allocDirReg( IC_LEFT(ic) );
740 /* special case for a function */
741 if (IS_FUNC(sym->type)) {
742 sym->aop = aop = newAsmop(AOP_IMMD);
743 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
744 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
745 strcpy(aop->aopu.aop_immd,sym->rname);
746 aop->size = FPTRSIZE;
747 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
753 /* only remaining is far space */
754 /* in which case DPTR gets the address */
755 sym->aop = aop = newAsmop(AOP_PCODE);
757 /* change the next if to 1 to revert to good old immediate code */
758 if(IN_CODESPACE(space)) {
759 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
760 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
761 PCOI(aop->aopu.pcop)->index = 0;
763 /* try to allocate via direct register */
764 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
765 // aop->size = getSize( sym->type );
768 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
769 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
772 if(!pic16_allocDirReg (IC_LEFT(ic)))
776 if(IN_DIRSPACE( space ))
778 else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
779 aop->size = FPTRSIZE;
780 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
781 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
786 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
788 /* if it is in code space */
789 if (IN_CODESPACE(space))
795 /*-----------------------------------------------------------------*/
796 /* aopForRemat - rematerialzes an object */
797 /*-----------------------------------------------------------------*/
798 static asmop *aopForRemat (operand *op) // x symbol *sym)
800 symbol *sym = OP_SYMBOL(op);
801 iCode *ic = NULL, *oldic;
802 asmop *aop = newAsmop(AOP_PCODE);
808 ic = sym->rematiCode;
810 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
812 if(IS_OP_POINTER(op)) {
813 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
819 // pic16_emitpcomment("ic: %s\n", printILine(ic));
822 val += (int) operandLitValue(IC_RIGHT(ic));
823 } else if (ic->op == '-') {
824 val -= (int) operandLitValue(IC_RIGHT(ic));
828 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
831 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
833 if(!op->isaddr)viaimmd++; else viaimmd=0;
835 /* set the following if to 1 to revert to good old immediate code */
836 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
839 DEBUGpic16_emitcode("%s:%d immediate", __FILE__, __LINE__);
841 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
844 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
846 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
849 PCOI(aop->aopu.pcop)->index = val;
851 DEBUGpic16_emitcode("%s:%d dir", __FILE__, __LINE__);
853 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
854 getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
855 // aop->size = AOP_SIZE( IC_LEFT(ic) );
859 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
860 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
862 val, IS_PTR_CONST(operandType(op)));
864 val, IS_CODEPTR(operandType(op)));
867 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
869 pic16_allocDirReg (IC_LEFT(ic));
871 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
878 static int aopIdx (asmop *aop, int offset)
883 if(aop->type != AOP_REG)
886 return aop->aopu.aop_reg[offset]->rIdx;
891 /*-----------------------------------------------------------------*/
892 /* regsInCommon - two operands have some registers in common */
893 /*-----------------------------------------------------------------*/
894 static bool regsInCommon (operand *op1, operand *op2)
899 /* if they have registers in common */
900 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
903 sym1 = OP_SYMBOL(op1);
904 sym2 = OP_SYMBOL(op2);
906 if (sym1->nRegs == 0 || sym2->nRegs == 0)
909 for (i = 0 ; i < sym1->nRegs ; i++) {
914 for (j = 0 ; j < sym2->nRegs ;j++ ) {
918 if (sym2->regs[j] == sym1->regs[i])
926 /*-----------------------------------------------------------------*/
927 /* operandsEqu - equivalent */
928 /*-----------------------------------------------------------------*/
929 static bool operandsEqu ( operand *op1, operand *op2)
933 /* if they not symbols */
934 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
937 sym1 = OP_SYMBOL(op1);
938 sym2 = OP_SYMBOL(op2);
940 /* if both are itemps & one is spilt
941 and the other is not then false */
942 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
943 sym1->isspilt != sym2->isspilt )
946 /* if they are the same */
950 if (sym1->rname[0] && sym2->rname[0]
951 && strcmp (sym1->rname, sym2->rname) == 0)
955 /* if left is a tmp & right is not */
959 (sym1->usl.spillLoc == sym2))
966 (sym2->usl.spillLoc == sym1))
972 /*-----------------------------------------------------------------*/
973 /* pic16_sameRegs - two asmops have the same registers */
974 /*-----------------------------------------------------------------*/
975 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
982 DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
983 pic16_AopType(aop1->type), pic16_AopType(aop2->type));
985 if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
988 if (aop1->type != AOP_REG ||
989 aop2->type != AOP_REG )
993 if (aop1->size != aop2->size )
996 for (i = 0 ; i < aop1->size ; i++ )
997 if (aop1->aopu.aop_reg[i] !=
998 aop2->aopu.aop_reg[i] )
1004 /*-----------------------------------------------------------------*/
1005 /* pic16_aopOp - allocates an asmop for an operand : */
1006 /*-----------------------------------------------------------------*/
1007 void pic16_aopOp (operand *op, iCode *ic, bool result)
1016 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
1018 /* if this a literal */
1019 if (IS_OP_LITERAL(op)) {
1020 op->aop = aop = newAsmop(AOP_LIT);
1021 aop->aopu.aop_lit = op->operand.valOperand;
1022 aop->size = getSize(operandType(op));
1027 sym_link *type = operandType(op);
1029 if(IS_PTR_CONST(type))
1031 if(IS_CODEPTR(type))
1033 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1036 /* if already has a asmop then continue */
1040 /* if the underlying symbol has a aop */
1041 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
1042 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
1043 op->aop = OP_SYMBOL(op)->aop;
1047 /* if this is a true symbol */
1048 if (IS_TRUE_SYMOP(op)) {
1049 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
1050 op->aop = aopForSym(ic, op, result);
1054 /* this is a temporary : this has
1060 e) can be a return use only */
1062 sym = OP_SYMBOL(op);
1064 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
1065 /* if the type is a conditional */
1066 if (sym->regType == REG_CND) {
1067 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
1072 /* if it is spilt then two situations
1074 b) has a spill location */
1075 if (sym->isspilt || sym->nRegs == 0) {
1077 DEBUGpic16_emitcode(";","%d",__LINE__);
1078 /* rematerialize it NOW */
1081 sym->aop = op->aop = aop =
1083 aop->size = getSize(sym->type);
1084 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
1091 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
1092 aop->size = getSize(sym->type);
1093 for ( i = 0 ; i < 1 ; i++ ) {
1094 aop->aopu.aop_str[i] = accUse[i];
1095 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
1097 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
1098 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
1106 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1107 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1108 //pic16_allocDirReg (IC_LEFT(ic));
1109 aop->size = getSize(sym->type);
1114 aop = op->aop = sym->aop = newAsmop(AOP_STR);
1115 aop->size = getSize(sym->type);
1116 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
1117 aop->aopu.aop_str[i] = fReturn[i];
1119 DEBUGpic16_emitcode(";","%d",__LINE__);
1123 /* else spill location */
1124 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
1125 /* force a new aop if sizes differ */
1126 sym->usl.spillLoc->aop = NULL;
1130 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1131 __FUNCTION__,__LINE__,
1132 sym->usl.spillLoc->rname,
1133 sym->rname, sym->usl.spillLoc->offset);
1136 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1137 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1138 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1140 sym->usl.spillLoc->offset, op);
1141 aop->size = getSize(sym->type);
1147 sym_link *type = operandType(op);
1149 if(IS_PTR_CONST(type))
1151 if(IS_CODEPTR(type))
1153 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1156 /* must be in a register */
1157 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1158 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1159 aop->size = sym->nRegs;
1160 for ( i = 0 ; i < sym->nRegs ;i++)
1161 aop->aopu.aop_reg[i] = sym->regs[i];
1164 /*-----------------------------------------------------------------*/
1165 /* pic16_freeAsmop - free up the asmop given to an operand */
1166 /*----------------------------------------------------------------*/
1167 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1184 /* depending on the asmop type only three cases need work AOP_RO
1185 , AOP_R1 && AOP_STK */
1187 switch (aop->type) {
1189 if (_G.fsr0Pushed ) {
1191 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
1192 pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
1193 // pic16_emitcode ("pop","ar0");
1197 bitVectUnSetBit(ic->rUsed,IDX_FSR0);
1201 bitVectUnSetBit(ic->rUsed,IDX_FSR2);
1207 pic16_emitcode ("pop","ar0");
1211 bitVectUnSetBit(ic->rUsed,R0_IDX);
1217 pic16_emitcode ("pop","ar1");
1221 bitVectUnSetBit(ic->rUsed,R1_IDX);
1227 int stk = aop->aopu.aop_stk + aop->size;
1228 bitVectUnSetBit(ic->rUsed,R0_IDX);
1229 bitVectUnSetBit(ic->rUsed,R1_IDX);
1231 getFreePtr(ic,&aop,FALSE);
1233 if (options.stack10bit)
1235 /* I'm not sure what to do here yet... */
1238 "*** Warning: probably generating bad code for "
1239 "10 bit stack mode.\n");
1243 pic16_emitcode ("mov","a,_bp");
1244 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1245 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1247 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1251 pic16_emitcode("pop","acc");
1252 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1254 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1257 pic16_freeAsmop(op,NULL,ic,TRUE);
1259 pic16_emitcode("pop","ar0");
1264 pic16_emitcode("pop","ar1");
1272 /* all other cases just dealloc */
1276 OP_SYMBOL(op)->aop = NULL;
1277 /* if the symbol has a spill */
1279 SPIL_LOC(op)->aop = NULL;
1284 /*-----------------------------------------------------------------*/
1285 /* pic16_aopGet - for fetching value of the aop */
1286 /*-----------------------------------------------------------------*/
1287 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1292 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1294 /* offset is greater than size then zero */
1295 if (offset > (aop->size - 1) &&
1296 aop->type != AOP_LIT)
1299 /* depending on type */
1300 switch (aop->type) {
1304 sprintf(s, "%s", aop->aopu.aop_ptr->name);
1305 rs = Safe_calloc(1, strlen(s)+1);
1310 /* if we need to increment it */
1311 while (offset > aop->coff)
1313 emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
1317 while (offset < aop->coff)
1319 emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
1325 emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
1326 return (dname ? "acc" : "a");
1328 sprintf (s, "@%s", aop->aopu.aop_ptr->name);
1329 rs = Safe_calloc (1, strlen (s) + 1);
1337 sprintf (s,"%s",aop->aopu.aop_immd);
1340 sprintf(s,"(%s >> %d)",
1345 aop->aopu.aop_immd);
1346 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1347 rs = Safe_calloc(1,strlen(s)+1);
1353 sprintf(s,"(%s + %d)",
1356 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1358 sprintf(s,"%s",aop->aopu.aop_dir);
1359 rs = Safe_calloc(1,strlen(s)+1);
1365 // return aop->aopu.aop_reg[offset]->dname;
1367 return aop->aopu.aop_reg[offset]->name;
1370 //pic16_emitcode(";","%d",__LINE__);
1371 return aop->aopu.aop_dir;
1374 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
1375 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1377 // return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1378 rs = Safe_strdup("WREG");
1382 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1383 rs = Safe_calloc(1,strlen(s)+1);
1388 aop->coff = offset ;
1389 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1392 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1394 return aop->aopu.aop_str[offset];
1398 pCodeOp *pcop = aop->aopu.pcop;
1399 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1401 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1402 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1403 sprintf(s,"%s", pcop->name);
1405 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1408 rs = Safe_calloc(1,strlen(s)+1);
1413 // pCodeOp *pcop = aop->aop
1418 fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type));
1419 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1420 "aopget got unsupported aop->type");
1425 /*-----------------------------------------------------------------*/
1426 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1427 /*-----------------------------------------------------------------*/
1428 pCodeOp *pic16_popGetTempReg(void)
1433 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1438 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1439 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1440 PCOR(pcop)->r->wasUsed=1;
1441 PCOR(pcop)->r->isFree=0;
1443 /* push value on stack */
1444 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1452 /*-----------------------------------------------------------------*/
1453 /* pic16_popReleaseTempReg - create a new temporary pCodeOp */
1454 /*-----------------------------------------------------------------*/
1455 void pic16_popReleaseTempReg(pCodeOp *pcop)
1457 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1459 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1460 PCOR(pcop)->r->isFree = 1;
1462 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1465 /*-----------------------------------------------------------------*/
1466 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1467 /*-----------------------------------------------------------------*/
1468 pCodeOp *pic16_popGetLabel(unsigned int key)
1471 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset);
1476 return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset);
1479 /*-----------------------------------------------------------------*/
1480 /* pic16_popCopyReg - copy a pcode operator */
1481 /*-----------------------------------------------------------------*/
1482 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1486 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1487 pcor->pcop.type = pc->pcop.type;
1489 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1490 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1492 pcor->pcop.name = NULL;
1495 pcor->rIdx = pc->rIdx;
1498 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1503 /*-----------------------------------------------------------------*/
1504 /* pic16_popGetLit - asm operator to pcode operator conversion */
1505 /*-----------------------------------------------------------------*/
1506 pCodeOp *pic16_popGetLit(unsigned int lit)
1508 return pic16_newpCodeOpLit(lit);
1511 /*-----------------------------------------------------------------*/
1512 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1513 /*-----------------------------------------------------------------*/
1514 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1516 return pic16_newpCodeOpLit2(lit, arg2);
1520 /*-----------------------------------------------------------------*/
1521 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1522 /*-----------------------------------------------------------------*/
1523 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1525 return pic16_newpCodeOpImmd(name, offset,index, 0);
1529 /*-----------------------------------------------------------------*/
1530 /* pic16_popGet - asm operator to pcode operator conversion */
1531 /*-----------------------------------------------------------------*/
1532 pCodeOp *pic16_popGetWithString(char *str)
1538 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1542 pcop = pic16_newpCodeOp(str,PO_STR);
1547 /*-----------------------------------------------------------------*/
1548 /* pic16_popRegFromString - */
1549 /*-----------------------------------------------------------------*/
1550 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op)
1553 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1554 pcop->type = PO_DIR;
1556 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1557 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1562 pcop->name = Safe_calloc(1,strlen(str)+1);
1563 strcpy(pcop->name,str);
1565 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1567 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1568 if(PCOR(pcop)->r == NULL) {
1569 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1570 // __FUNCTION__, __LINE__, str, size, offset);
1573 // PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
1574 fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
1576 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1578 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1580 PCOR(pcop)->instance = offset;
1585 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1589 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1591 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1592 PCOR(pcop)->rIdx = rIdx;
1593 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1595 PCOR(pcop)->r->isFree = 0;
1596 PCOR(pcop)->r->wasUsed = 1;
1598 pcop->type = PCOR(pcop)->r->pc_type;
1603 /*---------------------------------------------------------------------------------*/
1604 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1606 /*---------------------------------------------------------------------------------*/
1607 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1612 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1614 /* comment the following check, so errors to throw up */
1615 // if(!pcop2)return NULL;
1617 temp = pic16_popGet(aop_dst, offset);
1618 pcop2->pcop2 = temp;
1625 /*--------------------------------------------------------------------------------.-*/
1626 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1627 /* VR 030601 , adapted by Hans Dorn */
1628 /*--------------------------------------------------------------------------------.-*/
1629 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1633 pcop2 = (pCodeOpReg2 *)src;
1641 /*---------------------------------------------------------------------------------*/
1642 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1643 /* movff instruction */
1644 /*---------------------------------------------------------------------------------*/
1645 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1650 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1651 pcop2->pcop2 = pic16_popCopyReg(dst);
1653 /* the pCodeOp may be already allocated */
1654 pcop2 = (pCodeOpReg2 *)(src);
1655 pcop2->pcop2 = (pCodeOp *)(dst);
1662 /*-----------------------------------------------------------------*/
1663 /* pic16_popGet - asm operator to pcode operator conversion */
1664 /*-----------------------------------------------------------------*/
1665 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1667 //char *s = buffer ;
1671 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1672 /* offset is greater than
1675 // if (offset > (aop->size - 1) &&
1676 // aop->type != AOP_LIT)
1677 // return NULL; //zero;
1679 /* depending on type */
1680 switch (aop->type) {
1686 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1687 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1694 pcop = Safe_calloc(1, sizeof(pCodeOpReg));
1695 PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
1696 PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
1697 PCOR(pcop)->r->wasUsed = 1;
1698 PCOR(pcop)->r->isFree = 0;
1700 PCOR(pcop)->instance = offset;
1701 pcop->type = PCOR(pcop)->r->pc_type;
1705 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1706 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1710 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1712 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1714 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1716 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1717 PCOR(pcop)->rIdx = rIdx;
1718 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1719 PCOR(pcop)->r->wasUsed=1;
1720 PCOR(pcop)->r->isFree=0;
1722 PCOR(pcop)->instance = offset;
1723 pcop->type = PCOR(pcop)->r->pc_type;
1724 // rs = aop->aopu.aop_reg[offset]->name;
1725 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1729 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1730 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1736 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1737 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
1741 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1743 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1745 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1746 // pcop->type = PO_GPR_REGISTER;
1747 PCOR(pcop)->rIdx = rIdx;
1748 PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
1749 PCOR(pcop)->r->wasUsed=1;
1750 PCOR(pcop)->r->isFree=0;
1752 PCOR(pcop)->instance = offset;
1753 pcop->type = PCOR(pcop)->r->pc_type;
1754 rs = aop->aopu.aop_reg[offset]->name;
1755 DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs);
1760 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1762 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
1763 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1764 //if(PCOR(pcop)->r == NULL)
1765 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1769 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1770 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1773 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1774 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1777 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1778 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1779 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1780 pcop->type = PCOR(pcop)->r->pc_type;
1781 pcop->name = PCOR(pcop)->r->name;
1787 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1789 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1790 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1792 switch( aop->aopu.pcop->type ) {
1793 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1794 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1796 assert( 0 ); /* should never reach here */;
1799 PCOI(pcop)->offset = offset;
1804 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1805 "pic16_popGet got unsupported aop->type");
1808 /*-----------------------------------------------------------------*/
1809 /* pic16_aopPut - puts a string for a aop */
1810 /*-----------------------------------------------------------------*/
1811 void pic16_aopPut (asmop *aop, char *s, int offset)
1816 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1818 if (aop->size && offset > ( aop->size - 1)) {
1819 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1820 "pic16_aopPut got offset > aop->size");
1824 /* will assign value to value */
1825 /* depending on where it is ofcourse */
1826 switch (aop->type) {
1829 sprintf(d,"(%s + %d)",
1830 aop->aopu.aop_dir,offset);
1831 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1834 sprintf(d,"%s",aop->aopu.aop_dir);
1837 DEBUGpic16_emitcode(";","%d",__LINE__);
1839 pic16_emitcode("movf","%s,w",s);
1840 pic16_emitcode("movwf","%s",d);
1843 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1844 if(offset >= aop->size) {
1845 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1848 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1851 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1858 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1859 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1862 strcmp(s,"r0") == 0 ||
1863 strcmp(s,"r1") == 0 ||
1864 strcmp(s,"r2") == 0 ||
1865 strcmp(s,"r3") == 0 ||
1866 strcmp(s,"r4") == 0 ||
1867 strcmp(s,"r5") == 0 ||
1868 strcmp(s,"r6") == 0 ||
1869 strcmp(s,"r7") == 0 )
1870 pic16_emitcode("mov","%s,%s ; %d",
1871 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1875 if(strcmp(s,"W")==0 )
1876 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1878 pic16_emitcode("movwf","%s",
1879 aop->aopu.aop_reg[offset]->name);
1881 if(strcmp(s,zero)==0) {
1882 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1884 } else if(strcmp(s,"W")==0) {
1885 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1886 pcop->type = PO_GPR_REGISTER;
1888 PCOR(pcop)->rIdx = -1;
1889 PCOR(pcop)->r = NULL;
1891 DEBUGpic16_emitcode(";","%d",__LINE__);
1892 pcop->name = Safe_strdup(s);
1893 pic16_emitpcode(POC_MOVFW,pcop);
1894 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1895 } else if(strcmp(s,one)==0) {
1896 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1897 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1899 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1907 if (aop->type == AOP_DPTR2)
1913 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1914 "pic16_aopPut writting to code space");
1918 while (offset > aop->coff) {
1920 pic16_emitcode ("inc","dptr");
1923 while (offset < aop->coff) {
1925 pic16_emitcode("lcall","__decdptr");
1930 /* if not in accumulater */
1933 pic16_emitcode ("movx","@dptr,a");
1935 if (aop->type == AOP_DPTR2)
1943 while (offset > aop->coff) {
1945 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1947 while (offset < aop->coff) {
1949 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1955 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1960 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1962 if (strcmp(s,"r0") == 0 ||
1963 strcmp(s,"r1") == 0 ||
1964 strcmp(s,"r2") == 0 ||
1965 strcmp(s,"r3") == 0 ||
1966 strcmp(s,"r4") == 0 ||
1967 strcmp(s,"r5") == 0 ||
1968 strcmp(s,"r6") == 0 ||
1969 strcmp(s,"r7") == 0 ) {
1971 sprintf(buffer,"a%s",s);
1972 pic16_emitcode("mov","@%s,%s",
1973 aop->aopu.aop_ptr->name,buffer);
1975 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1980 if (strcmp(s,"a") == 0)
1981 pic16_emitcode("push","acc");
1983 pic16_emitcode("push","%s",s);
1988 /* if bit variable */
1989 if (!aop->aopu.aop_dir) {
1990 pic16_emitcode("clr","a");
1991 pic16_emitcode("rlc","a");
1994 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1997 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
2000 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2002 lbl = newiTempLabel(NULL);
2004 if (strcmp(s,"a")) {
2007 pic16_emitcode("clr","c");
2008 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
2009 pic16_emitcode("cpl","c");
2010 pic16_emitcode("","%05d_DS_:",lbl->key+100);
2011 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
2018 if (strcmp(aop->aopu.aop_str[offset],s))
2019 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
2024 if (!offset && (strcmp(s,"acc") == 0))
2027 if (strcmp(aop->aopu.aop_str[offset],s))
2028 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
2032 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
2033 "pic16_aopPut got unsupported aop->type");
2039 /*-----------------------------------------------------------------*/
2040 /* mov2w - generate either a MOVLW or MOVFW based operand type */
2041 /*-----------------------------------------------------------------*/
2042 static void mov2w (asmop *aop, int offset)
2048 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
2051 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
2053 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
2057 static void mov2f(asmop *dst, asmop *src, int offset)
2059 if(is_LitAOp(src)) {
2060 pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset));
2061 pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset));
2063 pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset),
2064 pic16_popGet(dst, offset)));
2069 /* push pcop into stack */
2070 void pic16_pushpCodeOp(pCodeOp *pcop)
2072 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2073 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
2076 /* pop pcop from stack */
2077 void pic16_poppCodeOp(pCodeOp *pcop)
2079 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
2083 /*-----------------------------------------------------------------*/
2084 /* pushw - pushes wreg to stack */
2085 /*-----------------------------------------------------------------*/
2088 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2089 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
2093 /*-----------------------------------------------------------------*/
2094 /* pushaop - pushes aop to stack */
2095 /*-----------------------------------------------------------------*/
2096 void pushaop(asmop *aop, int offset)
2098 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2099 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
2102 /*-----------------------------------------------------------------*/
2103 /* popaop - pops aop from stack */
2104 /*-----------------------------------------------------------------*/
2105 void popaop(asmop *aop, int offset)
2107 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
2108 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
2111 void popaopidx(asmop *aop, int offset, int index)
2115 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2117 if(STACK_MODEL_LARGE)ofs++;
2119 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
2120 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
2123 /*-----------------------------------------------------------------*/
2124 /* reAdjustPreg - points a register back to where it should */
2125 /*-----------------------------------------------------------------*/
2126 static void reAdjustPreg (asmop *aop)
2130 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2132 if ((size = aop->size) <= 1)
2135 switch (aop->type) {
2139 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
2143 if (aop->type == AOP_DPTR2)
2149 pic16_emitcode("lcall","__decdptr");
2152 if (aop->type == AOP_DPTR2)
2164 /*-----------------------------------------------------------------*/
2165 /* opIsGptr: returns non-zero if the passed operand is */
2166 /* a generic pointer type. */
2167 /*-----------------------------------------------------------------*/
2168 static int opIsGptr(operand *op)
2170 sym_link *type = operandType(op);
2172 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2173 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2181 /*-----------------------------------------------------------------*/
2182 /* pic16_getDataSize - get the operand data size */
2183 /*-----------------------------------------------------------------*/
2184 int pic16_getDataSize(operand *op)
2186 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2189 return AOP_SIZE(op);
2191 // tsd- in the pic port, the genptr size is 1, so this code here
2192 // fails. ( in the 8051 port, the size was 4).
2195 size = AOP_SIZE(op);
2196 if (size == GPTRSIZE)
2198 sym_link *type = operandType(op);
2199 if (IS_GENPTR(type))
2201 /* generic pointer; arithmetic operations
2202 * should ignore the high byte (pointer type).
2205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2212 /*-----------------------------------------------------------------*/
2213 /* pic16_outAcc - output Acc */
2214 /*-----------------------------------------------------------------*/
2215 void pic16_outAcc(operand *result)
2218 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2219 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2222 size = pic16_getDataSize(result);
2224 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2227 /* unsigned or positive */
2229 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2234 /*-----------------------------------------------------------------*/
2235 /* pic16_outBitC - output a bit C */
2236 /* Move to result the value of Carry flag -- VR */
2237 /*-----------------------------------------------------------------*/
2238 void pic16_outBitC(operand *result)
2242 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2243 /* if the result is bit */
2244 if (AOP_TYPE(result) == AOP_CRY) {
2245 fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
2246 pic16_aopPut(AOP(result),"c",0);
2249 i = AOP_SIZE(result);
2251 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
2253 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
2256 pic16_emitcode("clr","a ; %d", __LINE__);
2257 pic16_emitcode("rlc","a");
2258 pic16_outAcc(result);
2263 /*-----------------------------------------------------------------*/
2264 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2265 /*-----------------------------------------------------------------*/
2266 void pic16_toBoolean(operand *oper)
2268 int size = AOP_SIZE(oper) - 1;
2271 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2273 if ( AOP_TYPE(oper) != AOP_ACC) {
2274 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2277 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2282 #if !defined(GEN_Not)
2283 /*-----------------------------------------------------------------*/
2284 /* genNot - generate code for ! operation */
2285 /*-----------------------------------------------------------------*/
2286 static void pic16_genNot (iCode *ic)
2291 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2292 /* assign asmOps to operand & result */
2293 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2294 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2296 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2297 /* if in bit space then a special case */
2298 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2299 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2300 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2301 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2303 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2304 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2305 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2310 size = AOP_SIZE(IC_LEFT(ic));
2312 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2313 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2314 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2317 pic16_toBoolean(IC_LEFT(ic));
2319 tlbl = newiTempLabel(NULL);
2320 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2321 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2322 pic16_outBitC(IC_RESULT(ic));
2325 /* release the aops */
2326 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2327 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2332 #if !defined(GEN_Cpl)
2333 /*-----------------------------------------------------------------*/
2334 /* genCpl - generate code for complement */
2335 /*-----------------------------------------------------------------*/
2336 static void pic16_genCpl (iCode *ic)
2342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2343 /* assign asmOps to operand & result */
2344 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2345 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2347 /* if both are in bit space then
2349 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2350 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2352 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2353 pic16_emitcode("cpl","c");
2354 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2358 size = AOP_SIZE(IC_RESULT(ic));
2361 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2363 pic16_emitcode("cpl","a");
2364 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2366 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2367 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2369 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2370 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2378 /* release the aops */
2379 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2380 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2384 /*-----------------------------------------------------------------*/
2385 /* genUminusFloat - unary minus for floating points */
2386 /*-----------------------------------------------------------------*/
2387 static void genUminusFloat(operand *op,operand *result)
2389 int size ,offset =0 ;
2392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2393 /* for this we just need to flip the
2394 first it then copy the rest in place */
2395 size = AOP_SIZE(op) - 1;
2396 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2400 pic16_emitcode("cpl","acc.7");
2401 pic16_aopPut(AOP(result),"a",3);
2404 pic16_aopPut(AOP(result),
2405 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2411 /*-----------------------------------------------------------------*/
2412 /* genUminus - unary minus code generation */
2413 /*-----------------------------------------------------------------*/
2414 static void genUminus (iCode *ic)
2417 sym_link *optype, *rtype;
2419 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2422 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2423 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2425 /* if both in bit space then special case */
2426 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
2427 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2429 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2430 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2431 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2436 optype = operandType(IC_LEFT(ic));
2437 rtype = operandType(IC_RESULT(ic));
2439 /* if float then do float stuff */
2440 if (IS_FLOAT(optype)) {
2441 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2445 /* otherwise subtract from zero by taking the 2's complement */
2446 size = AOP_SIZE(IC_LEFT(ic));
2448 for(i=0; i<size; i++) {
2449 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2450 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2452 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2453 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2457 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2458 for(i=1; i<size; i++) {
2460 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2464 /* release the aops */
2465 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2466 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2469 /*-----------------------------------------------------------------*/
2470 /* saveRegisters - will look for a call and save the registers */
2471 /*-----------------------------------------------------------------*/
2472 static void saveRegisters(iCode *lic)
2479 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2481 for (ic = lic ; ic ; ic = ic->next)
2482 if (ic->op == CALL || ic->op == PCALL)
2486 fprintf(stderr,"found parameter push with no function call\n");
2490 /* if the registers have been saved already then
2492 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2495 /* find the registers in use at this time
2496 and push them away to safety */
2497 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2501 if (options.useXstack) {
2502 if (bitVectBitValue(rsave,R0_IDX))
2503 pic16_emitcode("mov","b,r0");
2504 pic16_emitcode("mov","r0,%s",spname);
2505 for (i = 0 ; i < pic16_nRegs ; i++) {
2506 if (bitVectBitValue(rsave,i)) {
2508 pic16_emitcode("mov","a,b");
2510 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2511 pic16_emitcode("movx","@r0,a");
2512 pic16_emitcode("inc","r0");
2515 pic16_emitcode("mov","%s,r0",spname);
2516 if (bitVectBitValue(rsave,R0_IDX))
2517 pic16_emitcode("mov","r0,b");
2519 //for (i = 0 ; i < pic16_nRegs ; i++) {
2520 // if (bitVectBitValue(rsave,i))
2521 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2524 dtype = operandType(IC_LEFT(ic));
2525 if (currFunc && dtype &&
2526 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2527 IFFUNC_ISISR(currFunc->type) &&
2530 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533 /*-----------------------------------------------------------------*/
2534 /* unsaveRegisters - pop the pushed registers */
2535 /*-----------------------------------------------------------------*/
2536 static void unsaveRegisters (iCode *ic)
2541 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2542 /* find the registers in use at this time
2543 and push them away to safety */
2544 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2547 if (options.useXstack) {
2548 pic16_emitcode("mov","r0,%s",spname);
2549 for (i = pic16_nRegs ; i >= 0 ; i--) {
2550 if (bitVectBitValue(rsave,i)) {
2551 pic16_emitcode("dec","r0");
2552 pic16_emitcode("movx","a,@r0");
2554 pic16_emitcode("mov","b,a");
2556 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2560 pic16_emitcode("mov","%s,r0",spname);
2561 if (bitVectBitValue(rsave,R0_IDX))
2562 pic16_emitcode("mov","r0,b");
2564 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2565 // if (bitVectBitValue(rsave,i))
2566 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2572 /*-----------------------------------------------------------------*/
2574 /*-----------------------------------------------------------------*/
2575 static void pushSide(operand * oper, int size)
2578 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2580 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2581 if (AOP_TYPE(oper) != AOP_REG &&
2582 AOP_TYPE(oper) != AOP_DIR &&
2584 pic16_emitcode("mov","a,%s",l);
2585 pic16_emitcode("push","acc");
2587 pic16_emitcode("push","%s",l);
2592 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2594 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2596 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2597 pic16_emitpcode(POC_MOVFW, src);
2598 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2600 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2601 src, pic16_popGet(AOP(op), offset)));
2606 /*-----------------------------------------------------------------*/
2607 /* assignResultValue - assign results to oper, rescall==1 is */
2608 /* called from genCall() or genPCall() */
2609 /*-----------------------------------------------------------------*/
2610 static void assignResultValue(operand * oper, int rescall)
2612 int size = AOP_SIZE(oper);
2614 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2615 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2618 /* assign result from a call/pcall function() */
2620 /* function results are stored in a special order,
2621 * see top of file with Function return policy, or manual */
2624 /* 8-bits, result in WREG */
2625 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2628 /* 16-bits, result in PRODL:WREG */
2629 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2633 /* 24-bits, result in PRODH:PRODL:WREG */
2634 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2638 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2639 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2642 /* >32-bits, result on stack, and FSR0 points to beginning.
2643 * Fix stack when done */
2646 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2647 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2649 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2654 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2655 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2656 if(STACK_MODEL_LARGE) {
2658 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2662 if(!GpsuedoStkPtr) {
2663 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2664 /* The last byte in the assignment is in W */
2666 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2671 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2672 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2674 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2680 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2682 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2692 /*-----------------------------------------------------------------*/
2693 /* genIpush - genrate code for pushing this gets a little complex */
2694 /*-----------------------------------------------------------------*/
2695 static void genIpush (iCode *ic)
2699 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2702 pic16_aopOp(IC_LEFT(ic), ic, FALSE);
2705 size = AOP_SIZE( IC_LEFT(ic) );
2708 mov2w( AOP(IC_LEFT(ic)), offset );
2714 int size, offset = 0 ;
2718 /* if this is not a parm push : ie. it is spill push
2719 and spill push is always done on the local stack */
2720 if (!ic->parmPush) {
2722 /* and the item is spilt then do nothing */
2723 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2726 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2727 size = AOP_SIZE(IC_LEFT(ic));
2728 /* push it on the stack */
2730 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2735 pic16_emitcode("push","%s",l);
2740 /* this is a paramter push: in this case we call
2741 the routine to find the call and save those
2742 registers that need to be saved */
2745 /* then do the push */
2746 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2749 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2750 size = AOP_SIZE(IC_LEFT(ic));
2753 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2754 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2755 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2757 pic16_emitcode("mov","a,%s",l);
2758 pic16_emitcode("push","acc");
2760 pic16_emitcode("push","%s",l);
2763 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2767 /*-----------------------------------------------------------------*/
2768 /* genIpop - recover the registers: can happen only for spilling */
2769 /*-----------------------------------------------------------------*/
2770 static void genIpop (iCode *ic)
2772 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2777 /* if the temp was not pushed then */
2778 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2781 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2782 size = AOP_SIZE(IC_LEFT(ic));
2785 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2788 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2792 /*-----------------------------------------------------------------*/
2793 /* unsaverbank - restores the resgister bank from stack */
2794 /*-----------------------------------------------------------------*/
2795 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2797 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2803 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2805 if (options.useXstack) {
2807 r = getFreePtr(ic,&aop,FALSE);
2810 pic16_emitcode("mov","%s,_spx",r->name);
2811 pic16_emitcode("movx","a,@%s",r->name);
2812 pic16_emitcode("mov","psw,a");
2813 pic16_emitcode("dec","%s",r->name);
2816 pic16_emitcode ("pop","psw");
2819 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2820 if (options.useXstack) {
2821 pic16_emitcode("movx","a,@%s",r->name);
2822 //pic16_emitcode("mov","(%s+%d),a",
2823 // regspic16[i].base,8*bank+regspic16[i].offset);
2824 pic16_emitcode("dec","%s",r->name);
2827 pic16_emitcode("pop",""); //"(%s+%d)",
2828 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2831 if (options.useXstack) {
2833 pic16_emitcode("mov","_spx,%s",r->name);
2834 pic16_freeAsmop(NULL,aop,ic,TRUE);
2840 /*-----------------------------------------------------------------*/
2841 /* saverbank - saves an entire register bank on the stack */
2842 /*-----------------------------------------------------------------*/
2843 static void saverbank (int bank, iCode *ic, bool pushPsw)
2845 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2851 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2852 if (options.useXstack) {
2855 r = getFreePtr(ic,&aop,FALSE);
2856 pic16_emitcode("mov","%s,_spx",r->name);
2860 for (i = 0 ; i < pic16_nRegs ;i++) {
2861 if (options.useXstack) {
2862 pic16_emitcode("inc","%s",r->name);
2863 //pic16_emitcode("mov","a,(%s+%d)",
2864 // regspic16[i].base,8*bank+regspic16[i].offset);
2865 pic16_emitcode("movx","@%s,a",r->name);
2867 pic16_emitcode("push","");// "(%s+%d)",
2868 //regspic16[i].base,8*bank+regspic16[i].offset);
2872 if (options.useXstack) {
2873 pic16_emitcode("mov","a,psw");
2874 pic16_emitcode("movx","@%s,a",r->name);
2875 pic16_emitcode("inc","%s",r->name);
2876 pic16_emitcode("mov","_spx,%s",r->name);
2877 pic16_freeAsmop (NULL,aop,ic,TRUE);
2880 pic16_emitcode("push","psw");
2882 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2890 /*-----------------------------------------------------------------*/
2891 /* genCall - generates a call statement */
2892 /*-----------------------------------------------------------------*/
2893 static void genCall (iCode *ic)
2898 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2900 /* if caller saves & we have not saved then */
2904 /* if we are calling a function that is not using
2905 * the same register bank then we need to save the
2906 * destination registers on the stack */
2907 dtype = operandType(IC_LEFT(ic));
2908 if (currFunc && dtype &&
2909 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2910 IFFUNC_ISISR(currFunc->type) &&
2913 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2916 /* initialise stackParms for IPUSH pushes */
2917 // stackParms = psuedoStkPtr;
2918 // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
2920 /* if send set is not empty the assign */
2924 /* For the Pic port, there is no data stack.
2925 * So parameters passed to functions are stored
2926 * in registers. (The pCode optimizer will get
2927 * rid of most of these :). */
2929 int psuedoStkPtr=-1;
2930 int firstTimeThruLoop = 1;
2932 _G.sendSet = reverseSet(_G.sendSet);
2934 /* First figure how many parameters are getting passed */
2935 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2936 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2937 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2938 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2941 stackParms = psuedoStkPtr;
2943 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2944 int size, offset = 0;
2946 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2947 size = AOP_SIZE(IC_LEFT(sic));
2950 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2951 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2952 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2954 if(!firstTimeThruLoop) {
2955 /* If this is not the first time we've been through the loop
2956 * then we need to save the parameter in a temporary
2957 * register. The last byte of the last parameter is
2961 --psuedoStkPtr; // sanity check
2964 firstTimeThruLoop=0;
2966 mov2w (AOP(IC_LEFT(sic)), offset);
2969 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2975 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2976 OP_SYMBOL(IC_LEFT(ic))->rname :
2977 OP_SYMBOL(IC_LEFT(ic))->name));
2980 /* if we need assign a result value */
2981 if ((IS_ITEMP(IC_RESULT(ic)) &&
2982 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2983 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2984 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2987 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2990 assignResultValue(IC_RESULT(ic), 1);
2992 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2993 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2995 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2998 if(!stackParms && ic->parmBytes) {
2999 stackParms = ic->parmBytes;
3003 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3004 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3005 if(STACK_MODEL_LARGE) {
3007 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3011 /* adjust the stack for parameters if required */
3012 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3014 if (ic->parmBytes) {
3017 if (ic->parmBytes > 3) {
3018 pic16_emitcode("mov","a,%s",spname);
3019 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3020 pic16_emitcode("mov","%s,a",spname);
3022 for ( i = 0 ; i < ic->parmBytes ;i++)
3023 pic16_emitcode("dec","%s",spname);
3028 /* if register bank was saved then pop them */
3030 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3032 /* if we hade saved some registers then unsave them */
3033 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3034 unsaveRegisters (ic);
3040 /*-----------------------------------------------------------------*/ // patch 14
3041 /* genPcall - generates a call by pointer statement */
3042 /*-----------------------------------------------------------------*/
3044 // new version, created from genCall
3046 static void genPcall (iCode *ic)
3050 symbol *retlbl = newiTempLabel(NULL);
3051 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
3053 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3055 /* if caller saves & we have not saved then */
3059 /* if we are calling a function that is not using
3060 * the same register bank then we need to save the
3061 * destination registers on the stack */
3062 dtype = operandType(IC_LEFT(ic));
3063 if (currFunc && dtype &&
3064 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
3065 IFFUNC_ISISR(currFunc->type) &&
3068 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3070 /* if send set is not empty the assign */
3074 /* For the Pic port, there is no data stack.
3075 * So parameters passed to functions are stored
3076 * in registers. (The pCode optimizer will get
3077 * rid of most of these :). */
3079 int psuedoStkPtr=-1;
3080 int firstTimeThruLoop = 1;
3082 _G.sendSet = reverseSet(_G.sendSet);
3084 /* First figure how many parameters are getting passed */
3085 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3086 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3087 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
3088 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
3091 stackParms = psuedoStkPtr;
3093 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
3094 int size, offset = 0;
3096 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3097 size = AOP_SIZE(IC_LEFT(sic));
3100 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3101 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
3102 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
3104 if(!firstTimeThruLoop) {
3105 /* If this is not the first time we've been through the loop
3106 * then we need to save the parameter in a temporary
3107 * register. The last byte of the last parameter is
3111 --psuedoStkPtr; // sanity check
3114 firstTimeThruLoop=0;
3116 mov2w (AOP(IC_LEFT(sic)), offset);
3119 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3124 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3126 // push return address
3127 // push $ on return stack, then replace with retlbl
3129 pic16_emitpcodeNULLop(POC_PUSH);
3131 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
3132 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
3133 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
3134 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
3135 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
3136 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
3138 /* make the call by writing the pointer into pc */
3139 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
3140 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
3142 // note: MOVFF to PCL not allowed
3143 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
3144 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
3147 // pic16_emitpcode(POC_GOTO, pic16_popGetLabel(retlbl->key));
3148 // pic16_emitpcodeNULLop(POC_NOP);
3149 // pic16_emitpcodeNULLop(POC_NOP);
3151 /* return address is here: (X) */
3152 pic16_emitpLabelFORCE(retlbl->key);
3154 // pic16_emitpcodeNULLop(POC_NOP);
3156 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3159 /* if we need assign a result value */
3160 if ((IS_ITEMP(IC_RESULT(ic)) &&
3161 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3162 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
3163 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3166 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3169 assignResultValue(IC_RESULT(ic), 1);
3171 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
3172 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
3174 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
3178 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
3179 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
3180 if(STACK_MODEL_LARGE) {
3182 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3186 /* adjust the stack for parameters if required */
3187 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3189 if (ic->parmBytes) {
3192 if (ic->parmBytes > 3) {
3193 pic16_emitcode("mov","a,%s",spname);
3194 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3195 pic16_emitcode("mov","%s,a",spname);
3197 for ( i = 0 ; i < ic->parmBytes ;i++)
3198 pic16_emitcode("dec","%s",spname);
3201 /* if register bank was saved then pop them */
3203 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3205 /* if we hade saved some registers then unsave them */
3206 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3207 unsaveRegisters (ic);
3212 // old version, kept for reference
3214 /*-----------------------------------------------------------------*/
3215 /* genPcall - generates a call by pointer statement */
3216 /*-----------------------------------------------------------------*/
3217 static void genPcall (iCode *ic)
3220 symbol *rlbl = newiTempLabel(NULL);
3223 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3224 /* if caller saves & we have not saved then */
3228 /* if we are calling a function that is not using
3229 the same register bank then we need to save the
3230 destination registers on the stack */
3231 dtype = operandType(IC_LEFT(ic));
3232 if (currFunc && dtype &&
3233 IFFUNC_ISISR(currFunc->type) &&
3234 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3235 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3238 /* push the return address on to the stack */
3239 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
3240 pic16_emitcode("push","acc");
3241 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
3242 pic16_emitcode("push","acc");
3244 if (options.model == MODEL_FLAT24)
3246 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
3247 pic16_emitcode("push","acc");
3250 /* now push the calling address */
3251 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3253 pushSide(IC_LEFT(ic), FPTRSIZE);
3255 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3257 /* if send set is not empty the assign */
3261 for (sic = setFirstItem(_G.sendSet) ; sic ;
3262 sic = setNextItem(_G.sendSet)) {
3263 int size, offset = 0;
3264 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3265 size = AOP_SIZE(IC_LEFT(sic));
3267 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
3269 if (strcmp(l,fReturn[offset]))
3270 pic16_emitcode("mov","%s,%s",
3275 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3280 pic16_emitcode("ret","");
3281 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
3284 /* if we need assign a result value */
3285 if ((IS_ITEMP(IC_RESULT(ic)) &&
3286 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3287 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
3288 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3291 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3294 assignResultValue(IC_RESULT(ic), 1);
3296 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3299 /* adjust the stack for parameters if
3301 if (ic->parmBytes) {
3303 if (ic->parmBytes > 3) {
3304 pic16_emitcode("mov","a,%s",spname);
3305 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3306 pic16_emitcode("mov","%s,a",spname);
3308 for ( i = 0 ; i < ic->parmBytes ;i++)
3309 pic16_emitcode("dec","%s",spname);
3313 /* if register bank was saved then unsave them */
3314 if (currFunc && dtype &&
3315 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3316 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3318 /* if we hade saved some registers then
3321 unsaveRegisters (ic);
3327 /*-----------------------------------------------------------------*/
3328 /* resultRemat - result is rematerializable */
3329 /*-----------------------------------------------------------------*/
3330 static int resultRemat (iCode *ic)
3332 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3333 if (SKIP_IC(ic) || ic->op == IFX)
3336 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3337 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3338 if (sym->remat && !POINTER_SET(ic))
3345 #if defined(__BORLANDC__) || defined(_MSC_VER)
3346 #define STRCASECMP stricmp
3348 #define STRCASECMP strcasecmp
3352 /*-----------------------------------------------------------------*/
3353 /* inExcludeList - return 1 if the string is in exclude Reg list */
3354 /*-----------------------------------------------------------------*/
3355 static bool inExcludeList(char *s)
3357 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3361 if (options.excludeRegs[i] &&
3362 STRCASECMP(options.excludeRegs[i],"none") == 0)
3365 for ( i = 0 ; options.excludeRegs[i]; i++) {
3366 if (options.excludeRegs[i] &&
3367 STRCASECMP(s,options.excludeRegs[i]) == 0)
3374 /*-----------------------------------------------------------------*/
3375 /* genFunction - generated code for function entry */
3376 /*-----------------------------------------------------------------*/
3377 static void genFunction (iCode *ic)
3382 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
3384 pic16_labelOffset += (max_key+4);
3389 ftype = operandType(IC_LEFT(ic));
3390 sym = OP_SYMBOL(IC_LEFT(ic));
3392 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3393 /* create an absolute section at the interrupt vector:
3394 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3402 sym = OP_SYMBOL( IC_LEFT(ic));
3404 if(interrupts[i]->name
3405 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3412 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3413 __FILE__, __LINE__, sym->name);
3416 _G.interruptvector = found;
3419 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3420 asym = newSymbol(asymname, 0);
3422 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3423 pic16_addpBlock( apb );
3425 pic16_addpCode2pBlock(apb,
3426 pic16_newpCodeCharP(";-----------------------------------------"));
3429 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3431 pic16_addpCode2pBlock(apb,
3432 pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3434 /* mark the end of this tiny function */
3435 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3440 abSym = Safe_calloc(1, sizeof(absSym));
3441 abSym->name = Safe_strdup( asymname );
3443 switch( _G.interruptvector ) {
3444 case 0: abSym->address = 0x000000; break;
3445 case 1: abSym->address = 0x000008; break;
3446 case 2: abSym->address = 0x000018; break;
3449 /* relocate interrupt vectors if needed */
3450 abSym->address += pic16_options.ivt_loc;
3452 addSet(&absSymSet, abSym);
3457 /* create the function header */
3458 pic16_emitcode(";","-----------------------------------------");
3459 pic16_emitcode(";"," function %s",sym->name);
3460 pic16_emitcode(";","-----------------------------------------");
3462 pic16_emitcode("","%s:",sym->rname);
3463 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3469 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3470 if(!strcmp(ab->name, sym->name)) {
3471 pic16_pBlockConvert2Absolute(pb);
3478 if(IFFUNC_ISNAKED(ftype)) {
3479 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3483 /* if critical function then turn interrupts off */
3484 if (IFFUNC_ISCRITICAL(ftype))
3485 pic16_emitcode("clr","ea");
3487 /* if this is an interrupt service routine then
3488 * save acc, b, dpl, dph */
3489 if (IFFUNC_ISISR(sym->type)) {
3492 _G.usefastretfie = 1; /* use shadow registers by default */
3493 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3494 if(!(_G.interruptvector == 1)) {
3496 /* do not save WREG,STATUS,BSR for high priority interrupts
3497 * because they are stored in the hardware shadow registers already */
3498 _G.usefastretfie = 0;
3499 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3500 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3501 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3505 /* these should really be optimized somehow, because not all
3506 * interrupt handlers modify them */
3507 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3508 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3509 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3510 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3512 // pic16_pBlockConvert2ISR(pb);
3514 /* if any registers used */
3515 if (sym->regsUsed) {
3516 /* save the registers used */
3517 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3518 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3519 if (bitVectBitValue(sym->regsUsed,i)) {
3521 fprintf(stderr, "%s:%d function %s uses register %s\n",
3522 __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3523 pic16_regWithIdx(i)->name);
3526 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3529 if(!pic16_regWithIdx(i)->wasUsed) {
3530 fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
3531 __FILE__, __LINE__, pic16_regWithIdx(i)->name);
3533 pic16_regWithIdx(i)->wasUsed = 1;
3539 /* emit code to setup stack frame if user enabled,
3540 * and function is not main() */
3542 // fprintf(stderr, "function name: %s\n", sym->name);
3543 if(strcmp(sym->name, "main")) {
3544 if(/*!options.ommitFramePtr || */sym->regsUsed) {
3545 /* setup the stack frame */
3546 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3547 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3548 if(STACK_MODEL_LARGE)
3549 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3553 /* if callee-save to be used for this function
3554 * then save the registers being used in this function */
3555 // if (IFFUNC_CALLEESAVES(sym->type))
3559 // fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
3561 // pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3563 /* if any registers used */
3564 if (sym->regsUsed) {
3565 /* save the registers used */
3566 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3567 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3568 if (bitVectBitValue(sym->regsUsed,i)) {
3571 fprintf(stderr, "%s:%d function %s uses register %s (wasUsed: %d, %p)\n",
3572 __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3573 pic16_regWithIdx(i)->name,
3574 pic16_regWithIdx(i)->wasUsed,
3575 pic16_regWithIdx(i));
3578 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3580 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3581 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3582 // &pic16_pc_postdec1, 0));
3586 if(!pic16_regWithIdx(i)->wasUsed) {
3587 fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
3588 __FILE__, __LINE__, pic16_regWithIdx(i)->name);
3590 pic16_regWithIdx(i)->wasUsed = 1;
3602 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3604 if (options.useXstack) {
3605 pic16_emitcode("mov","r0,%s",spname);
3606 pic16_emitcode("mov","a,_bp");
3607 pic16_emitcode("movx","@r0,a");
3608 pic16_emitcode("inc","%s",spname);
3610 /* set up the stack */
3611 pic16_emitcode ("push","_bp"); /* save the callers stack */
3613 pic16_emitcode ("mov","_bp,%s",spname);
3616 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3618 /* adjust the stack for the function */
3623 werror(W_STACK_OVERFLOW,sym->name);
3625 if (i > 3 && sym->recvSize < 4) {
3626 pic16_emitcode ("mov","a,sp");
3627 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3628 pic16_emitcode ("mov","sp,a");
3631 pic16_emitcode("inc","sp");
3635 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3637 pic16_emitcode ("mov","a,_spx");
3638 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3639 pic16_emitcode ("mov","_spx,a");
3644 /*-----------------------------------------------------------------*/
3645 /* genEndFunction - generates epilogue for functions */
3646 /*-----------------------------------------------------------------*/
3647 static void genEndFunction (iCode *ic)
3649 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3651 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3653 if(IFFUNC_ISNAKED(sym->type)) {
3654 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3658 /* add code for ISCRITICAL */
3661 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3663 pic16_emitcode ("mov","%s,_bp",spname);
3667 /* if use external stack but some variables were
3668 added to the local stack then decrement the
3670 if (options.useXstack && sym->stack) {
3671 pic16_emitcode("mov","a,sp");
3672 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3673 pic16_emitcode("mov","sp,a");
3678 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3679 if (options.useXstack) {
3680 pic16_emitcode("mov","r0,%s",spname);
3681 pic16_emitcode("movx","a,@r0");
3682 pic16_emitcode("mov","_bp,a");
3683 pic16_emitcode("dec","%s",spname);
3687 pic16_emitcode ("pop","_bp");
3692 if (IFFUNC_ISISR(sym->type)) {
3693 /* now we need to restore the registers */
3694 /* if any registers used */
3695 if (sym->regsUsed) {
3698 /* restore registers used */
3699 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3700 for ( i = sym->regsUsed->size; i >= 0; i--) {
3701 if (bitVectBitValue(sym->regsUsed,i)) {
3703 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3704 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3705 // pic16_regWithIdx(i)->name);
3707 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3709 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3710 // &pic16_pc_preinc1,
3711 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3717 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3718 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3719 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3720 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3722 if(!(_G.interruptvector == 1)) {
3723 /* do not restore interrupt vector for WREG,STATUS,BSR
3724 * for high priority interrupt, see genFunction */
3726 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3727 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3728 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3731 _G.interruptvector = 0; /* sanity check */
3733 // pic16_pBlockConvert2ISR(pb);
3736 /* if debug then send end of function */
3737 /* if (options.debug && currFunc) */
3739 debugFile->writeEndFunction (currFunc, ic, 1);
3742 if(_G.usefastretfie)
3743 pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
3745 pic16_emitpcodeNULLop(POC_RETFIE);
3746 _G.usefastretfie = 0;
3748 if (IFFUNC_ISCRITICAL(sym->type))
3749 pic16_emitcode("setb","ea");
3752 // pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3754 /* if any registers used */
3755 if (sym->regsUsed) {
3757 /* save the registers used */
3758 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3759 for ( i = sym->regsUsed->size; i >= 0; i--) {
3760 if (bitVectBitValue(sym->regsUsed,i)) {
3762 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3763 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3764 // pic16_regWithIdx(i)->name);
3766 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3768 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3769 // &pic16_pc_preinc1,
3770 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3777 // pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
3778 /* if debug then send end of function */
3780 debugFile->writeEndFunction (currFunc, ic, 1);
3783 /* insert code to restore stack frame, if user enabled it
3784 * and function is not main() */
3787 if(strcmp(sym->name, "main")) {
3788 if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
3789 /* restore stack frame */
3790 if(STACK_MODEL_LARGE)
3791 pic16_emitpcode(POC_MOVFF,
3792 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3793 pic16_emitpcode(POC_MOVFF,
3794 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3798 pic16_emitpcodeNULLop(POC_RETURN);
3800 /* Mark the end of a function */
3801 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3807 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3811 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
3813 if(dest->type != PO_WREG)
3814 pic16_emitpcode(POC_MOVWF, dest);
3816 if(dest->type == PO_WREG && (offset == 0)) {
3817 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
3821 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3822 pic16_popGet(AOP(op), offset), dest));
3826 /*-----------------------------------------------------------------*/
3827 /* genRet - generate code for return statement */
3828 /*-----------------------------------------------------------------*/
3829 static void genRet (iCode *ic)
3834 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3835 /* if we have no return value then
3836 * just generate the "ret" */
3841 /* we have something to return then
3842 * move the return value into place */
3843 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3844 size = AOP_SIZE(IC_LEFT(ic));
3848 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3849 // pic16_emitpcode(POC_MOVFF,
3850 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3853 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3854 // pic16_emitpcode(POC_MOVFF,
3855 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3858 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3859 // pic16_emitpcode(POC_MOVFF,
3860 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3863 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3865 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3866 // pic16_emitpcode(POC_MOVFF,
3867 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3870 /* >32-bits, setup stack and FSR0 */
3872 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3873 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3875 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3877 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3882 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3883 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3885 if(STACK_MODEL_LARGE) {
3886 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3887 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3889 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3894 /* old code, left here for reference -- VR */
3898 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3900 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3901 pic16_emitpcomment("push %s",l);
3904 DEBUGpic16_emitcode(";", "%d", __LINE__);
3905 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3906 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3908 if (strcmp(fReturn[offset],l)) {
3909 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3910 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3911 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3913 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3917 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3927 if (strcmp(fReturn[pushed],"a"))
3928 pic16_emitcode("pop",fReturn[pushed]);
3930 pic16_emitcode("pop","acc");
3936 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3939 /* generate a jump to the return label
3940 * if the next is not the return statement */
3941 if (!(ic->next && ic->next->op == LABEL
3942 && IC_LABEL(ic->next) == returnLabel)) {
3944 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3945 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
3949 /*-----------------------------------------------------------------*/
3950 /* genLabel - generates a label */
3951 /*-----------------------------------------------------------------*/
3952 static void genLabel (iCode *ic)
3956 /* special case never generate */
3957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3958 if (IC_LABEL(ic) == entryLabel)
3961 pic16_emitpLabel(IC_LABEL(ic)->key);
3962 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset));
3965 /*-----------------------------------------------------------------*/
3966 /* genGoto - generates a goto */
3967 /*-----------------------------------------------------------------*/
3969 static void genGoto (iCode *ic)
3971 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3972 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset);
3976 /*-----------------------------------------------------------------*/
3977 /* genMultbits :- multiplication of bits */
3978 /*-----------------------------------------------------------------*/
3979 static void genMultbits (operand *left,
3983 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3985 if(!pic16_sameRegs(AOP(result),AOP(right)))
3986 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3988 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3989 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3990 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3995 /*-----------------------------------------------------------------*/
3996 /* genMultOneByte : 8 bit multiplication & division */
3997 /*-----------------------------------------------------------------*/
3998 static void genMultOneByte (operand *left,
4003 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4004 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4005 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4007 /* (if two literals, the value is computed before) */
4008 /* if one literal, literal on the right */
4009 if (AOP_TYPE(left) == AOP_LIT){
4015 /* size is already checked in genMult == 1 */
4016 // size = AOP_SIZE(result);
4018 if (AOP_TYPE(right) == AOP_LIT){
4019 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4020 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4021 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4022 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4024 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4025 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4026 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4027 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4030 pic16_genMult8X8_8 (left, right,result);
4033 /*-----------------------------------------------------------------*/
4034 /* genMultOneWord : 16 bit multiplication */
4035 /*-----------------------------------------------------------------*/
4036 static void genMultOneWord (operand *left,
4041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4042 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4043 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4045 /* (if two literals, the value is computed before)
4046 * if one literal, literal on the right */
4047 if (AOP_TYPE(left) == AOP_LIT){
4053 /* size is checked already == 2 */
4054 // size = AOP_SIZE(result);
4056 if (AOP_TYPE(right) == AOP_LIT) {
4057 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4058 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4059 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4060 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4062 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4063 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4064 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4065 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4068 pic16_genMult16X16_16(left, right,result);
4071 /*-----------------------------------------------------------------*/
4072 /* genMultOneLong : 32 bit multiplication */
4073 /*-----------------------------------------------------------------*/
4074 static void genMultOneLong (operand *left,
4079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4080 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4081 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
4083 /* (if two literals, the value is computed before)
4084 * if one literal, literal on the right */
4085 if (AOP_TYPE(left) == AOP_LIT){
4091 /* size is checked already == 4 */
4092 // size = AOP_SIZE(result);
4094 if (AOP_TYPE(right) == AOP_LIT) {
4095 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
4096 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4097 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4098 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4100 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
4101 pic16_aopGet(AOP(right),0,FALSE,FALSE),
4102 pic16_aopGet(AOP(left),0,FALSE,FALSE),
4103 pic16_aopGet(AOP(result),0,FALSE,FALSE));
4106 pic16_genMult32X32_32(left, right,result);
4111 /*-----------------------------------------------------------------*/
4112 /* genMult - generates code for multiplication */
4113 /*-----------------------------------------------------------------*/
4114 static void genMult (iCode *ic)
4116 operand *left = IC_LEFT(ic);
4117 operand *right = IC_RIGHT(ic);
4118 operand *result= IC_RESULT(ic);
4120 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4121 /* assign the amsops */
4122 pic16_aopOp (left,ic,FALSE);
4123 pic16_aopOp (right,ic,FALSE);
4124 pic16_aopOp (result,ic,TRUE);
4126 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4128 /* special cases first *
4130 if (AOP_TYPE(left) == AOP_CRY
4131 && AOP_TYPE(right)== AOP_CRY) {
4132 genMultbits(left,right,result);
4136 /* if both are of size == 1 */
4137 if(AOP_SIZE(left) == 1
4138 && AOP_SIZE(right) == 1) {
4139 genMultOneByte(left,right,result);
4143 /* if both are of size == 2 */
4144 if(AOP_SIZE(left) == 2
4145 && AOP_SIZE(right) == 2) {
4146 genMultOneWord(left, right, result);
4150 /* if both are of size == 4 */
4151 if(AOP_SIZE(left) == 4
4152 && AOP_SIZE(right) == 4) {
4153 genMultOneLong(left, right, result);
4157 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
4160 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
4161 /* should have been converted to function call */
4165 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4166 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4167 pic16_freeAsmop(result,NULL,ic,TRUE);
4170 /*-----------------------------------------------------------------*/
4171 /* genDivbits :- division of bits */
4172 /*-----------------------------------------------------------------*/
4173 static void genDivbits (operand *left,
4180 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4181 /* the result must be bit */
4182 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4183 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4187 pic16_emitcode("div","ab");
4188 pic16_emitcode("rrc","a");
4189 pic16_aopPut(AOP(result),"c",0);
4192 /*-----------------------------------------------------------------*/
4193 /* genDivOneByte : 8 bit division */
4194 /*-----------------------------------------------------------------*/
4195 static void genDivOneByte (operand *left,
4199 sym_link *opetype = operandType(result);
4204 /* result = divident / divisor
4205 * - divident may be a register or a literal,
4206 * - divisor may be a register or a literal,
4207 * so there are 3 cases (literal / literal is optimized
4208 * by the front-end) to handle.
4209 * In addition we must handle signed and unsigned, which
4210 * result in 6 final different cases -- VR */
4212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4213 size = AOP_SIZE(result) - 1;
4215 /* signed or unsigned */
4216 if (SPEC_USIGN(opetype)) {
4217 pCodeOp *pct1, /* count */
4220 symbol *label1, *label2, *label3;;
4223 /* unsigned is easy */
4225 pct1 = pic16_popGetTempReg();
4226 pct2 = pic16_popGetTempReg();
4227 pct3 = pic16_popGetTempReg();
4229 label1 = newiTempLabel(NULL);
4230 label2 = newiTempLabel(NULL);
4231 label3 = newiTempLabel(NULL);
4233 /* the following algorithm is extracted from divuint.c */
4235 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
4236 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
4238 pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
4240 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
4242 pic16_emitpLabel(label1->key);
4245 pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
4249 pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
4253 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
4255 pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
4256 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
4258 pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
4259 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
4260 pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
4262 pic16_emitpLabel( label3->key );
4263 pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
4264 pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
4268 pic16_emitpLabel(label2->key);
4269 pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
4270 pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
4271 pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
4273 /* result is in wreg */
4274 if(AOP_TYPE(result) != AOP_ACC)
4275 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
4277 pic16_popReleaseTempReg( pct3 );
4278 pic16_popReleaseTempReg( pct2 );
4279 pic16_popReleaseTempReg( pct1 );
4284 /* signed is a little bit more difficult */
4286 /* save the signs of the operands */
4287 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4289 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4290 pic16_emitcode("push","acc"); /* save it on the stack */
4292 /* now sign adjust for both left & right */
4293 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4295 lbl = newiTempLabel(NULL);
4296 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4297 pic16_emitcode("cpl","a");
4298 pic16_emitcode("inc","a");
4299 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4300 pic16_emitcode("mov","b,a");
4302 /* sign adjust left side */
4303 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4306 lbl = newiTempLabel(NULL);
4307 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4308 pic16_emitcode("cpl","a");
4309 pic16_emitcode("inc","a");
4310 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4312 /* now the division */
4313 pic16_emitcode("div","ab");
4314 /* we are interested in the lower order
4316 pic16_emitcode("mov","b,a");
4317 lbl = newiTempLabel(NULL);
4318 pic16_emitcode("pop","acc");
4319 /* if there was an over flow we don't
4320 adjust the sign of the result */
4321 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4322 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4324 pic16_emitcode("clr","a");
4325 pic16_emitcode("subb","a,b");
4326 pic16_emitcode("mov","b,a");
4327 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4329 /* now we are done */
4330 pic16_aopPut(AOP(result),"b",0);
4332 pic16_emitcode("mov","c,b.7");
4333 pic16_emitcode("subb","a,acc");
4336 pic16_aopPut(AOP(result),"a",offset++);
4340 /*-----------------------------------------------------------------*/
4341 /* genDiv - generates code for division */
4342 /*-----------------------------------------------------------------*/
4343 static void genDiv (iCode *ic)
4345 operand *left = IC_LEFT(ic);
4346 operand *right = IC_RIGHT(ic);
4347 operand *result= IC_RESULT(ic);
4350 /* Division is a very lengthy algorithm, so it is better
4351 * to call support routines than inlining algorithm.
4352 * Division functions written here just in case someone
4353 * wants to inline and not use the support libraries -- VR */
4355 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4356 /* assign the amsops */
4357 pic16_aopOp (left,ic,FALSE);
4358 pic16_aopOp (right,ic,FALSE);
4359 pic16_aopOp (result,ic,TRUE);
4361 /* special cases first */
4363 if (AOP_TYPE(left) == AOP_CRY &&
4364 AOP_TYPE(right)== AOP_CRY) {
4365 genDivbits(left,right,result);
4369 /* if both are of size == 1 */
4370 if (AOP_SIZE(left) == 1 &&
4371 AOP_SIZE(right) == 1 ) {
4372 genDivOneByte(left,right,result);
4376 /* should have been converted to function call */
4379 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4380 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4381 pic16_freeAsmop(result,NULL,ic,TRUE);
4384 /*-----------------------------------------------------------------*/
4385 /* genModbits :- modulus of bits */
4386 /*-----------------------------------------------------------------*/
4387 static void genModbits (operand *left,
4394 /* the result must be bit */
4395 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4396 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4400 pic16_emitcode("div","ab");
4401 pic16_emitcode("mov","a,b");
4402 pic16_emitcode("rrc","a");
4403 pic16_aopPut(AOP(result),"c",0);
4406 /*-----------------------------------------------------------------*/
4407 /* genModOneByte : 8 bit modulus */
4408 /*-----------------------------------------------------------------*/
4409 static void genModOneByte (operand *left,
4413 sym_link *opetype = operandType(result);
4417 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4418 /* signed or unsigned */
4419 if (SPEC_USIGN(opetype)) {
4420 /* unsigned is easy */
4421 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4422 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4424 pic16_emitcode("div","ab");
4425 pic16_aopPut(AOP(result),"b",0);
4429 /* signed is a little bit more difficult */
4431 /* save the signs of the operands */
4432 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4435 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4436 pic16_emitcode("push","acc"); /* save it on the stack */
4438 /* now sign adjust for both left & right */
4439 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4442 lbl = newiTempLabel(NULL);
4443 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4444 pic16_emitcode("cpl","a");
4445 pic16_emitcode("inc","a");
4446 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4447 pic16_emitcode("mov","b,a");
4449 /* sign adjust left side */
4450 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4453 lbl = newiTempLabel(NULL);
4454 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4455 pic16_emitcode("cpl","a");
4456 pic16_emitcode("inc","a");
4457 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4459 /* now the multiplication */
4460 pic16_emitcode("div","ab");
4461 /* we are interested in the lower order
4463 lbl = newiTempLabel(NULL);
4464 pic16_emitcode("pop","acc");
4465 /* if there was an over flow we don't
4466 adjust the sign of the result */
4467 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4468 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4470 pic16_emitcode("clr","a");
4471 pic16_emitcode("subb","a,b");
4472 pic16_emitcode("mov","b,a");
4473 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4475 /* now we are done */
4476 pic16_aopPut(AOP(result),"b",0);
4480 /*-----------------------------------------------------------------*/
4481 /* genMod - generates code for division */
4482 /*-----------------------------------------------------------------*/
4483 static void genMod (iCode *ic)
4485 operand *left = IC_LEFT(ic);
4486 operand *right = IC_RIGHT(ic);
4487 operand *result= IC_RESULT(ic);
4489 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4490 /* assign the amsops */
4491 pic16_aopOp (left,ic,FALSE);
4492 pic16_aopOp (right,ic,FALSE);
4493 pic16_aopOp (result,ic,TRUE);
4495 /* special cases first */
4497 if (AOP_TYPE(left) == AOP_CRY &&
4498 AOP_TYPE(right)== AOP_CRY) {
4499 genModbits(left,right,result);
4503 /* if both are of size == 1 */
4504 if (AOP_SIZE(left) == 1 &&
4505 AOP_SIZE(right) == 1 ) {
4506 genModOneByte(left,right,result);
4510 /* should have been converted to function call */
4514 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4515 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4516 pic16_freeAsmop(result,NULL,ic,TRUE);
4519 /*-----------------------------------------------------------------*/
4520 /* genIfxJump :- will create a jump depending on the ifx */
4521 /*-----------------------------------------------------------------*/
4523 note: May need to add parameter to indicate when a variable is in bit space.
4525 static void genIfxJump (iCode *ic, char *jval)
4528 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4529 /* if true label then we jump if condition
4531 if ( IC_TRUE(ic) ) {
4533 if(strcmp(jval,"a") == 0)
4535 else if (strcmp(jval,"c") == 0)
4538 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4539 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4542 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4543 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
4547 /* false label is present */
4548 if(strcmp(jval,"a") == 0)
4550 else if (strcmp(jval,"c") == 0)
4553 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4554 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
4557 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4558 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
4563 /* mark the icode as generated */
4570 /*-----------------------------------------------------------------*/
4572 /*-----------------------------------------------------------------*/
4573 static void genSkip(iCode *ifx,int status_bit)
4575 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4579 if ( IC_TRUE(ifx) ) {
4580 switch(status_bit) {
4595 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4596 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4600 switch(status_bit) {
4614 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4615 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4622 /*-----------------------------------------------------------------*/
4624 /*-----------------------------------------------------------------*/
4625 static void genSkipc(resolvedIfx *rifx)
4627 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4637 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4638 rifx->generated = 1;
4641 /*-----------------------------------------------------------------*/
4643 /*-----------------------------------------------------------------*/
4644 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4646 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4651 if( (rifx->condition ^ invert_condition) & 1)
4656 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4657 rifx->generated = 1;
4661 /*-----------------------------------------------------------------*/
4663 /*-----------------------------------------------------------------*/
4664 static void genSkipz(iCode *ifx, int condition)
4675 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4677 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4680 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
4682 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
4687 /*-----------------------------------------------------------------*/
4689 /*-----------------------------------------------------------------*/
4690 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4696 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4698 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER));
4701 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4702 rifx->generated = 1;
4706 /*-----------------------------------------------------------------*/
4707 /* genChkZeroes :- greater or less than comparison */
4708 /* For each byte in a literal that is zero, inclusive or the */
4709 /* the corresponding byte in the operand with W */
4710 /* returns true if any of the bytes are zero */
4711 /*-----------------------------------------------------------------*/
4712 static int genChkZeroes(operand *op, int lit, int size)
4719 i = (lit >> (size*8)) & 0xff;
4723 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4725 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4734 /*-----------------------------------------------------------------*/
4735 /* genCmp :- greater or less than comparison */
4736 /*-----------------------------------------------------------------*/
4737 static void genCmp (operand *left,operand *right,
4738 operand *result, iCode *ifx, int sign)
4740 int size; //, offset = 0 ;
4741 unsigned long lit = 0L,i = 0;
4742 resolvedIfx rFalseIfx;
4743 // resolvedIfx rTrueIfx;
4745 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4748 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4749 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4753 resolveIfx(&rFalseIfx,ifx);
4754 truelbl = newiTempLabel(NULL);
4755 size = max(AOP_SIZE(left),AOP_SIZE(right));
4757 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4761 /* if literal is on the right then swap with left */
4762 if ((AOP_TYPE(right) == AOP_LIT)) {
4763 operand *tmp = right ;
4764 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4765 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4768 lit = (lit - 1) & mask;
4771 rFalseIfx.condition ^= 1;
4774 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4775 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4779 //if(IC_TRUE(ifx) == NULL)
4780 /* if left & right are bit variables */
4781 if (AOP_TYPE(left) == AOP_CRY &&
4782 AOP_TYPE(right) == AOP_CRY ) {
4783 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4784 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4786 /* subtract right from left if at the
4787 end the carry flag is set then we know that
4788 left is greater than right */
4790 symbol *lbl = newiTempLabel(NULL);
4793 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4794 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
4798 if(AOP_TYPE(right) == AOP_LIT) {
4800 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4802 DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
4809 genSkipCond(&rFalseIfx,left,size-1,7);
4811 /* no need to compare to 0...*/
4812 /* NOTE: this is a de-generate compare that most certainly
4813 * creates some dead code. */
4814 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4816 if(ifx) ifx->generated = 1;
4823 //i = (lit >> (size*8)) & 0xff;
4824 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4826 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4828 i = ((0-lit) & 0xff);
4831 /* lit is 0x7f, all signed chars are less than
4832 * this except for 0x7f itself */
4833 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4834 genSkipz2(&rFalseIfx,0);
4836 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4837 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4838 genSkipc(&rFalseIfx);
4843 genSkipz2(&rFalseIfx,1);
4845 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4846 genSkipc(&rFalseIfx);
4850 if(ifx) ifx->generated = 1;
4854 /* chars are out of the way. now do ints and longs */
4857 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4864 genSkipCond(&rFalseIfx,left,size,7);
4865 if(ifx) ifx->generated = 1;
4870 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4872 //rFalseIfx.condition ^= 1;
4873 //genSkipCond(&rFalseIfx,left,size,7);
4874 //rFalseIfx.condition ^= 1;
4876 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4877 if(rFalseIfx.condition)
4878 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4880 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4882 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4883 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4884 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4887 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4889 if(rFalseIfx.condition) {
4891 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4897 genSkipc(&rFalseIfx);
4898 pic16_emitpLabel(truelbl->key);
4899 if(ifx) ifx->generated = 1;
4906 if( (lit & 0xff) == 0) {
4907 /* lower byte is zero */
4908 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4909 i = ((lit >> 8) & 0xff) ^0x80;
4910 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4911 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4912 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4913 genSkipc(&rFalseIfx);
4916 if(ifx) ifx->generated = 1;
4921 /* Special cases for signed longs */
4922 if( (lit & 0xffffff) == 0) {
4923 /* lower byte is zero */
4924 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4925 i = ((lit >> 8*3) & 0xff) ^0x80;
4926 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4927 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4928 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4929 genSkipc(&rFalseIfx);
4932 if(ifx) ifx->generated = 1;
4940 if(lit & (0x80 << (size*8))) {
4941 /* lit is negative */
4942 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4944 //genSkipCond(&rFalseIfx,left,size,7);
4946 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4948 if(rFalseIfx.condition)
4949 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4951 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4955 /* lit is positive */
4956 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4957 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
4958 if(rFalseIfx.condition)
4959 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4961 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4966 This works, but is only good for ints.
4967 It also requires a "known zero" register.
4968 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4969 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4970 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4971 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4972 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4973 genSkipc(&rFalseIfx);
4975 pic16_emitpLabel(truelbl->key);
4976 if(ifx) ifx->generated = 1;
4980 /* There are no more special cases, so perform a general compare */
4982 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4983 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4987 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4989 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4991 //rFalseIfx.condition ^= 1;
4992 genSkipc(&rFalseIfx);
4994 pic16_emitpLabel(truelbl->key);
4996 if(ifx) ifx->generated = 1;
5003 /* sign is out of the way. So now do an unsigned compare */
5004 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
5007 /* General case - compare to an unsigned literal on the right.*/
5009 i = (lit >> (size*8)) & 0xff;
5010 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5011 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5013 i = (lit >> (size*8)) & 0xff;
5016 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5018 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5020 /* this byte of the lit is zero,
5021 *if it's not the last then OR in the variable */
5023 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
5028 pic16_emitpLabel(lbl->key);
5029 // pic16_emitpLabel(truelbl->key);
5030 //if(emitFinalCheck)
5031 genSkipc(&rFalseIfx);
5033 pic16_emitpLabel(truelbl->key);
5035 if(ifx) ifx->generated = 1;
5042 if(AOP_TYPE(left) == AOP_LIT) {
5043 //symbol *lbl = newiTempLabel(NULL);
5045 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
5048 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
5051 if((lit == 0) && (sign == 0)){
5054 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5056 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
5058 genSkipz2(&rFalseIfx,0);
5059 if(ifx) ifx->generated = 1;
5066 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
5067 /* degenerate compare can never be true */
5068 if(rFalseIfx.condition == 0)
5069 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
5071 if(ifx) ifx->generated = 1;
5076 /* signed comparisons to a literal byte */
5078 int lp1 = (lit+1) & 0xff;
5080 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
5083 rFalseIfx.condition ^= 1;
5084 genSkipCond(&rFalseIfx,right,0,7);
5087 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5088 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
5089 genSkipz2(&rFalseIfx,1);
5092 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5093 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5094 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
5095 rFalseIfx.condition ^= 1;
5096 genSkipc(&rFalseIfx);
5100 /* unsigned comparisons to a literal byte */
5102 switch(lit & 0xff ) {
5104 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5105 genSkipz2(&rFalseIfx,0);
5108 rFalseIfx.condition ^= 1;
5109 genSkipCond(&rFalseIfx,right,0,7);
5113 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
5114 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5115 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5116 rFalseIfx.condition ^= 1;
5117 if (AOP_TYPE(result) == AOP_CRY)
5118 genSkipc(&rFalseIfx);
5120 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5121 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5127 if(ifx) ifx->generated = 1;
5128 if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
5134 /* Size is greater than 1 */
5142 /* this means lit = 0xffffffff, or -1 */
5145 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
5146 rFalseIfx.condition ^= 1;
5147 genSkipCond(&rFalseIfx,right,size,7);
5148 if(ifx) ifx->generated = 1;
5155 if(rFalseIfx.condition) {
5156 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5157 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5160 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5162 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5166 if(rFalseIfx.condition) {
5167 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5168 pic16_emitpLabel(truelbl->key);
5170 rFalseIfx.condition ^= 1;
5171 genSkipCond(&rFalseIfx,right,s,7);
5174 if(ifx) ifx->generated = 1;
5178 if((size == 1) && (0 == (lp1&0xff))) {
5179 /* lower byte of signed word is zero */
5180 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
5181 i = ((lp1 >> 8) & 0xff) ^0x80;
5182 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5183 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
5184 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
5185 rFalseIfx.condition ^= 1;
5186 genSkipc(&rFalseIfx);
5189 if(ifx) ifx->generated = 1;
5193 if(lit & (0x80 << (size*8))) {
5194 /* Lit is less than zero */
5195 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
5196 //rFalseIfx.condition ^= 1;
5197 //genSkipCond(&rFalseIfx,left,size,7);
5198 //rFalseIfx.condition ^= 1;
5199 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5200 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5202 if(rFalseIfx.condition)
5203 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5205 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5209 /* Lit is greater than or equal to zero */
5210 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
5211 //rFalseIfx.condition ^= 1;
5212 //genSkipCond(&rFalseIfx,right,size,7);
5213 //rFalseIfx.condition ^= 1;
5215 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
5216 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5218 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
5219 if(rFalseIfx.condition)
5220 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5222 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5227 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5228 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5232 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5234 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5236 rFalseIfx.condition ^= 1;
5237 //rFalseIfx.condition = 1;
5238 genSkipc(&rFalseIfx);
5240 pic16_emitpLabel(truelbl->key);
5242 if(ifx) ifx->generated = 1;
5247 /* compare word or long to an unsigned literal on the right.*/
5252 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5255 break; /* handled above */
5258 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5260 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5261 genSkipz2(&rFalseIfx,0);
5265 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5267 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5270 if(rFalseIfx.condition)
5271 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5273 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5276 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5277 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5279 rFalseIfx.condition ^= 1;
5280 genSkipc(&rFalseIfx);
5283 pic16_emitpLabel(truelbl->key);
5285 if(ifx) ifx->generated = 1;
5291 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5292 i = (lit >> (size*8)) & 0xff;
5294 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5295 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5298 i = (lit >> (size*8)) & 0xff;
5301 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5303 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5305 /* this byte of the lit is zero,
5306 * if it's not the last then OR in the variable */
5308 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5313 pic16_emitpLabel(lbl->key);
5315 rFalseIfx.condition ^= 1;
5317 genSkipc(&rFalseIfx);
5321 pic16_emitpLabel(truelbl->key);
5322 if(ifx) ifx->generated = 1;
5326 /* Compare two variables */
5328 DEBUGpic16_emitcode(";sign","%d",sign);
5332 /* Sigh. thus sucks... */
5336 pctemp = pic16_popGetTempReg();
5337 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5338 pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
5339 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5340 pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5341 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5342 pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
5343 pic16_popReleaseTempReg(pctemp);
5345 /* Signed char comparison */
5346 /* Special thanks to Nikolai Golovchenko for this snippet */
5347 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5348 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5349 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5350 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5351 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5352 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5354 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5355 genSkipc(&rFalseIfx);
5357 if(ifx) ifx->generated = 1;
5363 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5364 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5368 /* The rest of the bytes of a multi-byte compare */
5372 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5375 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5376 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5381 pic16_emitpLabel(lbl->key);
5383 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5384 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5385 (AOP_TYPE(result) == AOP_REG)) {
5386 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5387 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5389 genSkipc(&rFalseIfx);
5391 //genSkipc(&rFalseIfx);
5392 if(ifx) ifx->generated = 1;
5399 if ((AOP_TYPE(result) != AOP_CRY)
5400 && AOP_SIZE(result)) {
5401 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5403 if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
5405 pic16_outBitC(result);
5407 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5408 /* if the result is used in the next
5409 ifx conditional branch then generate
5410 code a little differently */
5412 genIfxJump (ifx,"c");
5414 pic16_outBitC(result);
5415 /* leave the result in acc */
5420 /*-----------------------------------------------------------------*/
5421 /* genCmpGt :- greater than comparison */
5422 /*-----------------------------------------------------------------*/
5423 static void genCmpGt (iCode *ic, iCode *ifx)
5425 operand *left, *right, *result;
5426 sym_link *letype , *retype;
5429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5431 right= IC_RIGHT(ic);
5432 result = IC_RESULT(ic);
5434 letype = getSpec(operandType(left));
5435 retype =getSpec(operandType(right));
5436 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5437 /* assign the amsops */
5438 pic16_aopOp (left,ic,FALSE);
5439 pic16_aopOp (right,ic,FALSE);
5440 pic16_aopOp (result,ic,TRUE);
5442 genCmp(right, left, result, ifx, sign);
5444 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5445 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5446 pic16_freeAsmop(result,NULL,ic,TRUE);
5449 /*-----------------------------------------------------------------*/
5450 /* genCmpLt - less than comparisons */
5451 /*-----------------------------------------------------------------*/
5452 static void genCmpLt (iCode *ic, iCode *ifx)
5454 operand *left, *right, *result;
5455 sym_link *letype , *retype;
5458 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5460 right= IC_RIGHT(ic);
5461 result = IC_RESULT(ic);
5463 letype = getSpec(operandType(left));
5464 retype =getSpec(operandType(right));
5465 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5467 /* assign the amsops */
5468 pic16_aopOp (left,ic,FALSE);
5469 pic16_aopOp (right,ic,FALSE);
5470 pic16_aopOp (result,ic,TRUE);
5472 genCmp(left, right, result, ifx, sign);
5474 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5475 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5476 pic16_freeAsmop(result,NULL,ic,TRUE);
5481 // FIXME reenable literal optimisation when the pic16 port is stable
5483 /*-----------------------------------------------------------------*/
5484 /* genc16bit2lit - compare a 16 bit value to a literal */
5485 /*-----------------------------------------------------------------*/
5486 static void genc16bit2lit(operand *op, int lit, int offset)
5490 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5491 if( (lit&0xff) == 0)
5496 switch( BYTEofLONG(lit,i)) {
5498 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5501 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5504 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5507 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5508 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5513 switch( BYTEofLONG(lit,i)) {
5515 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5519 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5523 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5526 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5528 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5537 /*-----------------------------------------------------------------*/
5538 /* gencjneshort - compare and jump if not equal */
5539 /*-----------------------------------------------------------------*/
5540 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5542 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5544 int res_offset = 0; /* the result may be a different size then left or right */
5545 int res_size = AOP_SIZE(result);
5547 symbol *lbl, *lbl_done;
5549 unsigned long lit = 0L;
5550 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5552 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5553 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5555 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5556 resolveIfx(&rIfx,ifx);
5557 lbl = newiTempLabel(NULL);
5558 lbl_done = newiTempLabel(NULL);
5561 /* if the left side is a literal or
5562 if the right is in a pointer register and left
5564 if ((AOP_TYPE(left) == AOP_LIT) ||
5565 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5570 if(AOP_TYPE(right) == AOP_LIT)
5571 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5573 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5574 preserve_result = 1;
5576 if(result && !preserve_result)
5579 for(i = 0; i < AOP_SIZE(result); i++)
5580 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5584 /* if the right side is a literal then anything goes */
5585 if (AOP_TYPE(right) == AOP_LIT &&
5586 AOP_TYPE(left) != AOP_DIR ) {
5589 genc16bit2lit(left, lit, 0);
5591 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5594 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5597 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5598 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5600 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5604 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5606 if(res_offset < res_size-1)
5614 /* if the right side is in a register or in direct space or
5615 if the left is a pointer register & right is not */
5616 else if (AOP_TYPE(right) == AOP_REG ||
5617 AOP_TYPE(right) == AOP_DIR ||
5618 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5619 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5620 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5621 int lbl_key = lbl->key;
5624 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5625 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5627 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5628 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5629 __FUNCTION__,__LINE__);
5633 /* switch(size) { */
5635 /* genc16bit2lit(left, lit, 0); */
5637 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5642 if((AOP_TYPE(left) == AOP_DIR) &&
5643 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5645 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5646 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5648 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5650 switch (lit & 0xff) {
5652 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5655 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5656 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5657 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5661 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5662 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5663 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5664 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5668 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5669 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5674 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5677 if(AOP_TYPE(result) == AOP_CRY) {
5678 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5683 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5685 /* fix me. probably need to check result size too */
5686 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5691 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5692 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5699 if(res_offset < res_size-1)
5704 } else if(AOP_TYPE(right) == AOP_REG &&
5705 AOP_TYPE(left) != AOP_DIR){
5708 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5709 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5710 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5715 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5717 if(res_offset < res_size-1)
5722 /* right is a pointer reg need both a & b */
5724 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5726 pic16_emitcode("mov","b,%s",l);
5727 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5728 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5733 if(result && preserve_result)
5736 for(i = 0; i < AOP_SIZE(result); i++)
5737 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5740 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
5742 if(result && preserve_result)
5743 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
5746 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5748 pic16_emitpLabel(lbl->key);
5750 if(result && preserve_result)
5753 for(i = 0; i < AOP_SIZE(result); i++)
5754 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5756 pic16_emitpLabel(lbl_done->key);
5759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5767 /*-----------------------------------------------------------------*/
5768 /* gencjne - compare and jump if not equal */
5769 /*-----------------------------------------------------------------*/
5770 static void gencjne(operand *left, operand *right, iCode *ifx)
5772 symbol *tlbl = newiTempLabel(NULL);
5774 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5775 gencjneshort(left, right, lbl);
5777 pic16_emitcode("mov","a,%s",one);
5778 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5779 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5780 pic16_emitcode("clr","a");
5781 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5783 pic16_emitpLabel(lbl->key);
5784 pic16_emitpLabel(tlbl->key);
5790 /*-----------------------------------------------------------------*/
5791 /* is_LitOp - check if operand has to be treated as literal */
5792 /*-----------------------------------------------------------------*/
5793 static bool is_LitOp(operand *op)
5795 return (AOP_TYPE(op) == AOP_LIT)
5796 || ( (AOP_TYPE(op) == AOP_PCODE)
5797 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
5798 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
5801 /*-----------------------------------------------------------------*/
5802 /* is_LitAOp - check if operand has to be treated as literal */
5803 /*-----------------------------------------------------------------*/
5804 static bool is_LitAOp(asmop *aop)
5806 return (aop->type == AOP_LIT)
5807 || ( (aop->type == AOP_PCODE)
5808 && ( (aop->aopu.pcop->type == PO_LITERAL)
5809 || (aop->aopu.pcop->type == PO_IMMEDIATE) ));
5814 /*-----------------------------------------------------------------*/
5815 /* genCmpEq - generates code for equal to */
5816 /*-----------------------------------------------------------------*/
5817 static void genCmpEq (iCode *ic, iCode *ifx)
5819 operand *left, *right, *result;
5820 symbol *falselbl = newiTempLabel(NULL);
5821 symbol *donelbl = newiTempLabel(NULL);
5823 int preserve_result = 0;
5824 int generate_result = 0;
5827 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5828 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5829 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5831 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5832 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5834 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
5836 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5837 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
5841 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
5843 operand *tmp = right ;
5848 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5849 preserve_result = 1;
5851 if(result && AOP_SIZE(result))
5852 generate_result = 1;
5854 if(generate_result && !preserve_result)
5856 for(i = 0; i < AOP_SIZE(result); i++)
5857 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5860 for(i=0; i < AOP_SIZE(left); i++)
5862 if(AOP_TYPE(left) != AOP_ACC)
5865 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
5867 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
5870 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
5872 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
5874 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
5879 if(generate_result && preserve_result)
5881 for(i = 0; i < AOP_SIZE(result); i++)
5882 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5886 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
5888 if(generate_result && preserve_result)
5889 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5891 if(ifx && IC_TRUE(ifx))
5892 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5894 if(ifx && IC_FALSE(ifx))
5895 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5897 pic16_emitpLabel(falselbl->key);
5901 if(ifx && IC_FALSE(ifx))
5902 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5904 if(generate_result && preserve_result)
5906 for(i = 0; i < AOP_SIZE(result); i++)
5907 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5910 pic16_emitpLabel(donelbl->key);
5916 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5917 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5918 pic16_freeAsmop(result,NULL,ic,TRUE);
5924 // old version kept for reference
5926 /*-----------------------------------------------------------------*/
5927 /* genCmpEq - generates code for equal to */
5928 /*-----------------------------------------------------------------*/
5929 static void genCmpEq (iCode *ic, iCode *ifx)
5931 operand *left, *right, *result;
5932 unsigned long lit = 0L;
5934 symbol *falselbl = newiTempLabel(NULL);
5937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5940 DEBUGpic16_emitcode ("; ifx is non-null","");
5942 DEBUGpic16_emitcode ("; ifx is null","");
5944 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5945 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5946 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5948 size = max(AOP_SIZE(left),AOP_SIZE(right));
5950 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5952 /* if literal, literal on the right or
5953 if the right is in a pointer register and left
5955 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5956 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5957 operand *tmp = right ;
5963 if(ifx && !AOP_SIZE(result)){
5965 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5966 /* if they are both bit variables */
5967 if (AOP_TYPE(left) == AOP_CRY &&
5968 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5969 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5970 if(AOP_TYPE(right) == AOP_LIT){
5971 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5973 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5974 pic16_emitcode("cpl","c");
5975 } else if(lit == 1L) {
5976 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5978 pic16_emitcode("clr","c");
5980 /* AOP_TYPE(right) == AOP_CRY */
5982 symbol *lbl = newiTempLabel(NULL);
5983 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5984 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5985 pic16_emitcode("cpl","c");
5986 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5988 /* if true label then we jump if condition
5990 tlbl = newiTempLabel(NULL);
5991 if ( IC_TRUE(ifx) ) {
5992 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5993 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5995 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5996 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5998 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6001 /* left and right are both bit variables, result is carry */
6004 resolveIfx(&rIfx,ifx);
6006 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
6007 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
6008 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
6009 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
6014 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
6016 /* They're not both bit variables. Is the right a literal? */
6017 if(AOP_TYPE(right) == AOP_LIT) {
6018 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6023 switch(lit & 0xff) {
6025 if ( IC_TRUE(ifx) ) {
6026 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
6028 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6030 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
6031 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6035 if ( IC_TRUE(ifx) ) {
6036 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
6038 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6040 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
6041 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6045 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6047 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
6052 /* end of size == 1 */
6056 genc16bit2lit(left,lit,offset);
6059 /* end of size == 2 */
6064 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6065 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
6066 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6067 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6070 /* search for patterns that can be optimized */
6072 genc16bit2lit(left,lit,0);
6076 emitSKPZ; // if hi word unequal
6078 emitSKPNZ; // if hi word equal
6080 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
6081 genc16bit2lit(left,lit,2);
6084 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
6085 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
6089 pic16_emitpLabel(falselbl->key);
6098 } else if(AOP_TYPE(right) == AOP_CRY ) {
6099 /* we know the left is not a bit, but that the right is */
6100 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6101 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
6102 pic16_popGet(AOP(right),offset));
6103 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
6105 /* if the two are equal, then W will be 0 and the Z bit is set
6106 * we could test Z now, or go ahead and check the high order bytes if
6107 * the variable we're comparing is larger than a byte. */
6110 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
6112 if ( IC_TRUE(ifx) ) {
6114 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6115 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6118 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6119 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6123 /* They're both variables that are larger than bits */
6126 tlbl = newiTempLabel(NULL);
6129 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6130 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6132 if ( IC_TRUE(ifx) ) {
6136 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
6138 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
6139 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
6143 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
6146 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
6147 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
6152 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
6154 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
6155 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
6159 if(s>1 && IC_TRUE(ifx)) {
6160 pic16_emitpLabel(tlbl->key);
6161 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6165 /* mark the icode as generated */
6170 /* if they are both bit variables */
6171 if (AOP_TYPE(left) == AOP_CRY &&
6172 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
6173 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
6174 if(AOP_TYPE(right) == AOP_LIT){
6175 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
6177 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6178 pic16_emitcode("cpl","c");
6179 } else if(lit == 1L) {
6180 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6182 pic16_emitcode("clr","c");
6184 /* AOP_TYPE(right) == AOP_CRY */
6186 symbol *lbl = newiTempLabel(NULL);
6187 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6188 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
6189 pic16_emitcode("cpl","c");
6190 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
6193 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
6194 pic16_outBitC(result);
6198 genIfxJump (ifx,"c");
6201 /* if the result is used in an arithmetic operation
6202 then put the result in place */
6203 pic16_outBitC(result);
6206 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
6207 gencjne(left,right,result,ifx);
6210 gencjne(left,right,newiTempLabel(NULL));
6212 if(IC_TRUE(ifx)->key)
6213 gencjne(left,right,IC_TRUE(ifx)->key);
6215 gencjne(left,right,IC_FALSE(ifx)->key);
6219 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
6220 pic16_aopPut(AOP(result),"a",0);
6225 genIfxJump (ifx,"a");
6229 /* if the result is used in an arithmetic operation
6230 then put the result in place */
6232 if (AOP_TYPE(result) != AOP_CRY)
6233 pic16_outAcc(result);
6235 /* leave the result in acc */
6239 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6240 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6241 pic16_freeAsmop(result,NULL,ic,TRUE);
6245 /*-----------------------------------------------------------------*/
6246 /* ifxForOp - returns the icode containing the ifx for operand */
6247 /*-----------------------------------------------------------------*/
6248 static iCode *ifxForOp ( operand *op, iCode *ic )
6250 /* if true symbol then needs to be assigned */
6251 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6252 if (IS_TRUE_SYMOP(op))
6255 /* if this has register type condition and
6256 the next instruction is ifx with the same operand
6257 and live to of the operand is upto the ifx only then */
6259 && ic->next->op == IFX
6260 && IC_COND(ic->next)->key == op->key
6261 && OP_SYMBOL(op)->liveTo <= ic->next->seq
6263 DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
6268 ic->next->op == IFX &&
6269 IC_COND(ic->next)->key == op->key) {
6270 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6274 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6276 ic->next->op == IFX)
6277 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6280 ic->next->op == IFX &&
6281 IC_COND(ic->next)->key == op->key) {
6282 DEBUGpic16_emitcode ("; "," key is okay");
6283 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6284 OP_SYMBOL(op)->liveTo,
6289 /* the code below is completely untested
6290 * it just allows ulong2fs.c compile -- VR */
6293 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6294 __FILE__, __FUNCTION__, __LINE__);
6296 /* if this has register type condition and
6297 the next instruction is ifx with the same operand
6298 and live to of the operand is upto the ifx only then */
6300 ic->next->op == IFX &&
6301 IC_COND(ic->next)->key == op->key &&
6302 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6306 ic->next->op == IFX &&
6307 IC_COND(ic->next)->key == op->key) {
6308 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6312 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6313 __FILE__, __FUNCTION__, __LINE__);
6315 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6320 /*-----------------------------------------------------------------*/
6321 /* genAndOp - for && operation */
6322 /*-----------------------------------------------------------------*/
6323 static void genAndOp (iCode *ic)
6325 operand *left,*right, *result;
6328 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6329 /* note here that && operations that are in an
6330 if statement are taken away by backPatchLabels
6331 only those used in arthmetic operations remain */
6332 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6333 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6334 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6336 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6338 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6339 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6340 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6342 /* if both are bit variables */
6343 /* if (AOP_TYPE(left) == AOP_CRY && */
6344 /* AOP_TYPE(right) == AOP_CRY ) { */
6345 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6346 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6347 /* pic16_outBitC(result); */
6349 /* tlbl = newiTempLabel(NULL); */
6350 /* pic16_toBoolean(left); */
6351 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6352 /* pic16_toBoolean(right); */
6353 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6354 /* pic16_outBitAcc(result); */
6357 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6358 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6359 pic16_freeAsmop(result,NULL,ic,TRUE);
6363 /*-----------------------------------------------------------------*/
6364 /* genOrOp - for || operation */
6365 /*-----------------------------------------------------------------*/
6368 modified this code, but it doesn't appear to ever get called
6371 static void genOrOp (iCode *ic)
6373 operand *left,*right, *result;
6376 /* note here that || operations that are in an
6377 if statement are taken away by backPatchLabels
6378 only those used in arthmetic operations remain */
6379 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6380 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6381 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6382 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6384 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6386 /* if both are bit variables */
6387 if (AOP_TYPE(left) == AOP_CRY &&
6388 AOP_TYPE(right) == AOP_CRY ) {
6389 pic16_emitcode("clrc","");
6390 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6391 AOP(left)->aopu.aop_dir,
6392 AOP(left)->aopu.aop_dir);
6393 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6394 AOP(right)->aopu.aop_dir,
6395 AOP(right)->aopu.aop_dir);
6396 pic16_emitcode("setc","");
6399 tlbl = newiTempLabel(NULL);
6400 pic16_toBoolean(left);
6402 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
6403 pic16_toBoolean(right);
6404 pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
6406 pic16_outBitAcc(result);
6409 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6410 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6411 pic16_freeAsmop(result,NULL,ic,TRUE);
6414 /*-----------------------------------------------------------------*/
6415 /* isLiteralBit - test if lit == 2^n */
6416 /*-----------------------------------------------------------------*/
6417 static int isLiteralBit(unsigned long lit)
6419 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6420 0x100L,0x200L,0x400L,0x800L,
6421 0x1000L,0x2000L,0x4000L,0x8000L,
6422 0x10000L,0x20000L,0x40000L,0x80000L,
6423 0x100000L,0x200000L,0x400000L,0x800000L,
6424 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6425 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6429 for(idx = 0; idx < 32; idx++)
6435 /*-----------------------------------------------------------------*/
6436 /* continueIfTrue - */
6437 /*-----------------------------------------------------------------*/
6438 static void continueIfTrue (iCode *ic)
6440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6442 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6446 /*-----------------------------------------------------------------*/
6448 /*-----------------------------------------------------------------*/
6449 static void jumpIfTrue (iCode *ic)
6451 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6453 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6457 /*-----------------------------------------------------------------*/
6458 /* jmpTrueOrFalse - */
6459 /*-----------------------------------------------------------------*/
6460 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6462 // ugly but optimized by peephole
6463 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6465 symbol *nlbl = newiTempLabel(NULL);
6466 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6467 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6468 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6469 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6472 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6473 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6478 /*-----------------------------------------------------------------*/
6479 /* genAnd - code for and */
6480 /*-----------------------------------------------------------------*/
6481 static void genAnd (iCode *ic, iCode *ifx)
6483 operand *left, *right, *result;
6485 unsigned long lit = 0L;
6490 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6491 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6492 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6493 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6495 resolveIfx(&rIfx,ifx);
6497 /* if left is a literal & right is not then exchange them */
6498 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6499 AOP_NEEDSACC(left)) {
6500 operand *tmp = right ;
6505 /* if result = right then exchange them */
6506 if(pic16_sameRegs(AOP(result),AOP(right))){
6507 operand *tmp = right ;
6512 /* if right is bit then exchange them */
6513 if (AOP_TYPE(right) == AOP_CRY &&
6514 AOP_TYPE(left) != AOP_CRY){
6515 operand *tmp = right ;
6519 if(AOP_TYPE(right) == AOP_LIT)
6520 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6522 size = AOP_SIZE(result);
6524 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6527 // result = bit & yy;
6528 if (AOP_TYPE(left) == AOP_CRY){
6529 // c = bit & literal;
6530 if(AOP_TYPE(right) == AOP_LIT){
6532 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6535 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6538 if(size && (AOP_TYPE(result) == AOP_CRY)){
6539 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6542 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6546 pic16_emitcode("clr","c");
6549 if (AOP_TYPE(right) == AOP_CRY){
6551 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6552 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6555 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6557 pic16_emitcode("rrc","a");
6558 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6564 pic16_outBitC(result);
6566 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6567 genIfxJump(ifx, "c");
6571 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6572 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6573 if((AOP_TYPE(right) == AOP_LIT) &&
6574 (AOP_TYPE(result) == AOP_CRY) &&
6575 (AOP_TYPE(left) != AOP_CRY)){
6576 int posbit = isLiteralBit(lit);
6580 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6583 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6589 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6590 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6592 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6593 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6596 DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
6597 size = AOP_SIZE(left);
6600 int bp = posbit, ofs=0;
6607 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6608 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
6612 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6613 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6615 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6622 symbol *tlbl = newiTempLabel(NULL);
6623 int sizel = AOP_SIZE(left);
6629 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) {
6631 /* patch provided by Aaron Colwell */
6632 if((posbit = isLiteralBit(bytelit)) != 0) {
6633 pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ),
6634 pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE),
6635 (posbit-1),0, PO_GPR_REGISTER));
6637 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key));
6638 // pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
6640 if (bytelit == 0xff) {
6641 /* Aaron had a MOVF instruction here, changed to MOVFW cause
6642 * a peephole could optimize it out -- VR */
6643 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
6645 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset));
6646 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit));
6649 pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
6650 pic16_popGetLabel(tlbl->key));
6654 /* old code, left here for reference -- VR 09/2004 */
6655 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6657 if((posbit = isLiteralBit(bytelit)) != 0)
6658 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
6660 if(bytelit != 0x0FFL)
6661 pic16_emitcode("anl","a,%s",
6662 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
6663 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6669 // bit = left & literal
6672 pic16_emitpLabel(tlbl->key);
6674 // if(left & literal)
6677 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key));
6678 pic16_emitpLabel(tlbl->key);
6685 pic16_outBitC(result);
6689 /* if left is same as result */
6690 if(pic16_sameRegs(AOP(result),AOP(left))){
6692 for(;size--; offset++,lit>>=8) {
6693 if(AOP_TYPE(right) == AOP_LIT){
6694 switch(lit & 0xff) {
6696 /* and'ing with 0 has clears the result */
6697 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6698 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6701 /* and'ing with 0xff is a nop when the result and left are the same */
6706 int p = my_powof2( (~lit) & 0xff );
6708 /* only one bit is set in the literal, so use a bcf instruction */
6709 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
6710 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
6713 pic16_emitcode("movlw","0x%x", (lit & 0xff));
6714 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6715 if(know_W != (lit&0xff))
6716 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6718 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6723 if (AOP_TYPE(left) == AOP_ACC) {
6724 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6726 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6727 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6734 // left & result in different registers
6735 if(AOP_TYPE(result) == AOP_CRY){
6737 // if(size), result in bit
6738 // if(!size && ifx), conditional oper: if(left & right)
6739 symbol *tlbl = newiTempLabel(NULL);
6740 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
6742 pic16_emitcode("setb","c");
6744 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6745 pic16_emitcode("anl","a,%s",
6746 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6747 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6752 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6753 pic16_outBitC(result);
6755 jmpTrueOrFalse(ifx, tlbl);
6757 for(;(size--);offset++) {
6759 // result = left & right
6760 if(AOP_TYPE(right) == AOP_LIT){
6761 int t = (lit >> (offset*8)) & 0x0FFL;
6764 pic16_emitcode("clrf","%s",
6765 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6766 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6769 pic16_emitcode("movf","%s,w",
6770 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6771 pic16_emitcode("movwf","%s",
6772 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6773 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6774 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6777 pic16_emitcode("movlw","0x%x",t);
6778 pic16_emitcode("andwf","%s,w",
6779 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6780 pic16_emitcode("movwf","%s",
6781 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6783 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6784 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6785 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6790 if (AOP_TYPE(left) == AOP_ACC) {
6791 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6792 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6794 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6795 pic16_emitcode("andwf","%s,w",
6796 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6797 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6798 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6800 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6801 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6807 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6808 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6809 pic16_freeAsmop(result,NULL,ic,TRUE);
6812 /*-----------------------------------------------------------------*/
6813 /* genOr - code for or */
6814 /*-----------------------------------------------------------------*/
6815 static void genOr (iCode *ic, iCode *ifx)
6817 operand *left, *right, *result;
6819 unsigned long lit = 0L;
6821 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6823 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6824 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6825 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6827 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6829 /* if left is a literal & right is not then exchange them */
6830 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6831 AOP_NEEDSACC(left)) {
6832 operand *tmp = right ;
6837 /* if result = right then exchange them */
6838 if(pic16_sameRegs(AOP(result),AOP(right))){
6839 operand *tmp = right ;
6844 /* if right is bit then exchange them */
6845 if (AOP_TYPE(right) == AOP_CRY &&
6846 AOP_TYPE(left) != AOP_CRY){
6847 operand *tmp = right ;
6852 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6854 if(AOP_TYPE(right) == AOP_LIT)
6855 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6857 size = AOP_SIZE(result);
6861 if (AOP_TYPE(left) == AOP_CRY){
6862 if(AOP_TYPE(right) == AOP_LIT){
6863 // c = bit & literal;
6865 // lit != 0 => result = 1
6866 if(AOP_TYPE(result) == AOP_CRY){
6868 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6869 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6870 // AOP(result)->aopu.aop_dir,
6871 // AOP(result)->aopu.aop_dir);
6873 continueIfTrue(ifx);
6877 // lit == 0 => result = left
6878 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6880 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6883 if (AOP_TYPE(right) == AOP_CRY){
6884 if(pic16_sameRegs(AOP(result),AOP(left))){
6886 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6887 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6888 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6890 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6891 AOP(result)->aopu.aop_dir,
6892 AOP(result)->aopu.aop_dir);
6893 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6894 AOP(right)->aopu.aop_dir,
6895 AOP(right)->aopu.aop_dir);
6896 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6897 AOP(result)->aopu.aop_dir,
6898 AOP(result)->aopu.aop_dir);
6900 if( AOP_TYPE(result) == AOP_ACC) {
6901 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6902 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6903 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6904 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6908 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6909 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6910 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6911 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6913 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6914 AOP(result)->aopu.aop_dir,
6915 AOP(result)->aopu.aop_dir);
6916 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6917 AOP(right)->aopu.aop_dir,
6918 AOP(right)->aopu.aop_dir);
6919 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6920 AOP(left)->aopu.aop_dir,
6921 AOP(left)->aopu.aop_dir);
6922 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6923 AOP(result)->aopu.aop_dir,
6924 AOP(result)->aopu.aop_dir);
6929 symbol *tlbl = newiTempLabel(NULL);
6930 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6933 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6934 if( AOP_TYPE(right) == AOP_ACC) {
6935 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6937 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6938 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6943 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6944 pic16_emitcode(";XXX setb","c");
6945 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6946 AOP(left)->aopu.aop_dir,tlbl->key+100);
6947 pic16_toBoolean(right);
6948 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6949 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6950 jmpTrueOrFalse(ifx, tlbl);
6954 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6961 pic16_outBitC(result);
6963 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6964 genIfxJump(ifx, "c");
6968 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6969 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6970 if((AOP_TYPE(right) == AOP_LIT) &&
6971 (AOP_TYPE(result) == AOP_CRY) &&
6972 (AOP_TYPE(left) != AOP_CRY)){
6974 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6977 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6979 continueIfTrue(ifx);
6982 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6983 // lit = 0, result = boolean(left)
6985 pic16_emitcode(";XXX setb","c");
6986 pic16_toBoolean(right);
6988 symbol *tlbl = newiTempLabel(NULL);
6989 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6991 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6993 genIfxJump (ifx,"a");
6997 pic16_outBitC(result);
7001 /* if left is same as result */
7002 if(pic16_sameRegs(AOP(result),AOP(left))){
7004 for(;size--; offset++,lit>>=8) {
7005 if(AOP_TYPE(right) == AOP_LIT){
7006 if((lit & 0xff) == 0)
7007 /* or'ing with 0 has no effect */
7010 int p = my_powof2(lit & 0xff);
7012 /* only one bit is set in the literal, so use a bsf instruction */
7013 pic16_emitpcode(POC_BSF,
7014 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
7016 if(know_W != (lit & 0xff))
7017 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
7018 know_W = lit & 0xff;
7019 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7024 if (AOP_TYPE(left) == AOP_ACC) {
7025 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
7026 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7028 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7029 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
7031 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7032 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7038 // left & result in different registers
7039 if(AOP_TYPE(result) == AOP_CRY){
7041 // if(size), result in bit
7042 // if(!size && ifx), conditional oper: if(left | right)
7043 symbol *tlbl = newiTempLabel(NULL);
7044 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7045 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
7049 pic16_emitcode(";XXX setb","c");
7051 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7052 pic16_emitcode(";XXX orl","a,%s",
7053 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7054 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
7059 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7060 pic16_outBitC(result);
7062 jmpTrueOrFalse(ifx, tlbl);
7063 } else for(;(size--);offset++){
7065 // result = left & right
7066 if(AOP_TYPE(right) == AOP_LIT){
7067 int t = (lit >> (offset*8)) & 0x0FFL;
7070 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7071 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7073 pic16_emitcode("movf","%s,w",
7074 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7075 pic16_emitcode("movwf","%s",
7076 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7079 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7080 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7081 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7083 pic16_emitcode("movlw","0x%x",t);
7084 pic16_emitcode("iorwf","%s,w",
7085 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7086 pic16_emitcode("movwf","%s",
7087 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7093 // faster than result <- left, anl result,right
7094 // and better if result is SFR
7095 if (AOP_TYPE(left) == AOP_ACC) {
7096 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
7097 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7099 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
7100 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
7102 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7103 pic16_emitcode("iorwf","%s,w",
7104 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7106 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7107 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7112 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7113 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7114 pic16_freeAsmop(result,NULL,ic,TRUE);
7117 /*-----------------------------------------------------------------*/
7118 /* genXor - code for xclusive or */
7119 /*-----------------------------------------------------------------*/
7120 static void genXor (iCode *ic, iCode *ifx)
7122 operand *left, *right, *result;
7124 unsigned long lit = 0L;
7126 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7128 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
7129 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
7130 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
7132 /* if left is a literal & right is not ||
7133 if left needs acc & right does not */
7134 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
7135 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
7136 operand *tmp = right ;
7141 /* if result = right then exchange them */
7142 if(pic16_sameRegs(AOP(result),AOP(right))){
7143 operand *tmp = right ;
7148 /* if right is bit then exchange them */
7149 if (AOP_TYPE(right) == AOP_CRY &&
7150 AOP_TYPE(left) != AOP_CRY){
7151 operand *tmp = right ;
7155 if(AOP_TYPE(right) == AOP_LIT)
7156 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
7158 size = AOP_SIZE(result);
7162 if (AOP_TYPE(left) == AOP_CRY){
7163 if(AOP_TYPE(right) == AOP_LIT){
7164 // c = bit & literal;
7166 // lit>>1 != 0 => result = 1
7167 if(AOP_TYPE(result) == AOP_CRY){
7169 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
7170 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
7172 continueIfTrue(ifx);
7175 pic16_emitcode("setb","c");
7179 // lit == 0, result = left
7180 if(size && pic16_sameRegs(AOP(result),AOP(left)))
7182 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7184 // lit == 1, result = not(left)
7185 if(size && pic16_sameRegs(AOP(result),AOP(left))){
7186 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
7187 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
7188 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
7191 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
7192 pic16_emitcode("cpl","c");
7199 symbol *tlbl = newiTempLabel(NULL);
7200 if (AOP_TYPE(right) == AOP_CRY){
7202 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
7205 int sizer = AOP_SIZE(right);
7207 // if val>>1 != 0, result = 1
7208 pic16_emitcode("setb","c");
7210 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
7212 // test the msb of the lsb
7213 pic16_emitcode("anl","a,#0xfe");
7214 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7218 pic16_emitcode("rrc","a");
7220 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
7221 pic16_emitcode("cpl","c");
7222 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
7227 pic16_outBitC(result);
7229 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
7230 genIfxJump(ifx, "c");
7234 if(pic16_sameRegs(AOP(result),AOP(left))){
7235 /* if left is same as result */
7236 for(;size--; offset++) {
7237 if(AOP_TYPE(right) == AOP_LIT){
7238 int t = (lit >> (offset*8)) & 0x0FFL;
7242 if (IS_AOP_PREG(left)) {
7243 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7244 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7245 pic16_aopPut(AOP(result),"a",offset);
7247 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7248 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7249 pic16_emitcode("xrl","%s,%s",
7250 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
7251 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7254 if (AOP_TYPE(left) == AOP_ACC)
7255 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7257 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7258 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
7260 if (IS_AOP_PREG(left)) {
7261 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7262 pic16_aopPut(AOP(result),"a",offset);
7264 pic16_emitcode("xrl","%s,a",
7265 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
7271 // left & result in different registers
7272 if(AOP_TYPE(result) == AOP_CRY){
7274 // if(size), result in bit
7275 // if(!size && ifx), conditional oper: if(left ^ right)
7276 symbol *tlbl = newiTempLabel(NULL);
7277 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
7279 pic16_emitcode("setb","c");
7281 if((AOP_TYPE(right) == AOP_LIT) &&
7282 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
7283 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7285 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7286 pic16_emitcode("xrl","a,%s",
7287 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7289 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
7294 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7295 pic16_outBitC(result);
7297 jmpTrueOrFalse(ifx, tlbl);
7298 } else for(;(size--);offset++){
7300 // result = left & right
7301 if(AOP_TYPE(right) == AOP_LIT){
7302 int t = (lit >> (offset*8)) & 0x0FFL;
7305 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7306 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7307 pic16_emitcode("movf","%s,w",
7308 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7309 pic16_emitcode("movwf","%s",
7310 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7313 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7314 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7315 pic16_emitcode("comf","%s,w",
7316 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7317 pic16_emitcode("movwf","%s",
7318 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7321 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7322 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7323 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7324 pic16_emitcode("movlw","0x%x",t);
7325 pic16_emitcode("xorwf","%s,w",
7326 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7327 pic16_emitcode("movwf","%s",
7328 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7334 // faster than result <- left, anl result,right
7335 // and better if result is SFR
7336 if (AOP_TYPE(left) == AOP_ACC) {
7337 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7338 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7340 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7341 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7342 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7343 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7345 if ( AOP_TYPE(result) != AOP_ACC){
7346 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7347 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7353 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7354 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7355 pic16_freeAsmop(result,NULL,ic,TRUE);
7358 /*-----------------------------------------------------------------*/
7359 /* genInline - write the inline code out */
7360 /*-----------------------------------------------------------------*/
7361 static void genInline (iCode *ic)
7363 char *buffer, *bp, *bp1;
7365 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7367 _G.inLine += (!options.asmpeep);
7369 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7370 strcpy(buffer,IC_INLINE(ic));
7372 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7374 /* emit each line as a code */
7380 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7388 /* print label, use this special format with NULL directive
7389 * to denote that the argument should not be indented with tab */
7390 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7397 if ((bp1 != bp) && *bp1)
7398 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7403 _G.inLine -= (!options.asmpeep);
7406 /*-----------------------------------------------------------------*/
7407 /* genRRC - rotate right with carry */
7408 /*-----------------------------------------------------------------*/
7409 static void genRRC (iCode *ic)
7411 operand *left , *result ;
7412 int size, offset = 0, same;
7414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7416 /* rotate right with carry */
7418 result=IC_RESULT(ic);
7419 pic16_aopOp (left,ic,FALSE);
7420 pic16_aopOp (result,ic,FALSE);
7422 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7424 same = pic16_sameRegs(AOP(result),AOP(left));
7426 size = AOP_SIZE(result);
7428 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7430 /* get the lsb and put it into the carry */
7431 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7438 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7440 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7441 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7447 pic16_freeAsmop(left,NULL,ic,TRUE);
7448 pic16_freeAsmop(result,NULL,ic,TRUE);
7451 /*-----------------------------------------------------------------*/
7452 /* genRLC - generate code for rotate left with carry */
7453 /*-----------------------------------------------------------------*/
7454 static void genRLC (iCode *ic)
7456 operand *left , *result ;
7457 int size, offset = 0;
7460 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7461 /* rotate right with carry */
7463 result=IC_RESULT(ic);
7464 pic16_aopOp (left,ic,FALSE);
7465 pic16_aopOp (result,ic,FALSE);
7467 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7469 same = pic16_sameRegs(AOP(result),AOP(left));
7471 /* move it to the result */
7472 size = AOP_SIZE(result);
7474 /* get the msb and put it into the carry */
7475 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7482 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7484 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7485 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7492 pic16_freeAsmop(left,NULL,ic,TRUE);
7493 pic16_freeAsmop(result,NULL,ic,TRUE);
7497 /* gpasm can get the highest order bit with HIGH/UPPER
7498 * so the following probably is not needed -- VR */
7500 /*-----------------------------------------------------------------*/
7501 /* genGetHbit - generates code get highest order bit */
7502 /*-----------------------------------------------------------------*/
7503 static void genGetHbit (iCode *ic)
7505 operand *left, *result;
7507 result=IC_RESULT(ic);
7508 pic16_aopOp (left,ic,FALSE);
7509 pic16_aopOp (result,ic,FALSE);
7511 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7512 /* get the highest order byte into a */
7513 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7514 if(AOP_TYPE(result) == AOP_CRY){
7515 pic16_emitcode("rlc","a");
7516 pic16_outBitC(result);
7519 pic16_emitcode("rl","a");
7520 pic16_emitcode("anl","a,#0x01");
7521 pic16_outAcc(result);
7525 pic16_freeAsmop(left,NULL,ic,TRUE);
7526 pic16_freeAsmop(result,NULL,ic,TRUE);
7530 /*-----------------------------------------------------------------*/
7531 /* AccRol - rotate left accumulator by known count */
7532 /*-----------------------------------------------------------------*/
7533 static void AccRol (int shCount)
7535 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7536 shCount &= 0x0007; // shCount : 0..7
7541 pic16_emitcode("rl","a");
7544 pic16_emitcode("rl","a");
7545 pic16_emitcode("rl","a");
7548 pic16_emitcode("swap","a");
7549 pic16_emitcode("rr","a");
7552 pic16_emitcode("swap","a");
7555 pic16_emitcode("swap","a");
7556 pic16_emitcode("rl","a");
7559 pic16_emitcode("rr","a");
7560 pic16_emitcode("rr","a");
7563 pic16_emitcode("rr","a");
7569 /*-----------------------------------------------------------------*/
7570 /* AccLsh - left shift accumulator by known count */
7571 /*-----------------------------------------------------------------*/
7572 static void AccLsh (int shCount)
7574 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7580 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7583 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7584 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7587 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7588 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7591 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7594 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7595 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7598 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7599 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7602 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7606 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7609 /*-----------------------------------------------------------------*/
7610 /* AccRsh - right shift accumulator by known count */
7611 /*-----------------------------------------------------------------*/
7612 static void AccRsh (int shCount, int andmask)
7614 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7619 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7622 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7623 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7626 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7627 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7630 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7633 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7634 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7637 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7638 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7641 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7646 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
7648 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
7652 /*-----------------------------------------------------------------*/
7653 /* AccSRsh - signed right shift accumulator by known count */
7654 /*-----------------------------------------------------------------*/
7655 static void AccSRsh (int shCount)
7658 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7661 pic16_emitcode("mov","c,acc.7");
7662 pic16_emitcode("rrc","a");
7663 } else if(shCount == 2){
7664 pic16_emitcode("mov","c,acc.7");
7665 pic16_emitcode("rrc","a");
7666 pic16_emitcode("mov","c,acc.7");
7667 pic16_emitcode("rrc","a");
7669 tlbl = newiTempLabel(NULL);
7670 /* rotate right accumulator */
7671 AccRol(8 - shCount);
7672 /* and kill the higher order bits */
7673 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
7674 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
7675 pic16_emitcode("orl","a,#0x%02x",
7676 (unsigned char)~SRMask[shCount]);
7677 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7682 /*-----------------------------------------------------------------*/
7683 /* shiftR1Left2Result - shift right one byte from left to result */
7684 /*-----------------------------------------------------------------*/
7685 static void shiftR1Left2ResultSigned (operand *left, int offl,
7686 operand *result, int offr,
7691 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7693 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7697 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7699 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7701 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7702 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7708 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7710 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7712 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7713 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7715 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7716 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7722 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7724 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7725 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7728 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7729 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7730 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7732 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
7733 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
7735 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7739 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7740 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7741 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
7742 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
7743 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7747 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7749 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7750 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7752 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7753 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
7754 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER));
7755 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
7756 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7761 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7762 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
7763 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
7764 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
7765 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
7766 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7768 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7769 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
7770 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7771 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER));
7772 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
7778 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7779 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
7780 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7781 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7783 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7784 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER));
7785 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7793 /*-----------------------------------------------------------------*/
7794 /* shiftR1Left2Result - shift right one byte from left to result */
7795 /*-----------------------------------------------------------------*/
7796 static void shiftR1Left2Result (operand *left, int offl,
7797 operand *result, int offr,
7798 int shCount, int sign)
7802 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7804 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7806 /* Copy the msb into the carry if signed. */
7808 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
7818 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7820 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7821 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7827 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7829 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7830 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7833 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7838 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7840 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7841 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7844 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7845 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7846 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7847 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7851 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7852 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7857 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7858 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7859 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7861 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7866 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7867 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7868 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7869 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7870 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7875 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7876 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7877 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7886 /*-----------------------------------------------------------------*/
7887 /* shiftL1Left2Result - shift left one byte from left to result */
7888 /*-----------------------------------------------------------------*/
7889 static void shiftL1Left2Result (operand *left, int offl,
7890 operand *result, int offr, int shCount)
7895 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7897 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7898 DEBUGpic16_emitcode ("; ***","same = %d",same);
7899 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7901 /* shift left accumulator */
7902 //AccLsh(shCount); // don't comment out just yet...
7903 // pic16_aopPut(AOP(result),"a",offr);
7907 /* Shift left 1 bit position */
7908 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7910 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7912 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7913 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7917 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7918 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7919 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7920 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7923 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7924 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7925 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7926 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7927 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7930 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7931 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7932 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7935 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7936 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7937 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7938 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7941 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7942 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7943 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7944 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7945 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7948 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7949 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7950 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7954 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7959 /*-----------------------------------------------------------------*/
7960 /* movLeft2Result - move byte from left to result */
7961 /*-----------------------------------------------------------------*/
7962 static void movLeft2Result (operand *left, int offl,
7963 operand *result, int offr)
7966 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7967 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7968 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7970 if (*l == '@' && (IS_AOP_PREG(result))) {
7971 pic16_emitcode("mov","a,%s",l);
7972 pic16_aopPut(AOP(result),"a",offr);
7974 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7975 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7980 /*-----------------------------------------------------------------*/
7981 /* shiftL2Left2Result - shift left two bytes from left to result */
7982 /*-----------------------------------------------------------------*/
7983 static void shiftL2Left2Result (operand *left, int offl,
7984 operand *result, int offr, int shCount)
7986 int same = pic16_sameRegs(AOP(result), AOP(left));
7989 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7991 if (same && (offl != offr)) { // shift bytes
7994 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7995 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7997 } else { // just treat as different later on
8010 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
8011 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
8012 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8016 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8017 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8023 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
8024 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
8025 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8026 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8027 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
8028 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8029 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8031 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8032 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8036 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8037 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8038 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8039 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8040 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8041 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8042 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8043 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8044 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8045 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8048 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8049 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
8050 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8051 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8052 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8062 /* note, use a mov/add for the shift since the mov has a
8063 chance of getting optimized out */
8064 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
8065 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8066 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8067 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8068 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8072 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8073 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8079 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8080 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
8081 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8082 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8083 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8084 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
8085 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
8086 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8090 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8091 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8095 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8096 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8097 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
8098 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8100 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8101 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8102 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
8103 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
8104 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8105 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
8106 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
8107 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8110 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8111 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8112 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8113 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
8114 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8119 /*-----------------------------------------------------------------*/
8120 /* shiftR2Left2Result - shift right two bytes from left to result */
8121 /*-----------------------------------------------------------------*/
8122 static void shiftR2Left2Result (operand *left, int offl,
8123 operand *result, int offr,
8124 int shCount, int sign)
8126 int same = pic16_sameRegs(AOP(result), AOP(left));
8128 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
8130 if (same && (offl != offr)) { // shift right bytes
8133 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
8134 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
8136 } else { // just treat as different later on
8148 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8153 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8154 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8156 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
8157 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8158 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
8159 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8164 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
8167 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
8168 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
8175 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
8176 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
8177 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
8179 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
8180 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
8181 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8182 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8184 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
8185 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
8186 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
8188 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
8189 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
8190 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8191 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
8192 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
8196 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
8197 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
8201 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
8202 pic16_emitpcode(POC_BTFSC,
8203 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
8204 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
8212 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8213 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8215 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8216 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8217 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
8218 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8220 pic16_emitpcode(POC_BTFSC,
8221 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0, PO_GPR_REGISTER));
8222 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8224 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8225 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
8226 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
8227 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8229 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8230 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8231 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8232 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8233 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8234 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8235 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
8236 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
8238 pic16_emitpcode(POC_BTFSC,
8239 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8240 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
8242 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
8243 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
8250 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
8251 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
8252 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
8253 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
8256 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
8258 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
8263 /*-----------------------------------------------------------------*/
8264 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
8265 /*-----------------------------------------------------------------*/
8266 static void shiftLLeftOrResult (operand *left, int offl,
8267 operand *result, int offr, int shCount)
8269 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8271 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8272 /* shift left accumulator */
8274 /* or with result */
8275 /* back to result */
8276 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8279 /*-----------------------------------------------------------------*/
8280 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
8281 /*-----------------------------------------------------------------*/
8282 static void shiftRLeftOrResult (operand *left, int offl,
8283 operand *result, int offr, int shCount)
8285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8287 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
8288 /* shift right accumulator */
8290 /* or with result */
8291 /* back to result */
8292 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
8295 /*-----------------------------------------------------------------*/
8296 /* genlshOne - left shift a one byte quantity by known count */
8297 /*-----------------------------------------------------------------*/
8298 static void genlshOne (operand *result, operand *left, int shCount)
8300 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8301 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8304 /*-----------------------------------------------------------------*/
8305 /* genlshTwo - left shift two bytes by known amount != 0 */
8306 /*-----------------------------------------------------------------*/
8307 static void genlshTwo (operand *result,operand *left, int shCount)
8311 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8312 size = pic16_getDataSize(result);
8314 /* if shCount >= 8 */
8320 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8322 movLeft2Result(left, LSB, result, MSB16);
8324 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8327 /* 1 <= shCount <= 7 */
8330 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8332 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8336 /*-----------------------------------------------------------------*/
8337 /* shiftLLong - shift left one long from left to result */
8338 /* offr = LSB or MSB16 */
8339 /*-----------------------------------------------------------------*/
8340 static void shiftLLong (operand *left, operand *result, int offr )
8342 int size = AOP_SIZE(result);
8343 int same = pic16_sameRegs(AOP(left),AOP(result));
8346 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8348 if (same && (offr == MSB16)) { //shift one byte
8349 for(i=size-1;i>=MSB16;i--) {
8350 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8351 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8354 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8357 if (size >= LSB+offr ){
8359 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8361 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8362 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8366 if(size >= MSB16+offr){
8368 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8370 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8371 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8375 if(size >= MSB24+offr){
8377 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8379 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8380 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8384 if(size > MSB32+offr){
8386 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8388 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8389 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8393 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8397 /*-----------------------------------------------------------------*/
8398 /* genlshFour - shift four byte by a known amount != 0 */
8399 /*-----------------------------------------------------------------*/
8400 static void genlshFour (operand *result, operand *left, int shCount)
8404 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8405 size = AOP_SIZE(result);
8407 /* if shifting more that 3 bytes */
8408 if (shCount >= 24 ) {
8411 /* lowest order of left goes to the highest
8412 order of the destination */
8413 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8415 movLeft2Result(left, LSB, result, MSB32);
8417 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8418 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8419 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8424 /* more than two bytes */
8425 else if ( shCount >= 16 ) {
8426 /* lower order two bytes goes to higher order two bytes */
8428 /* if some more remaining */
8430 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8432 movLeft2Result(left, MSB16, result, MSB32);
8433 movLeft2Result(left, LSB, result, MSB24);
8435 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8436 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8440 /* if more than 1 byte */
8441 else if ( shCount >= 8 ) {
8442 /* lower order three bytes goes to higher order three bytes */
8446 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8448 movLeft2Result(left, LSB, result, MSB16);
8450 else{ /* size = 4 */
8452 movLeft2Result(left, MSB24, result, MSB32);
8453 movLeft2Result(left, MSB16, result, MSB24);
8454 movLeft2Result(left, LSB, result, MSB16);
8455 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8457 else if(shCount == 1)
8458 shiftLLong(left, result, MSB16);
8460 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8461 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8462 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8463 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8468 /* 1 <= shCount <= 7 */
8469 else if(shCount <= 3)
8471 shiftLLong(left, result, LSB);
8472 while(--shCount >= 1)
8473 shiftLLong(result, result, LSB);
8475 /* 3 <= shCount <= 7, optimize */
8477 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8478 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8479 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8483 /*-----------------------------------------------------------------*/
8484 /* genLeftShiftLiteral - left shifting by known count */
8485 /*-----------------------------------------------------------------*/
8486 static void genLeftShiftLiteral (operand *left,
8491 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8494 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8495 pic16_freeAsmop(right,NULL,ic,TRUE);
8497 pic16_aopOp(left,ic,FALSE);
8498 pic16_aopOp(result,ic,FALSE);
8500 size = getSize(operandType(result));
8503 pic16_emitcode("; shift left ","result %d, left %d",size,
8507 /* I suppose that the left size >= result size */
8510 movLeft2Result(left, size, result, size);
8514 else if(shCount >= (size * 8))
8516 pic16_aopPut(AOP(result),zero,size);
8520 genlshOne (result,left,shCount);
8525 genlshTwo (result,left,shCount);
8529 genlshFour (result,left,shCount);
8533 pic16_freeAsmop(left,NULL,ic,TRUE);
8534 pic16_freeAsmop(result,NULL,ic,TRUE);
8537 /*-----------------------------------------------------------------*
8538 * genMultiAsm - repeat assembly instruction for size of register.
8539 * if endian == 1, then the high byte (i.e base address + size of
8540 * register) is used first else the low byte is used first;
8541 *-----------------------------------------------------------------*/
8542 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8560 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8565 /*-----------------------------------------------------------------*/
8566 /* genLeftShift - generates code for left shifting */
8567 /*-----------------------------------------------------------------*/
8568 static void genLeftShift (iCode *ic)
8570 operand *left,*right, *result;
8573 symbol *tlbl , *tlbl1;
8576 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8578 right = IC_RIGHT(ic);
8580 result = IC_RESULT(ic);
8582 pic16_aopOp(right,ic,FALSE);
8584 /* if the shift count is known then do it
8585 as efficiently as possible */
8586 if (AOP_TYPE(right) == AOP_LIT) {
8587 genLeftShiftLiteral (left,right,result,ic);
8591 /* shift count is unknown then we have to form
8592 * a loop. Get the loop count in WREG : Note: we take
8593 * only the lower order byte since shifting
8594 * more than 32 bits make no sense anyway, ( the
8595 * largest size of an object can be only 32 bits ) */
8597 pic16_aopOp(left,ic,FALSE);
8598 pic16_aopOp(result,ic,FALSE);
8600 /* now move the left to the result if they are not the
8601 * same, and if size > 1,
8602 * and if right is not same to result (!!!) -- VR */
8603 if (!pic16_sameRegs(AOP(left),AOP(result))
8604 && (AOP_SIZE(result) > 1)) {
8606 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8608 size = AOP_SIZE(result);
8613 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8614 if (*l == '@' && (IS_AOP_PREG(result))) {
8616 pic16_emitcode("mov","a,%s",l);
8617 pic16_aopPut(AOP(result),"a",offset);
8621 /* we don't know if left is a literal or a register, take care -- VR */
8622 mov2f(AOP(result), AOP(left), offset);
8628 size = AOP_SIZE(result);
8630 /* if it is only one byte then */
8632 if(optimized_for_speed) {
8633 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8634 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8635 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
8636 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8637 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8638 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8639 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8640 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8641 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8642 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8643 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
8644 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8647 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8649 tlbl = newiTempLabel(NULL);
8652 /* this is already done, why change it? */
8653 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8654 mov2f(AOP(result), AOP(left), 0);
8658 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8659 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8660 pic16_emitpLabel(tlbl->key);
8661 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8662 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8664 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8669 if (pic16_sameRegs(AOP(left),AOP(result))) {
8671 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8673 tlbl = newiTempLabel(NULL);
8674 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8675 genMultiAsm(POC_RRCF, result, size,1);
8676 pic16_emitpLabel(tlbl->key);
8677 genMultiAsm(POC_RLCF, result, size,0);
8678 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8680 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8684 //tlbl = newiTempLabel(NULL);
8686 //tlbl1 = newiTempLabel(NULL);
8688 //reAdjustPreg(AOP(result));
8690 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8691 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8692 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8694 //pic16_emitcode("add","a,acc");
8695 //pic16_aopPut(AOP(result),"a",offset++);
8697 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8699 // pic16_emitcode("rlc","a");
8700 // pic16_aopPut(AOP(result),"a",offset++);
8702 //reAdjustPreg(AOP(result));
8704 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8705 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8708 tlbl = newiTempLabel(NULL);
8709 tlbl1= newiTempLabel(NULL);
8711 size = AOP_SIZE(result);
8714 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8716 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8718 /* offset should be 0, 1 or 3 */
8720 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8722 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8724 pic16_emitpcode(POC_MOVWF, pctemp);
8727 pic16_emitpLabel(tlbl->key);
8730 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8732 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8734 pic16_emitpcode(POC_DECFSZ, pctemp);
8735 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8736 pic16_emitpLabel(tlbl1->key);
8738 pic16_popReleaseTempReg(pctemp);
8742 pic16_freeAsmop (right,NULL,ic,TRUE);
8743 pic16_freeAsmop(left,NULL,ic,TRUE);
8744 pic16_freeAsmop(result,NULL,ic,TRUE);
8750 #error old code (left here for reference)
8751 /*-----------------------------------------------------------------*/
8752 /* genLeftShift - generates code for left shifting */
8753 /*-----------------------------------------------------------------*/
8754 static void genLeftShift (iCode *ic)
8756 operand *left,*right, *result;
8759 symbol *tlbl , *tlbl1;
8762 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8764 right = IC_RIGHT(ic);
8766 result = IC_RESULT(ic);
8768 pic16_aopOp(right,ic,FALSE);
8770 /* if the shift count is known then do it
8771 as efficiently as possible */
8772 if (AOP_TYPE(right) == AOP_LIT) {
8773 genLeftShiftLiteral (left,right,result,ic);
8777 /* shift count is unknown then we have to form
8778 a loop get the loop count in B : Note: we take
8779 only the lower order byte since shifting
8780 more that 32 bits make no sense anyway, ( the
8781 largest size of an object can be only 32 bits ) */
8784 pic16_aopOp(left,ic,FALSE);
8785 pic16_aopOp(result,ic,FALSE);
8787 /* now move the left to the result if they are not the
8789 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8790 AOP_SIZE(result) > 1) {
8792 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8794 size = AOP_SIZE(result);
8797 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8798 if (*l == '@' && (IS_AOP_PREG(result))) {
8800 pic16_emitcode("mov","a,%s",l);
8801 pic16_aopPut(AOP(result),"a",offset);
8804 /* we don't know if left is a literal or a register, take care -- VR */
8805 mov2f(AOP(result), AOP(left), offset);
8811 size = AOP_SIZE(result);
8813 /* if it is only one byte then */
8815 if(optimized_for_speed) {
8816 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8817 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8818 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER));
8819 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8820 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8821 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
8822 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8823 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8824 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8825 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8826 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER));
8827 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8830 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8832 tlbl = newiTempLabel(NULL);
8833 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8834 mov2f(AOP(result), AOP(left), 0);
8836 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8837 // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8840 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8841 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8842 pic16_emitpLabel(tlbl->key);
8843 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8844 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8846 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8851 if (pic16_sameRegs(AOP(left),AOP(result))) {
8853 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8855 tlbl = newiTempLabel(NULL);
8856 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8857 genMultiAsm(POC_RRCF, result, size,1);
8858 pic16_emitpLabel(tlbl->key);
8859 genMultiAsm(POC_RLCF, result, size,0);
8860 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8862 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8866 //tlbl = newiTempLabel(NULL);
8868 //tlbl1 = newiTempLabel(NULL);
8870 //reAdjustPreg(AOP(result));
8872 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8873 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8874 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8876 //pic16_emitcode("add","a,acc");
8877 //pic16_aopPut(AOP(result),"a",offset++);
8879 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8881 // pic16_emitcode("rlc","a");
8882 // pic16_aopPut(AOP(result),"a",offset++);
8884 //reAdjustPreg(AOP(result));
8886 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8887 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8890 tlbl = newiTempLabel(NULL);
8891 tlbl1= newiTempLabel(NULL);
8893 size = AOP_SIZE(result);
8896 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8898 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8900 /* offset should be 0, 1 or 3 */
8902 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8904 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8906 pic16_emitpcode(POC_MOVWF, pctemp);
8909 pic16_emitpLabel(tlbl->key);
8912 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8914 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8916 pic16_emitpcode(POC_DECFSZ, pctemp);
8917 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8918 pic16_emitpLabel(tlbl1->key);
8920 pic16_popReleaseTempReg(pctemp);
8924 pic16_freeAsmop (right,NULL,ic,TRUE);
8925 pic16_freeAsmop(left,NULL,ic,TRUE);
8926 pic16_freeAsmop(result,NULL,ic,TRUE);
8930 /*-----------------------------------------------------------------*/
8931 /* genrshOne - right shift a one byte quantity by known count */
8932 /*-----------------------------------------------------------------*/
8933 static void genrshOne (operand *result, operand *left,
8934 int shCount, int sign)
8936 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8937 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
8940 /*-----------------------------------------------------------------*/
8941 /* genrshTwo - right shift two bytes by known amount != 0 */
8942 /*-----------------------------------------------------------------*/
8943 static void genrshTwo (operand *result,operand *left,
8944 int shCount, int sign)
8946 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8947 /* if shCount >= 8 */
8951 shiftR1Left2Result(left, MSB16, result, LSB,
8954 movLeft2Result(left, MSB16, result, LSB);
8956 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8959 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER));
8960 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
8964 /* 1 <= shCount <= 7 */
8966 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
8969 /*-----------------------------------------------------------------*/
8970 /* shiftRLong - shift right one long from left to result */
8971 /* offl = LSB or MSB16 */
8972 /*-----------------------------------------------------------------*/
8973 static void shiftRLong (operand *left, int offl,
8974 operand *result, int sign)
8976 int size = AOP_SIZE(result);
8977 int same = pic16_sameRegs(AOP(left),AOP(result));
8979 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
8981 if (same && (offl == MSB16)) { //shift one byte right
8982 for(i=MSB16;i<size;i++) {
8983 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
8984 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
8989 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
8995 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
8997 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
8998 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
9002 /* add sign of "a" */
9003 pic16_addSign(result, MSB32, sign);
9007 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
9009 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
9010 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
9014 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
9016 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
9017 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
9021 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
9024 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
9025 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
9030 /*-----------------------------------------------------------------*/
9031 /* genrshFour - shift four byte by a known amount != 0 */
9032 /*-----------------------------------------------------------------*/
9033 static void genrshFour (operand *result, operand *left,
9034 int shCount, int sign)
9036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9037 /* if shifting more that 3 bytes */
9038 if(shCount >= 24 ) {
9041 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
9043 movLeft2Result(left, MSB32, result, LSB);
9045 pic16_addSign(result, MSB16, sign);
9047 else if(shCount >= 16){
9050 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
9052 movLeft2Result(left, MSB24, result, LSB);
9053 movLeft2Result(left, MSB32, result, MSB16);
9055 pic16_addSign(result, MSB24, sign);
9057 else if(shCount >= 8){
9060 shiftRLong(left, MSB16, result, sign);
9061 else if(shCount == 0){
9062 movLeft2Result(left, MSB16, result, LSB);
9063 movLeft2Result(left, MSB24, result, MSB16);
9064 movLeft2Result(left, MSB32, result, MSB24);
9065 pic16_addSign(result, MSB32, sign);
9067 else{ //shcount >= 2
9068 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
9069 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
9070 /* the last shift is signed */
9071 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
9072 pic16_addSign(result, MSB32, sign);
9075 else{ /* 1 <= shCount <= 7 */
9077 shiftRLong(left, LSB, result, sign);
9079 shiftRLong(result, LSB, result, sign);
9082 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
9083 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
9084 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
9089 /*-----------------------------------------------------------------*/
9090 /* genRightShiftLiteral - right shifting by known count */
9091 /*-----------------------------------------------------------------*/
9092 static void genRightShiftLiteral (operand *left,
9098 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
9101 pic16_freeAsmop(right,NULL,ic,TRUE);
9103 pic16_aopOp(left,ic,FALSE);
9104 pic16_aopOp(result,ic,FALSE);
9106 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
9109 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
9113 lsize = pic16_getDataSize(left);
9114 res_size = pic16_getDataSize(result);
9115 /* test the LEFT size !!! */
9117 /* I suppose that the left size >= result size */
9120 movLeft2Result(left, lsize, result, res_size);
9123 else if(shCount >= (lsize * 8)){
9126 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
9128 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9129 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
9134 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
9135 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
9136 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9138 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
9143 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
9150 genrshOne (result,left,shCount,sign);
9154 genrshTwo (result,left,shCount,sign);
9158 genrshFour (result,left,shCount,sign);
9166 pic16_freeAsmop(left,NULL,ic,TRUE);
9167 pic16_freeAsmop(result,NULL,ic,TRUE);
9170 /*-----------------------------------------------------------------*/
9171 /* genSignedRightShift - right shift of signed number */
9172 /*-----------------------------------------------------------------*/
9173 static void genSignedRightShift (iCode *ic)
9175 operand *right, *left, *result;
9178 symbol *tlbl, *tlbl1 ;
9181 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
9183 /* we do it the hard way put the shift count in b
9184 and loop thru preserving the sign */
9185 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9187 right = IC_RIGHT(ic);
9189 result = IC_RESULT(ic);
9191 pic16_aopOp(right,ic,FALSE);
9192 pic16_aopOp(left,ic,FALSE);
9193 pic16_aopOp(result,ic,FALSE);
9196 if ( AOP_TYPE(right) == AOP_LIT) {
9197 genRightShiftLiteral (left,right,result,ic,1);
9200 /* shift count is unknown then we have to form
9201 a loop get the loop count in B : Note: we take
9202 only the lower order byte since shifting
9203 more that 32 bits make no sense anyway, ( the
9204 largest size of an object can be only 32 bits ) */
9206 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9207 //pic16_emitcode("inc","b");
9208 //pic16_freeAsmop (right,NULL,ic,TRUE);
9209 //pic16_aopOp(left,ic,FALSE);
9210 //pic16_aopOp(result,ic,FALSE);
9212 /* now move the left to the result if they are not the
9214 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9215 AOP_SIZE(result) > 1) {
9217 size = AOP_SIZE(result);
9221 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9222 if (*l == '@' && IS_AOP_PREG(result)) {
9224 pic16_emitcode("mov","a,%s",l);
9225 pic16_aopPut(AOP(result),"a",offset);
9227 pic16_aopPut(AOP(result),l,offset);
9229 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
9230 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9236 /* mov the highest order bit to OVR */
9237 tlbl = newiTempLabel(NULL);
9238 tlbl1= newiTempLabel(NULL);
9240 size = AOP_SIZE(result);
9243 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
9245 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9247 /* offset should be 0, 1 or 3 */
9248 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
9250 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
9252 pic16_emitpcode(POC_MOVWF, pctemp);
9255 pic16_emitpLabel(tlbl->key);
9257 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
9258 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
9261 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
9264 pic16_emitpcode(POC_DECFSZ, pctemp);
9265 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9266 pic16_emitpLabel(tlbl1->key);
9268 pic16_popReleaseTempReg(pctemp);
9270 size = AOP_SIZE(result);
9272 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
9273 pic16_emitcode("rlc","a");
9274 pic16_emitcode("mov","ov,c");
9275 /* if it is only one byte then */
9277 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9279 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9280 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9281 pic16_emitcode("mov","c,ov");
9282 pic16_emitcode("rrc","a");
9283 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9284 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9285 pic16_aopPut(AOP(result),"a",0);
9289 reAdjustPreg(AOP(result));
9290 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9291 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9292 pic16_emitcode("mov","c,ov");
9294 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9296 pic16_emitcode("rrc","a");
9297 pic16_aopPut(AOP(result),"a",offset--);
9299 reAdjustPreg(AOP(result));
9300 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9301 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9306 pic16_freeAsmop(left,NULL,ic,TRUE);
9307 pic16_freeAsmop(result,NULL,ic,TRUE);
9308 pic16_freeAsmop(right,NULL,ic,TRUE);
9311 /*-----------------------------------------------------------------*/
9312 /* genRightShift - generate code for right shifting */
9313 /*-----------------------------------------------------------------*/
9314 static void genRightShift (iCode *ic)
9316 operand *right, *left, *result;
9320 symbol *tlbl, *tlbl1 ;
9322 /* if signed then we do it the hard way preserve the
9323 sign bit moving it inwards */
9324 letype = getSpec(operandType(IC_LEFT(ic)));
9325 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9327 if (!SPEC_USIGN(letype)) {
9328 genSignedRightShift (ic);
9332 /* signed & unsigned types are treated the same : i.e. the
9333 signed is NOT propagated inwards : quoting from the
9334 ANSI - standard : "for E1 >> E2, is equivalent to division
9335 by 2**E2 if unsigned or if it has a non-negative value,
9336 otherwise the result is implementation defined ", MY definition
9337 is that the sign does not get propagated */
9339 right = IC_RIGHT(ic);
9341 result = IC_RESULT(ic);
9343 pic16_aopOp(right,ic,FALSE);
9345 /* if the shift count is known then do it
9346 as efficiently as possible */
9347 if (AOP_TYPE(right) == AOP_LIT) {
9348 genRightShiftLiteral (left,right,result,ic, 0);
9352 /* shift count is unknown then we have to form
9353 a loop get the loop count in B : Note: we take
9354 only the lower order byte since shifting
9355 more that 32 bits make no sense anyway, ( the
9356 largest size of an object can be only 32 bits ) */
9358 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
9359 pic16_emitcode("inc","b");
9360 pic16_aopOp(left,ic,FALSE);
9361 pic16_aopOp(result,ic,FALSE);
9363 /* now move the left to the result if they are not the
9365 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
9366 AOP_SIZE(result) > 1) {
9368 size = AOP_SIZE(result);
9371 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
9372 if (*l == '@' && IS_AOP_PREG(result)) {
9374 pic16_emitcode("mov","a,%s",l);
9375 pic16_aopPut(AOP(result),"a",offset);
9377 pic16_aopPut(AOP(result),l,offset);
9382 tlbl = newiTempLabel(NULL);
9383 tlbl1= newiTempLabel(NULL);
9384 size = AOP_SIZE(result);
9387 /* if it is only one byte then */
9390 tlbl = newiTempLabel(NULL);
9391 if (!pic16_sameRegs(AOP(left),AOP(result))) {
9392 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
9393 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9396 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
9397 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
9398 pic16_emitpLabel(tlbl->key);
9399 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
9400 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
9402 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
9407 reAdjustPreg(AOP(result));
9408 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
9409 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
9412 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
9414 pic16_emitcode("rrc","a");
9415 pic16_aopPut(AOP(result),"a",offset--);
9417 reAdjustPreg(AOP(result));
9419 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
9420 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
9423 pic16_freeAsmop(left,NULL,ic,TRUE);
9424 pic16_freeAsmop (right,NULL,ic,TRUE);
9425 pic16_freeAsmop(result,NULL,ic,TRUE);
9429 void pic16_loadFSR0(operand *op)
9431 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9434 /*-----------------------------------------------------------------*/
9435 /* genUnpackBits - generates code for unpacking bits */
9436 /*-----------------------------------------------------------------*/
9437 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
9444 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9445 etype = getSpec(operandType(result));
9447 /* the following call to pic16_loadFSR0 is temporary until
9448 * optimization to handle single bit assignments is added
9449 * to the function. Until then use the old safe way! -- VR */
9450 pic16_loadFSR0( left );
9452 /* read the first byte */
9459 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9462 pic16_emitcode("clr","a");
9463 pic16_emitcode("movc","a","@a+dptr");
9468 /* if we have bitdisplacement then it fits */
9469 /* into this byte completely or if length is */
9470 /* less than a byte */
9471 if ((shCnt = SPEC_BSTR(etype)) ||
9472 (SPEC_BLEN(etype) <= 8)) {
9474 /* shift right acc */
9477 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9478 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
9480 /* VR -- normally I would use the following, but since we use the hack,
9481 * to avoid the masking from AccRsh, why not mask it right now? */
9484 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
9487 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9493 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9494 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9497 /* bit field did not fit in a byte */
9498 rlen = SPEC_BLEN(etype) - 8;
9499 pic16_aopPut(AOP(result),"a",offset++);
9506 pic16_emitcode("inc","%s",rname);
9507 pic16_emitcode("mov","a,@%s",rname);
9511 pic16_emitcode("inc","%s",rname);
9512 pic16_emitcode("movx","a,@%s",rname);
9516 pic16_emitcode("inc","dptr");
9517 pic16_emitcode("movx","a,@dptr");
9521 pic16_emitcode("clr","a");
9522 pic16_emitcode("inc","dptr");
9523 pic16_emitcode("movc","a","@a+dptr");
9527 pic16_emitcode("inc","dptr");
9528 pic16_emitcode("lcall","__gptrget");
9533 /* if we are done */
9537 pic16_aopPut(AOP(result),"a",offset++);
9542 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9543 pic16_aopPut(AOP(result),"a",offset);
9550 static void genDataPointerGet(operand *left,
9554 int size, offset = 0, leoffset=0 ;
9556 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9557 pic16_aopOp(result, ic, FALSE);
9559 size = AOP_SIZE(result);
9560 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9564 /* The following tests may save a redudant movff instruction when
9565 * accessing unions */
9567 /* if they are the same */
9568 if (operandsEqu (left, result)) {
9569 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9575 /* if they are the same registers */
9576 if (pic16_sameRegs(AOP(left),AOP(result))) {
9577 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9583 if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
9584 pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
9585 DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
9592 if ( AOP_TYPE(left) == AOP_PCODE) {
9593 fprintf(stderr,"genDataPointerGet %s, %d\n",
9594 AOP(left)->aopu.pcop->name,
9595 (AOP(left)->aopu.pcop->type == PO_DIR)?
9596 PCOR(AOP(left)->aopu.pcop)->instance:
9597 PCOI(AOP(left)->aopu.pcop)->offset);
9601 if(AOP(left)->aopu.pcop->type == PO_DIR)
9602 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
9604 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9607 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
9609 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
9610 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
9611 mov2w(AOP(left), offset); // patch 8
9612 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
9614 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
9615 pic16_popGet(AOP(left), offset), //patch 8
9616 pic16_popGet(AOP(result), offset)));
9624 pic16_freeAsmop(result,NULL,ic,TRUE);
9629 /*-----------------------------------------------------------------*/
9630 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
9631 /*-----------------------------------------------------------------*/
9632 static void genNearPointerGet (operand *left,
9637 //regs *preg = NULL ;
9638 sym_link *rtype, *retype;
9639 sym_link *ltype = operandType(left);
9641 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9642 rtype = operandType(result);
9643 retype= getSpec(rtype);
9645 pic16_aopOp(left,ic,FALSE);
9647 // pic16_DumpOp("(left)",left);
9648 // pic16_DumpOp("(result)",result);
9650 /* if left is rematerialisable and
9651 * result is not bit variable type and
9652 * the left is pointer to data space i.e
9653 * lower 128 bytes of space */
9654 if (AOP_TYPE(left) == AOP_PCODE
9655 && !IS_BITFIELD(retype)
9656 && DCL_TYPE(ltype) == POINTER) {
9658 genDataPointerGet (left,result,ic);
9659 pic16_freeAsmop(left, NULL, ic, TRUE);
9663 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9665 /* if the value is already in a pointer register
9666 * then don't need anything more */
9667 if (!AOP_INPREG(AOP(left))) {
9668 /* otherwise get a free pointer register */
9669 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9671 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
9672 if( (AOP_TYPE(left) == AOP_PCODE)
9673 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9674 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
9676 if(!IS_BITFIELD(retype))
9677 pic16_loadFSR0( left ); // patch 10
9679 // set up FSR0 with address from left
9680 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9681 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9685 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9687 pic16_aopOp (result,ic,FALSE);
9689 /* if bitfield then unpack the bits */
9690 if (IS_BITFIELD(retype))
9691 genUnpackBits (result, left, NULL, POINTER);
9693 /* we have can just get the values */
9694 int size = AOP_SIZE(result);
9697 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9700 /* fsr0 is loaded already -- VR */
9701 // pic16_loadFSR0( left );
9703 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
9704 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9708 pic16_emitpcode(POC_MOVFF,
9709 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
9710 pic16_popGet(AOP(result), offset++)));
9712 pic16_emitpcode(POC_MOVFF,
9713 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
9714 pic16_popGet(AOP(result), offset++)));
9718 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
9719 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
9721 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9725 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
9727 pic16_emitcode("mov","a,@%s",rname);
9728 pic16_aopPut(AOP(result),"a",offset);
9730 sprintf(buffer,"@%s",rname);
9731 pic16_aopPut(AOP(result),buffer,offset);
9735 pic16_emitcode("inc","%s",rname);
9740 /* now some housekeeping stuff */
9742 /* we had to allocate for this iCode */
9743 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9744 pic16_freeAsmop(NULL,aop,ic,TRUE);
9746 /* we did not allocate which means left
9747 already in a pointer register, then
9748 if size > 0 && this could be used again
9749 we have to point it back to where it
9751 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9752 if (AOP_SIZE(result) > 1 &&
9753 !OP_SYMBOL(left)->remat &&
9754 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9756 // int size = AOP_SIZE(result) - 1;
9758 // pic16_emitcode("dec","%s",rname);
9763 pic16_freeAsmop(left,NULL,ic,TRUE);
9764 pic16_freeAsmop(result,NULL,ic,TRUE);
9768 /*-----------------------------------------------------------------*/
9769 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
9770 /*-----------------------------------------------------------------*/
9771 static void genPagedPointerGet (operand *left,
9778 sym_link *rtype, *retype;
9780 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9782 rtype = operandType(result);
9783 retype= getSpec(rtype);
9785 pic16_aopOp(left,ic,FALSE);
9787 /* if the value is already in a pointer register
9788 then don't need anything more */
9789 if (!AOP_INPREG(AOP(left))) {
9790 /* otherwise get a free pointer register */
9792 preg = getFreePtr(ic,&aop,FALSE);
9793 pic16_emitcode("mov","%s,%s",
9795 pic16_aopGet(AOP(left),0,FALSE,TRUE));
9796 rname = preg->name ;
9798 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9800 pic16_freeAsmop(left,NULL,ic,TRUE);
9801 pic16_aopOp (result,ic,FALSE);
9803 /* if bitfield then unpack the bits */
9804 if (IS_BITFIELD(retype))
9805 genUnpackBits (result,left,rname,PPOINTER);
9807 /* we have can just get the values */
9808 int size = AOP_SIZE(result);
9813 pic16_emitcode("movx","a,@%s",rname);
9814 pic16_aopPut(AOP(result),"a",offset);
9819 pic16_emitcode("inc","%s",rname);
9823 /* now some housekeeping stuff */
9825 /* we had to allocate for this iCode */
9826 pic16_freeAsmop(NULL,aop,ic,TRUE);
9828 /* we did not allocate which means left
9829 already in a pointer register, then
9830 if size > 0 && this could be used again
9831 we have to point it back to where it
9833 if (AOP_SIZE(result) > 1 &&
9834 !OP_SYMBOL(left)->remat &&
9835 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9837 int size = AOP_SIZE(result) - 1;
9839 pic16_emitcode("dec","%s",rname);
9844 pic16_freeAsmop(result,NULL,ic,TRUE);
9849 /*-----------------------------------------------------------------*/
9850 /* genFarPointerGet - gget value from far space */
9851 /*-----------------------------------------------------------------*/
9852 static void genFarPointerGet (operand *left,
9853 operand *result, iCode *ic)
9856 sym_link *retype = getSpec(operandType(result));
9858 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9860 pic16_aopOp(left,ic,FALSE);
9862 /* if the operand is already in dptr
9863 then we do nothing else we move the value to dptr */
9864 if (AOP_TYPE(left) != AOP_STR) {
9865 /* if this is remateriazable */
9866 if (AOP_TYPE(left) == AOP_IMMD)
9867 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9868 else { /* we need to get it byte by byte */
9869 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9870 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9871 if (options.model == MODEL_FLAT24)
9873 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9877 /* so dptr know contains the address */
9878 pic16_freeAsmop(left,NULL,ic,TRUE);
9879 pic16_aopOp(result,ic,FALSE);
9881 /* if bit then unpack */
9882 if (IS_BITFIELD(retype))
9883 genUnpackBits(result,left,"dptr",FPOINTER);
9885 size = AOP_SIZE(result);
9889 pic16_emitcode("movx","a,@dptr");
9890 pic16_aopPut(AOP(result),"a",offset++);
9892 pic16_emitcode("inc","dptr");
9896 pic16_freeAsmop(result,NULL,ic,TRUE);
9899 /*-----------------------------------------------------------------*/
9900 /* genCodePointerGet - get value from code space */
9901 /*-----------------------------------------------------------------*/
9902 static void genCodePointerGet (operand *left,
9903 operand *result, iCode *ic)
9906 sym_link *retype = getSpec(operandType(result));
9908 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9910 pic16_aopOp(left,ic,FALSE);
9912 /* if the operand is already in dptr
9913 then we do nothing else we move the value to dptr */
9914 if (AOP_TYPE(left) != AOP_STR) {
9915 /* if this is remateriazable */
9916 if (AOP_TYPE(left) == AOP_IMMD)
9917 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9918 else { /* we need to get it byte by byte */
9919 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9920 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9921 if (options.model == MODEL_FLAT24)
9923 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9927 /* so dptr know contains the address */
9928 pic16_freeAsmop(left,NULL,ic,TRUE);
9929 pic16_aopOp(result,ic,FALSE);
9931 /* if bit then unpack */
9932 if (IS_BITFIELD(retype))
9933 genUnpackBits(result,left,"dptr",CPOINTER);
9935 size = AOP_SIZE(result);
9939 pic16_emitcode("clr","a");
9940 pic16_emitcode("movc","a,@a+dptr");
9941 pic16_aopPut(AOP(result),"a",offset++);
9943 pic16_emitcode("inc","dptr");
9947 pic16_freeAsmop(result,NULL,ic,TRUE);
9950 /*-----------------------------------------------------------------*/
9951 /* genGenPointerGet - gget value from generic pointer space */
9952 /*-----------------------------------------------------------------*/
9953 static void genGenPointerGet (operand *left,
9954 operand *result, iCode *ic)
9956 int size, offset, lit;
9957 sym_link *retype = getSpec(operandType(result));
9959 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9960 pic16_aopOp(left,ic,FALSE);
9961 pic16_aopOp(result,ic,FALSE);
9962 size = AOP_SIZE(result);
9964 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9966 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
9968 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
9969 // load FSR0 from immediate
9970 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9972 // pic16_loadFSR0( left );
9977 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9979 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9986 else { /* we need to get it byte by byte */
9987 // set up FSR0 with address from left
9988 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9989 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9995 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9997 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
10004 /* if bit then unpack */
10005 if (IS_BITFIELD(retype))
10006 genUnpackBits(result,left,"BAD",GPOINTER);
10009 pic16_freeAsmop(left,NULL,ic,TRUE);
10010 pic16_freeAsmop(result,NULL,ic,TRUE);
10014 /*-----------------------------------------------------------------*/
10015 /* genConstPointerGet - get value from const generic pointer space */
10016 /*-----------------------------------------------------------------*/
10017 static void genConstPointerGet (operand *left,
10018 operand *result, iCode *ic)
10020 //sym_link *retype = getSpec(operandType(result));
10021 // symbol *albl = newiTempLabel(NULL); // patch 15
10022 // symbol *blbl = newiTempLabel(NULL); //
10023 // PIC_OPCODE poc; // patch 15
10027 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10028 pic16_aopOp(left,ic,FALSE);
10029 pic16_aopOp(result,ic,TRUE);
10030 size = AOP_SIZE(result);
10032 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
10034 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
10036 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
10037 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
10038 pic16_emitpLabel(albl->key);
10040 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
10042 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
10043 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
10044 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
10045 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
10046 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
10048 pic16_emitpLabel(blbl->key);
10050 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
10054 // set up table pointer
10055 if( (AOP_TYPE(left) == AOP_PCODE)
10056 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
10057 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
10059 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
10060 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
10061 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
10062 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
10063 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
10064 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
10068 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
10069 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
10070 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
10076 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
10077 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
10081 pic16_freeAsmop(left,NULL,ic,TRUE);
10082 pic16_freeAsmop(result,NULL,ic,TRUE);
10087 /*-----------------------------------------------------------------*/
10088 /* genPointerGet - generate code for pointer get */
10089 /*-----------------------------------------------------------------*/
10090 static void genPointerGet (iCode *ic)
10092 operand *left, *result ;
10093 sym_link *type, *etype;
10096 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10098 left = IC_LEFT(ic);
10099 result = IC_RESULT(ic) ;
10101 /* depending on the type of pointer we need to
10102 move it to the correct pointer register */
10103 type = operandType(left);
10104 etype = getSpec(type);
10107 if (IS_PTR_CONST(type))
10109 if (IS_CODEPTR(type))
10111 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
10113 /* if left is of type of pointer then it is simple */
10114 if (IS_PTR(type) && !IS_FUNC(type->next))
10115 p_type = DCL_TYPE(type);
10117 /* we have to go by the storage class */
10118 p_type = PTR_TYPE(SPEC_OCLS(etype));
10120 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
10122 if (SPEC_OCLS(etype)->codesp ) {
10123 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
10124 //p_type = CPOINTER ;
10127 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
10128 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
10129 /*p_type = FPOINTER ;*/
10131 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
10132 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
10133 /* p_type = PPOINTER; */
10135 if (SPEC_OCLS(etype) == idata )
10136 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
10137 /* p_type = IPOINTER; */
10139 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
10140 /* p_type = POINTER ; */
10143 /* now that we have the pointer type we assign
10144 the pointer values */
10149 genNearPointerGet (left,result,ic);
10153 genPagedPointerGet(left,result,ic);
10157 genFarPointerGet (left,result,ic);
10161 genConstPointerGet (left,result,ic);
10162 //pic16_emitcodePointerGet (left,result,ic);
10167 if (IS_PTR_CONST(type))
10168 genConstPointerGet (left,result,ic);
10171 genGenPointerGet (left,result,ic);
10175 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10176 "genPointerGet: illegal pointer type");
10182 /*-----------------------------------------------------------------*/
10183 /* genPackBits - generates code for packed bit storage */
10184 /*-----------------------------------------------------------------*/
10185 static void genPackBits (sym_link *etype , operand *result,
10187 char *rname, int p_type)
10195 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10196 blen = SPEC_BLEN(etype);
10197 bstr = SPEC_BSTR(etype);
10199 if(AOP_TYPE(right) == AOP_LIT) {
10200 if((blen == 1) && (bstr < 8)) {
10202 /* it is a single bit, so use the appropriate bit instructions */
10204 DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
10206 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10207 // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10208 if((p_type == POINTER) && (result)) {
10209 /* workaround to reduce the extra lfsr instruction */
10211 pic16_emitpcode(POC_BSF,
10212 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10214 pic16_emitpcode(POC_BCF,
10215 pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
10220 pic16_emitpcode(POC_BSF,
10221 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10223 pic16_emitpcode(POC_BCF,
10224 pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
10231 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
10234 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
10236 /* if the bit lenth is less than or */
10237 /* it exactly fits a byte then */
10238 if((shCnt=SPEC_BSTR(etype))
10239 || SPEC_BLEN(etype) <= 8 ) {
10241 /* shift left acc */
10244 /* using PRODL as a temporary register here */
10245 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
10251 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
10252 // pic16_emitcode ("mov","b,a");
10253 // pic16_emitcode("mov","a,@%s",rname);
10257 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
10258 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
10259 (unsigned char)(0xff >> (8-bstr))) ));
10260 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
10261 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10268 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
10269 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
10274 if ( SPEC_BLEN(etype) <= 8 )
10277 pic16_emitcode("inc","%s",rname);
10278 rLen = SPEC_BLEN(etype) ;
10282 /* now generate for lengths greater than one byte */
10285 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
10295 pic16_emitcode("mov","@%s,a",rname);
10297 pic16_emitcode("mov","@%s,%s",rname,l);
10302 pic16_emitcode("movx","@dptr,a");
10307 DEBUGpic16_emitcode(";lcall","__gptrput");
10310 pic16_emitcode ("inc","%s",rname);
10315 /* last last was not complete */
10317 /* save the byte & read byte */
10320 pic16_emitcode ("mov","b,a");
10321 pic16_emitcode("mov","a,@%s",rname);
10325 pic16_emitcode ("mov","b,a");
10326 pic16_emitcode("movx","a,@dptr");
10330 pic16_emitcode ("push","b");
10331 pic16_emitcode ("push","acc");
10332 pic16_emitcode ("lcall","__gptrget");
10333 pic16_emitcode ("pop","b");
10337 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
10338 pic16_emitcode ("orl","a,b");
10341 if (p_type == GPOINTER)
10342 pic16_emitcode("pop","b");
10347 pic16_emitcode("mov","@%s,a",rname);
10351 pic16_emitcode("movx","@dptr,a");
10355 DEBUGpic16_emitcode(";lcall","__gptrput");
10359 /*-----------------------------------------------------------------*/
10360 /* genDataPointerSet - remat pointer to data space */
10361 /*-----------------------------------------------------------------*/
10362 static void genDataPointerSet(operand *right,
10366 int size, offset = 0, resoffset=0 ;
10368 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10369 pic16_aopOp(right,ic,FALSE);
10371 size = AOP_SIZE(right);
10373 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
10376 if ( AOP_TYPE(result) == AOP_PCODE) {
10377 fprintf(stderr,"genDataPointerSet %s, %d\n",
10378 AOP(result)->aopu.pcop->name,
10379 (AOP(result)->aopu.pcop->type == PO_DIR)?
10380 PCOR(AOP(result)->aopu.pcop)->instance:
10381 PCOI(AOP(result)->aopu.pcop)->offset);
10385 if(AOP(result)->aopu.pcop->type == PO_DIR)
10386 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
10389 if (AOP_TYPE(right) == AOP_LIT) {
10390 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
10392 lit = lit >> (8*offset);
10394 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
10395 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
10397 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
10400 mov2w(AOP(right), offset);
10401 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
10407 pic16_freeAsmop(right,NULL,ic,TRUE);
10412 /*-----------------------------------------------------------------*/
10413 /* genNearPointerSet - pic16_emitcode for near pointer put */
10414 /*-----------------------------------------------------------------*/
10415 static void genNearPointerSet (operand *right,
10422 sym_link *ptype = operandType(result);
10423 sym_link *resetype;
10425 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10426 retype= getSpec(operandType(right));
10427 resetype = getSpec(operandType(result));
10429 pic16_aopOp(result,ic,FALSE);
10431 /* if the result is rematerializable &
10432 * in data space & not a bit variable */
10434 /* and result is not a bit variable */
10435 if (AOP_TYPE(result) == AOP_PCODE
10436 // && AOP_TYPE(result) == AOP_IMMD
10437 && DCL_TYPE(ptype) == POINTER
10438 && !IS_BITFIELD(retype)
10439 && !IS_BITFIELD(resetype)) {
10441 genDataPointerSet (right,result,ic);
10442 pic16_freeAsmop(result,NULL,ic,TRUE);
10446 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10447 pic16_aopOp(right,ic,FALSE);
10448 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10450 /* if the value is already in a pointer register
10451 * then don't need anything more */
10452 if (!AOP_INPREG(AOP(result))) {
10453 /* otherwise get a free pointer register */
10454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10456 if( (AOP_TYPE(result) == AOP_PCODE)
10457 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
10458 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
10460 if(!IS_BITFIELD(resetype))
10461 pic16_loadFSR0( result ); // patch 10
10463 // set up FSR0 with address of result
10464 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
10465 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
10470 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10472 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10474 /* if bitfield then unpack the bits */
10475 if (IS_BITFIELD(resetype)) {
10476 genPackBits (resetype, result, right, NULL, POINTER);
10478 /* we have can just get the values */
10479 int size = AOP_SIZE(right);
10482 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10484 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10487 //pic16_emitcode("mov","@%s,a",rname);
10488 pic16_emitcode("movf","indf0,w ;1");
10491 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
10492 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
10494 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
10496 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
10498 } else { // no literal //
10500 pic16_emitpcode(POC_MOVFF, //
10501 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
10502 pic16_popCopyReg(&pic16_pc_postinc0))); //
10504 pic16_emitpcode(POC_MOVFF, //
10505 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
10506 pic16_popCopyReg(&pic16_pc_indf0))); //
10514 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10515 /* now some housekeeping stuff */
10517 /* we had to allocate for this iCode */
10518 pic16_freeAsmop(NULL,aop,ic,TRUE);
10520 /* we did not allocate which means left
10521 * already in a pointer register, then
10522 * if size > 0 && this could be used again
10523 * we have to point it back to where it
10525 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10526 if (AOP_SIZE(right) > 1
10527 && !OP_SYMBOL(result)->remat
10528 && ( OP_SYMBOL(result)->liveTo > ic->seq
10531 int size = AOP_SIZE(right) - 1;
10534 pic16_emitcode("decf","fsr0,f");
10535 //pic16_emitcode("dec","%s",rname);
10539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10542 pic16_freeAsmop(right,NULL,ic,TRUE);
10543 pic16_freeAsmop(result,NULL,ic,TRUE);
10546 /*-----------------------------------------------------------------*/
10547 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
10548 /*-----------------------------------------------------------------*/
10549 static void genPagedPointerSet (operand *right,
10554 regs *preg = NULL ;
10558 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10560 retype= getSpec(operandType(right));
10562 pic16_aopOp(result,ic,FALSE);
10564 /* if the value is already in a pointer register
10565 then don't need anything more */
10566 if (!AOP_INPREG(AOP(result))) {
10567 /* otherwise get a free pointer register */
10569 preg = getFreePtr(ic,&aop,FALSE);
10570 pic16_emitcode("mov","%s,%s",
10572 pic16_aopGet(AOP(result),0,FALSE,TRUE));
10573 rname = preg->name ;
10575 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10577 pic16_freeAsmop(result,NULL,ic,TRUE);
10578 pic16_aopOp (right,ic,FALSE);
10580 /* if bitfield then unpack the bits */
10581 if (IS_BITFIELD(retype))
10582 genPackBits (retype,result,right,rname,PPOINTER);
10584 /* we have can just get the values */
10585 int size = AOP_SIZE(right);
10589 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10592 pic16_emitcode("movx","@%s,a",rname);
10595 pic16_emitcode("inc","%s",rname);
10601 /* now some housekeeping stuff */
10603 /* we had to allocate for this iCode */
10604 pic16_freeAsmop(NULL,aop,ic,TRUE);
10606 /* we did not allocate which means left
10607 already in a pointer register, then
10608 if size > 0 && this could be used again
10609 we have to point it back to where it
10611 if (AOP_SIZE(right) > 1 &&
10612 !OP_SYMBOL(result)->remat &&
10613 ( OP_SYMBOL(result)->liveTo > ic->seq ||
10615 int size = AOP_SIZE(right) - 1;
10617 pic16_emitcode("dec","%s",rname);
10622 pic16_freeAsmop(right,NULL,ic,TRUE);
10627 /*-----------------------------------------------------------------*/
10628 /* genFarPointerSet - set value from far space */
10629 /*-----------------------------------------------------------------*/
10630 static void genFarPointerSet (operand *right,
10631 operand *result, iCode *ic)
10634 sym_link *retype = getSpec(operandType(right));
10636 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10637 pic16_aopOp(result,ic,FALSE);
10639 /* if the operand is already in dptr
10640 then we do nothing else we move the value to dptr */
10641 if (AOP_TYPE(result) != AOP_STR) {
10642 /* if this is remateriazable */
10643 if (AOP_TYPE(result) == AOP_IMMD)
10644 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
10645 else { /* we need to get it byte by byte */
10646 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
10647 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
10648 if (options.model == MODEL_FLAT24)
10650 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
10654 /* so dptr know contains the address */
10655 pic16_freeAsmop(result,NULL,ic,TRUE);
10656 pic16_aopOp(right,ic,FALSE);
10658 /* if bit then unpack */
10659 if (IS_BITFIELD(retype))
10660 genPackBits(retype,result,right,"dptr",FPOINTER);
10662 size = AOP_SIZE(right);
10666 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10668 pic16_emitcode("movx","@dptr,a");
10670 pic16_emitcode("inc","dptr");
10674 pic16_freeAsmop(right,NULL,ic,TRUE);
10677 /*-----------------------------------------------------------------*/
10678 /* genGenPointerSet - set value from generic pointer space */
10679 /*-----------------------------------------------------------------*/
10680 static void genGenPointerSet (operand *right,
10681 operand *result, iCode *ic)
10683 int i, size, offset, lit;
10684 sym_link *retype = getSpec(operandType(right));
10686 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10688 pic16_aopOp(result,ic,FALSE);
10689 pic16_aopOp(right,ic,FALSE);
10690 size = AOP_SIZE(right);
10693 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10695 /* if the operand is already in dptr
10696 then we do nothing else we move the value to dptr */
10697 if (AOP_TYPE(result) != AOP_STR) {
10698 /* if this is remateriazable */
10699 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10700 // WARNING: anythig until "else" is untested!
10701 if (AOP_TYPE(result) == AOP_IMMD) {
10702 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10703 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
10704 // load FSR0 from immediate
10705 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10709 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10711 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10717 else { /* we need to get it byte by byte */
10718 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10719 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10721 // set up FSR0 with address of result
10722 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10723 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10725 /* hack hack! see if this the FSR. If so don't load W */
10726 if(AOP_TYPE(right) != AOP_ACC) {
10728 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10730 if(AOP_TYPE(right) == AOP_LIT)
10733 // note: pic16_popGet handles sign extension
10734 for(i=0;i<size;i++) {
10735 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
10737 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
10739 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10744 for(i=0;i<size;i++) {
10746 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10747 pic16_popCopyReg(&pic16_pc_postinc0)));
10749 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10750 pic16_popCopyReg(&pic16_pc_indf0)));
10756 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10757 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10759 } // if (AOP_TYPE(result) != AOP_IMMD)
10761 } // if (AOP_TYPE(result) != AOP_STR)
10762 /* so dptr know contains the address */
10765 /* if bit then unpack */
10766 if (IS_BITFIELD(retype))
10767 genPackBits(retype,result,right,"dptr",GPOINTER);
10769 size = AOP_SIZE(right);
10772 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
10774 // set up FSR0 with address of result
10775 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10776 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10779 if (AOP_TYPE(right) == AOP_LIT) {
10780 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10782 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
10784 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10786 } else { // no literal
10788 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10790 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10798 pic16_freeAsmop(right,NULL,ic,TRUE);
10799 pic16_freeAsmop(result,NULL,ic,TRUE);
10802 /*-----------------------------------------------------------------*/
10803 /* genPointerSet - stores the value into a pointer location */
10804 /*-----------------------------------------------------------------*/
10805 static void genPointerSet (iCode *ic)
10807 operand *right, *result ;
10808 sym_link *type, *etype;
10811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10813 right = IC_RIGHT(ic);
10814 result = IC_RESULT(ic) ;
10816 /* depending on the type of pointer we need to
10817 move it to the correct pointer register */
10818 type = operandType(result);
10819 etype = getSpec(type);
10820 /* if left is of type of pointer then it is simple */
10821 if (IS_PTR(type) && !IS_FUNC(type->next)) {
10822 p_type = DCL_TYPE(type);
10825 /* we have to go by the storage class */
10826 p_type = PTR_TYPE(SPEC_OCLS(etype));
10828 /* if (SPEC_OCLS(etype)->codesp ) { */
10829 /* p_type = CPOINTER ; */
10832 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10833 /* p_type = FPOINTER ; */
10835 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10836 /* p_type = PPOINTER ; */
10838 /* if (SPEC_OCLS(etype) == idata ) */
10839 /* p_type = IPOINTER ; */
10841 /* p_type = POINTER ; */
10844 /* now that we have the pointer type we assign
10845 the pointer values */
10850 genNearPointerSet (right,result,ic);
10854 genPagedPointerSet (right,result,ic);
10858 genFarPointerSet (right,result,ic);
10862 genGenPointerSet (right,result,ic);
10866 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10867 "genPointerSet: illegal pointer type");
10871 /*-----------------------------------------------------------------*/
10872 /* genIfx - generate code for Ifx statement */
10873 /*-----------------------------------------------------------------*/
10874 static void genIfx (iCode *ic, iCode *popIc)
10876 operand *cond = IC_COND(ic);
10879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10881 pic16_aopOp(cond,ic,FALSE);
10883 /* get the value into acc */
10884 if (AOP_TYPE(cond) != AOP_CRY)
10885 pic16_toBoolean(cond);
10888 /* the result is now in the accumulator */
10889 pic16_freeAsmop(cond,NULL,ic,TRUE);
10891 /* if there was something to be popped then do it */
10895 /* if the condition is a bit variable */
10896 if (isbit && IS_ITEMP(cond) &&
10898 genIfxJump(ic,SPIL_LOC(cond)->rname);
10899 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
10902 if (isbit && !IS_ITEMP(cond))
10903 genIfxJump(ic,OP_SYMBOL(cond)->rname);
10905 genIfxJump(ic,"a");
10911 /*-----------------------------------------------------------------*/
10912 /* genAddrOf - generates code for address of */
10913 /*-----------------------------------------------------------------*/
10914 static void genAddrOf (iCode *ic)
10916 operand *result, *left;
10918 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
10919 pCodeOp *pcop0, *pcop1, *pcop2;
10921 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10923 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
10924 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
10926 sym = OP_SYMBOL( left );
10928 size = AOP_SIZE(IC_RESULT(ic));
10932 DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
10937 // if(pic16_debug_verbose) {
10938 // fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
10939 // __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
10942 /* Assume that what we want the address of is in data space
10943 * since there is no stack on the PIC, yet! -- VR */
10945 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10948 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10951 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10955 pic16_emitpcode(POC_MOVLW, pcop0);
10956 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10957 pic16_emitpcode(POC_MOVLW, pcop1);
10958 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10959 pic16_emitpcode(POC_MOVLW, pcop2);
10960 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10963 pic16_emitpcode(POC_MOVLW, pcop0);
10964 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10965 pic16_emitpcode(POC_MOVLW, pcop1);
10966 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10968 pic16_emitpcode(POC_MOVLW, pcop0);
10969 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10972 pic16_freeAsmop(result,NULL,ic,TRUE);
10973 pic16_freeAsmop(left, NULL, ic, FALSE);
10978 /*-----------------------------------------------------------------*/
10979 /* genFarFarAssign - assignment when both are in far space */
10980 /*-----------------------------------------------------------------*/
10981 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
10983 int size = AOP_SIZE(right);
10986 /* first push the right side on to the stack */
10988 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10990 pic16_emitcode ("push","acc");
10993 pic16_freeAsmop(right,NULL,ic,FALSE);
10994 /* now assign DPTR to result */
10995 pic16_aopOp(result,ic,FALSE);
10996 size = AOP_SIZE(result);
10998 pic16_emitcode ("pop","acc");
10999 pic16_aopPut(AOP(result),"a",--offset);
11001 pic16_freeAsmop(result,NULL,ic,FALSE);
11006 /*-----------------------------------------------------------------*/
11007 /* genAssign - generate code for assignment */
11008 /*-----------------------------------------------------------------*/
11009 static void genAssign (iCode *ic)
11011 operand *result, *right;
11012 int size, offset,know_W;
11013 unsigned long lit = 0L;
11015 result = IC_RESULT(ic);
11016 right = IC_RIGHT(ic) ;
11018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11020 /* if they are the same */
11021 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
11024 pic16_aopOp(right,ic,FALSE);
11025 pic16_aopOp(result,ic,TRUE);
11027 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11029 /* if they are the same registers */
11030 if (pic16_sameRegs(AOP(right),AOP(result)))
11033 /* if the result is a bit */
11034 if (AOP_TYPE(result) == AOP_CRY) {
11035 /* if the right size is a literal then
11036 we know what the value is */
11037 if (AOP_TYPE(right) == AOP_LIT) {
11039 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
11040 pic16_popGet(AOP(result),0));
11042 if (((int) operandLitValue(right)))
11043 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11044 AOP(result)->aopu.aop_dir,
11045 AOP(result)->aopu.aop_dir);
11047 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11048 AOP(result)->aopu.aop_dir,
11049 AOP(result)->aopu.aop_dir);
11053 /* the right is also a bit variable */
11054 if (AOP_TYPE(right) == AOP_CRY) {
11055 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11056 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11057 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11059 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
11060 AOP(result)->aopu.aop_dir,
11061 AOP(result)->aopu.aop_dir);
11062 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
11063 AOP(right)->aopu.aop_dir,
11064 AOP(right)->aopu.aop_dir);
11065 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
11066 AOP(result)->aopu.aop_dir,
11067 AOP(result)->aopu.aop_dir);
11071 /* we need to or */
11072 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11073 pic16_toBoolean(right);
11075 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11076 //pic16_aopPut(AOP(result),"a",0);
11080 /* bit variables done */
11082 size = AOP_SIZE(result);
11085 if(AOP_TYPE(right) == AOP_LIT) {
11086 if(!IS_FLOAT(operandType( right )))
11087 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
11090 unsigned long lit_int;
11094 /* take care if literal is a float */
11095 info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
11096 lit = info.lit_int;
11100 // fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
11101 // sizeof(unsigned long int), sizeof(float));
11103 if(AOP_TYPE(right) != AOP_LIT
11104 && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) {
11105 DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
11106 fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
11108 // set up table pointer
11109 if( (AOP_TYPE(right) == AOP_PCODE)
11110 && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
11111 || (AOP(right)->aopu.pcop->type == PO_DIR)))
11113 fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
11114 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
11115 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
11116 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
11117 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
11118 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
11119 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
11121 fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
11122 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
11123 pic16_popCopyReg(&pic16_pc_tblptrl)));
11124 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
11125 pic16_popCopyReg(&pic16_pc_tblptrh)));
11126 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2),
11127 pic16_popCopyReg(&pic16_pc_tblptru)));
11130 size = min(AOP_SIZE(right), AOP_SIZE(result));
11132 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
11133 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat),
11134 pic16_popGet(AOP(result),offset)));
11138 if(AOP_SIZE(result) > AOP_SIZE(right)) {
11139 size = AOP_SIZE(result) - AOP_SIZE(right);
11141 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset));
11151 /* VR - What is this?! */
11152 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
11153 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11154 if(aopIdx(AOP(result),0) == 4) {
11156 /* this is a workaround to save value of right into wreg too,
11157 * value of wreg is going to be used later */
11158 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11159 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11160 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11164 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
11170 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11171 if(AOP_TYPE(right) == AOP_LIT) {
11173 if(know_W != (lit&0xff))
11174 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
11176 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11178 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11182 } else if (AOP_TYPE(right) == AOP_CRY) {
11183 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11185 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
11186 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
11188 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
11189 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11190 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11192 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11195 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
11196 normally should work, but mind that the W register live range
11197 is not checked, so if the code generator assumes that the W
11198 is already loaded after such a pair, wrong code will be generated.
11200 Checking the live range is the next step.
11201 This is experimental code yet and has not been fully tested yet.
11202 USE WITH CARE. Revert to old code by setting 0 to the condition above.
11203 Vangelis Rokas 030603 (vrokas@otenet.gr) */
11205 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
11207 /* This is the old code, which is assumed(?!) that works fine(!?) */
11209 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11210 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11219 pic16_freeAsmop (right,NULL,ic,FALSE);
11220 pic16_freeAsmop (result,NULL,ic,TRUE);
11223 /*-----------------------------------------------------------------*/
11224 /* genJumpTab - generates code for jump table */
11225 /*-----------------------------------------------------------------*/
11226 static void genJumpTab (iCode *ic)
11231 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11233 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
11234 /* get the condition into accumulator */
11235 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
11237 /* multiply by three */
11238 pic16_emitcode("add","a,acc");
11239 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
11241 jtab = newiTempLabel(NULL);
11242 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
11243 pic16_emitcode("jmp","@a+dptr");
11244 pic16_emitcode("","%05d_DS_:",jtab->key+100);
11246 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
11247 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
11249 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
11250 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
11251 pic16_emitpLabel(jtab->key);
11253 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
11255 /* now generate the jump labels */
11256 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
11257 jtab = setNextItem(IC_JTLABELS(ic))) {
11258 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
11259 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
11265 /*-----------------------------------------------------------------*/
11266 /* genMixedOperation - gen code for operators between mixed types */
11267 /*-----------------------------------------------------------------*/
11269 TSD - Written for the PIC port - but this unfortunately is buggy.
11270 This routine is good in that it is able to efficiently promote
11271 types to different (larger) sizes. Unfortunately, the temporary
11272 variables that are optimized out by this routine are sometimes
11273 used in other places. So until I know how to really parse the
11274 iCode tree, I'm going to not be using this routine :(.
11276 static int genMixedOperation (iCode *ic)
11279 operand *result = IC_RESULT(ic);
11280 sym_link *ctype = operandType(IC_LEFT(ic));
11281 operand *right = IC_RIGHT(ic);
11287 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
11289 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11295 nextright = IC_RIGHT(nextic);
11296 nextleft = IC_LEFT(nextic);
11297 nextresult = IC_RESULT(nextic);
11299 pic16_aopOp(right,ic,FALSE);
11300 pic16_aopOp(result,ic,FALSE);
11301 pic16_aopOp(nextright, nextic, FALSE);
11302 pic16_aopOp(nextleft, nextic, FALSE);
11303 pic16_aopOp(nextresult, nextic, FALSE);
11305 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
11307 operand *t = right;
11311 pic16_emitcode(";remove right +","");
11313 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
11315 operand *t = right;
11319 pic16_emitcode(";remove left +","");
11323 big = AOP_SIZE(nextleft);
11324 small = AOP_SIZE(nextright);
11326 switch(nextic->op) {
11329 pic16_emitcode(";optimize a +","");
11330 /* if unsigned or not an integral type */
11331 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
11332 pic16_emitcode(";add a bit to something","");
11335 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
11337 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
11338 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
11339 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
11341 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
11349 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11350 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11351 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11354 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11356 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
11357 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
11358 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
11359 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11360 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
11363 pic16_emitcode("rlf","known_zero,w");
11370 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
11371 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
11372 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11374 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
11384 pic16_freeAsmop(right,NULL,ic,TRUE);
11385 pic16_freeAsmop(result,NULL,ic,TRUE);
11386 pic16_freeAsmop(nextright,NULL,ic,TRUE);
11387 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
11389 nextic->generated = 1;
11396 /*-----------------------------------------------------------------*/
11397 /* genCast - gen code for casting */
11398 /*-----------------------------------------------------------------*/
11399 static void genCast (iCode *ic)
11401 operand *result = IC_RESULT(ic);
11402 sym_link *ctype = operandType(IC_LEFT(ic));
11403 sym_link *rtype = operandType(IC_RIGHT(ic));
11404 operand *right = IC_RIGHT(ic);
11407 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11408 /* if they are equivalent then do nothing */
11409 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
11412 pic16_aopOp(right,ic,FALSE) ;
11413 pic16_aopOp(result,ic,FALSE);
11415 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
11417 /* if the result is a bit */
11418 if (AOP_TYPE(result) == AOP_CRY) {
11420 /* if the right size is a literal then
11421 * we know what the value is */
11422 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11424 if (AOP_TYPE(right) == AOP_LIT) {
11425 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
11426 pic16_popGet(AOP(result),0));
11428 if (((int) operandLitValue(right)))
11429 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
11430 AOP(result)->aopu.aop_dir,
11431 AOP(result)->aopu.aop_dir);
11433 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
11434 AOP(result)->aopu.aop_dir,
11435 AOP(result)->aopu.aop_dir);
11439 /* the right is also a bit variable */
11440 if (AOP_TYPE(right) == AOP_CRY) {
11442 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11444 pic16_emitcode("clrc","");
11445 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
11446 AOP(right)->aopu.aop_dir,
11447 AOP(right)->aopu.aop_dir);
11448 pic16_aopPut(AOP(result),"c",0);
11452 /* we need to or */
11453 if (AOP_TYPE(right) == AOP_REG) {
11454 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
11455 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
11456 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
11458 pic16_toBoolean(right);
11459 pic16_aopPut(AOP(result),"a",0);
11463 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
11466 size = AOP_SIZE(result);
11468 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11470 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
11471 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
11472 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
11475 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
11480 /* if they are the same size : or less */
11481 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
11483 /* if they are in the same place */
11484 if (pic16_sameRegs(AOP(right),AOP(result)))
11487 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11489 if (IS_PTR_CONST(rtype))
11491 if (IS_CODEPTR(rtype))
11493 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
11496 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
11498 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
11500 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
11503 if(AOP_TYPE(right) == AOP_IMMD) {
11504 pCodeOp *pcop0, *pcop1, *pcop2;
11505 symbol *sym = OP_SYMBOL( right );
11507 size = AOP_SIZE(result);
11509 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11511 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11513 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
11516 pic16_emitpcode(POC_MOVLW, pcop0);
11517 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
11518 pic16_emitpcode(POC_MOVLW, pcop1);
11519 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
11520 pic16_emitpcode(POC_MOVLW, pcop2);
11521 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
11524 pic16_emitpcode(POC_MOVLW, pcop0);
11525 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11526 pic16_emitpcode(POC_MOVLW, pcop1);
11527 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
11529 pic16_emitpcode(POC_MOVLW, pcop0);
11530 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11534 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
11535 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
11536 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
11537 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
11538 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
11539 if(AOP_SIZE(result) <2)
11540 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
11542 /* if they in different places then copy */
11543 size = AOP_SIZE(result);
11546 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11547 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11554 /* if the result is of type pointer */
11555 if (IS_PTR(ctype)) {
11557 sym_link *type = operandType(right);
11558 sym_link *etype = getSpec(type);
11560 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
11562 /* pointer to generic pointer */
11563 if (IS_GENPTR(ctype)) {
11567 p_type = DCL_TYPE(type);
11569 /* we have to go by the storage class */
11570 p_type = PTR_TYPE(SPEC_OCLS(etype));
11572 /* if (SPEC_OCLS(etype)->codesp ) */
11573 /* p_type = CPOINTER ; */
11575 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
11576 /* p_type = FPOINTER ; */
11578 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
11579 /* p_type = PPOINTER; */
11581 /* if (SPEC_OCLS(etype) == idata ) */
11582 /* p_type = IPOINTER ; */
11584 /* p_type = POINTER ; */
11587 /* the first two bytes are known */
11588 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
11589 size = GPTRSIZE - 1;
11592 if(offset < AOP_SIZE(right)) {
11593 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
11594 if ((AOP_TYPE(right) == AOP_PCODE) &&
11595 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
11596 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
11597 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11599 pic16_aopPut(AOP(result),
11600 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
11604 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
11607 /* the last byte depending on type */
11611 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
11614 pic16_emitcode(";BUG!? ","%d",__LINE__);
11618 pic16_emitcode(";BUG!? ","%d",__LINE__);
11622 pic16_emitcode(";BUG!? ","%d",__LINE__);
11627 /* this should never happen */
11628 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11629 "got unknown pointer type");
11632 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
11636 /* just copy the pointers */
11637 size = AOP_SIZE(result);
11640 pic16_aopPut(AOP(result),
11641 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
11650 /* so we now know that the size of destination is greater
11651 than the size of the source.
11652 Now, if the next iCode is an operator then we might be
11653 able to optimize the operation without performing a cast.
11655 if(genMixedOperation(ic))
11658 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11660 /* we move to result for the size of source */
11661 size = AOP_SIZE(right);
11664 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
11665 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11666 // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11670 /* now depending on the sign of the destination */
11671 size = AOP_SIZE(result) - AOP_SIZE(right);
11672 /* if unsigned or not an integral type */
11673 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
11675 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
11677 /* we need to extend the sign :( */
11680 /* Save one instruction of casting char to int */
11681 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11682 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
11683 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
11685 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
11688 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
11690 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
11692 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
11695 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
11700 pic16_freeAsmop(right,NULL,ic,TRUE);
11701 pic16_freeAsmop(result,NULL,ic,TRUE);
11705 /*-----------------------------------------------------------------*/
11706 /* genDjnz - generate decrement & jump if not zero instrucion */
11707 /*-----------------------------------------------------------------*/
11708 static int genDjnz (iCode *ic, iCode *ifx)
11710 symbol *lbl, *lbl1;
11711 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11716 /* if the if condition has a false label
11717 then we cannot save */
11721 /* if the minus is not of the form
11723 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
11724 !IS_OP_LITERAL(IC_RIGHT(ic)))
11727 if (operandLitValue(IC_RIGHT(ic)) != 1)
11730 /* if the size of this greater than one then no
11732 if (getSize(operandType(IC_RESULT(ic))) > 1)
11735 /* otherwise we can save BIG */
11736 lbl = newiTempLabel(NULL);
11737 lbl1= newiTempLabel(NULL);
11739 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11741 if (IS_AOP_PREG(IC_RESULT(ic))) {
11742 pic16_emitcode("dec","%s",
11743 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11744 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11745 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
11749 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
11750 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
11752 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11753 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
11756 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
11757 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
11758 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
11759 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
11762 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11763 ifx->generated = 1;
11767 /*-----------------------------------------------------------------*/
11768 /* genReceive - generate code for a receive iCode */
11769 /*-----------------------------------------------------------------*/
11770 static void genReceive (iCode *ic)
11772 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11775 fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__,
11776 OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack);
11778 // pic16_DumpOp(__FUNCTION__, IC_RESULT(ic));
11780 if (isOperandInFarSpace(IC_RESULT(ic)) &&
11781 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
11782 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
11784 int size = getSize(operandType(IC_RESULT(ic)));
11785 int offset = pic16_fReturnSizePic - size;
11789 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
11790 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
11794 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
11796 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11797 size = AOP_SIZE(IC_RESULT(ic));
11800 pic16_emitcode ("pop","acc");
11801 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
11804 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
11807 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11809 assignResultValue(IC_RESULT(ic), 0);
11812 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11815 /*-----------------------------------------------------------------*/
11816 /* genDummyRead - generate code for dummy read of volatiles */
11817 /*-----------------------------------------------------------------*/
11819 genDummyRead (iCode * ic)
11821 pic16_emitcode ("; genDummyRead","");
11822 pic16_emitcode ("; not implemented","");
11827 /*-----------------------------------------------------------------*/
11828 /* genpic16Code - generate code for pic16 based controllers */
11829 /*-----------------------------------------------------------------*/
11831 * At this point, ralloc.c has gone through the iCode and attempted
11832 * to optimize in a way suitable for a PIC. Now we've got to generate
11833 * PIC instructions that correspond to the iCode.
11835 * Once the instructions are generated, we'll pass through both the
11836 * peep hole optimizer and the pCode optimizer.
11837 *-----------------------------------------------------------------*/
11839 void genpic16Code (iCode *lic)
11844 lineHead = lineCurr = NULL;
11846 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
11847 pic16_addpBlock(pb);
11850 /* if debug information required */
11851 if (options.debug && currFunc) {
11853 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
11858 for (ic = lic ; ic ; ic = ic->next ) {
11860 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
11861 if ( cln != ic->lineno ) {
11862 if ( options.debug ) {
11863 debugFile->writeCLine (ic);
11866 if(!options.noCcodeInAsm) {
11867 pic16_addpCode2pBlock(pb,
11868 pic16_newpCodeCSource(ic->lineno, ic->filename,
11869 printCLine(ic->filename, ic->lineno)));
11875 if(options.iCodeInAsm) {
11877 /* insert here code to print iCode as comment */
11878 l = Safe_strdup(printILine(ic));
11879 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
11882 /* if the result is marked as
11883 spilt and rematerializable or code for
11884 this has already been generated then
11886 if (resultRemat(ic) || ic->generated )
11889 /* depending on the operation */
11908 /* IPOP happens only when trying to restore a
11909 spilt live range, if there is an ifx statement
11910 following this pop then the if statement might
11911 be using some of the registers being popped which
11912 would destroy the contents of the register so
11913 we need to check for this condition and handle it */
11915 ic->next->op == IFX &&
11916 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
11917 genIfx (ic->next,ic);
11935 genEndFunction (ic);
11951 pic16_genPlus (ic) ;
11955 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
11956 pic16_genMinus (ic);
11972 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
11976 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
11983 /* note these two are xlated by algebraic equivalence
11984 during parsing SDCC.y */
11985 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11986 "got '>=' or '<=' shouldn't have come here");
11990 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
12002 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
12006 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
12010 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
12034 genRightShift (ic);
12037 case GET_VALUE_AT_ADDRESS:
12042 if (POINTER_SET(ic))
12069 addSet(&_G.sendSet,ic);
12072 case DUMMY_READ_VOLATILE:
12082 /* now we are ready to call the
12083 peep hole optimizer */
12084 if (!options.nopeep) {
12085 peepHole (&lineHead);
12087 /* now do the actual printing */
12088 printLine (lineHead,codeOutFile);
12091 DFPRINTF((stderr,"printing pBlock\n\n"));
12092 pic16_printpBlock(stdout,pb);