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)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
29 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
30 Made everything static
31 -------------------------------------------------------------------------*/
37 #include "SDCCglobl.h"
41 #include "SDCCpeeph.h"
49 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
50 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
51 void pic16_genMult8X8_8 (operand *, operand *,operand *);
52 void pic16_genMult16X16_16(operand *, operand *, operand *);
53 void pic16_genMult32X32_32(operand *, operand *, operand *);
54 pCode *pic16_AssembleLine(char *line, int peeps);
55 extern void pic16_printpBlock(FILE *of, pBlock *pb);
56 static asmop *newAsmop (short type);
57 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
58 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
59 static void mov2w (asmop *aop, int offset);
60 static int aopIdx (asmop *aop, int offset);
62 static int labelOffset=0;
63 extern int pic16_debug_verbose;
64 static int optimized_for_speed = 0;
70 /* max_key keeps track of the largest label number used in
71 a function. This is then used to adjust the label offset
72 for the next function.
75 static int GpsuedoStkPtr=0;
77 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
78 unsigned int pic16aopLiteral (value *val, int offset);
79 const char *pic16_AopType(short type);
80 static iCode *ifxForOp ( operand *op, iCode *ic );
82 void pic16_pushpCodeOp(pCodeOp *pcop);
83 void pic16_poppCodeOp(pCodeOp *pcop);
87 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
89 /* this is the down and dirty file with all kinds of
90 kludgy & hacky stuff. This is what it is all about
91 CODE GENERATION for a specific MCU . some of the
92 routines may be reusable, will have to see */
94 static char *zero = "#0x00";
95 static char *one = "#0x01";
96 static char *spname = "sp";
100 * Function return value policy (MSB-->LSB):
102 * 16 bits -> PRODL:WREG
103 * 24 bits -> PRODH:PRODL:WREG
104 * 32 bits -> FSR0L:PRODH:PRODL:WREG
105 * >32 bits -> on stack, and FSR0 points to the beginning
110 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
111 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
112 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
113 static char **fReturn = fReturnpic16;
115 static char *accUse[] = {"WREG"};
117 //static short rbank = -1;
130 /* Resolved ifx structure. This structure stores information
131 about an iCode ifx that makes it easier to generate code.
133 typedef struct resolvedIfx {
134 symbol *lbl; /* pointer to a label */
135 int condition; /* true or false ifx */
136 int generated; /* set true when the code associated with the ifx
140 extern int pic16_ptrRegReq ;
141 extern int pic16_nRegs;
142 extern FILE *codeOutFile;
143 static void saverbank (int, iCode *,bool);
145 static lineNode *lineHead = NULL;
146 static lineNode *lineCurr = NULL;
148 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
149 0xE0, 0xC0, 0x80, 0x00};
150 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
151 0x07, 0x03, 0x01, 0x00};
155 /*-----------------------------------------------------------------*/
156 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
157 /* exponent of 2 is returned, otherwise -1 is */
159 /* note that this is similar to the function `powof2' in SDCCsymt */
163 /*-----------------------------------------------------------------*/
164 static int my_powof2 (unsigned long num)
167 if( (num & (num-1)) == 0) {
180 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
182 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
184 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
185 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
186 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
187 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
188 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
189 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
190 ((result) ? AOP_SIZE(result) : 0));
193 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
196 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
198 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
199 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
200 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
201 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
202 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
203 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
207 void pic16_emitpcomment (char *fmt, ...)
210 char lb[INITIAL_INLINEASM];
216 vsprintf(lb+1,fmt,ap);
218 while (isspace(*lbp)) lbp++;
221 lineCurr = (lineCurr ?
222 connectLine(lineCurr,newLineNode(lb)) :
223 (lineHead = newLineNode(lb)));
224 lineCurr->isInline = _G.inLine;
225 lineCurr->isDebug = _G.debugLine;
227 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
230 // fprintf(stderr, "%s\n", lb);
233 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
236 char lb[INITIAL_INLINEASM];
239 if(!pic16_debug_verbose)
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
262 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
265 // fprintf(stderr, "%s\n", lb);
268 void pic16_emitpLabel(int key)
270 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
273 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
277 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
279 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
281 // fprintf(stderr, "%s\n", pcop->name);
284 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
287 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
293 #define pic16_emitcode DEBUGpic16_emitcode
295 /*-----------------------------------------------------------------*/
296 /* pic16_emitcode - writes the code into a file : for now it is simple */
297 /*-----------------------------------------------------------------*/
298 void pic16_emitcode (char *inst,char *fmt, ...)
301 char lb[INITIAL_INLINEASM];
308 sprintf(lb,"%s\t",inst);
310 sprintf(lb,"%s",inst);
311 vsprintf(lb+(strlen(lb)),fmt,ap);
315 while (isspace(*lbp)) lbp++;
318 lineCurr = (lineCurr ?
319 connectLine(lineCurr,newLineNode(lb)) :
320 (lineHead = newLineNode(lb)));
321 lineCurr->isInline = _G.inLine;
322 lineCurr->isDebug = _G.debugLine;
324 // VR fprintf(stderr, "lb = <%s>\n", lbp);
326 // if(pic16_debug_verbose)
327 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
334 /*-----------------------------------------------------------------*/
335 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
336 /*-----------------------------------------------------------------*/
337 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
339 bool r0iu = FALSE , r1iu = FALSE;
340 bool r0ou = FALSE , r1ou = FALSE;
342 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
344 /* the logic: if r0 & r1 used in the instruction
345 then we are in trouble otherwise */
347 /* first check if r0 & r1 are used by this
348 instruction, in which case we are in trouble */
349 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
350 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
355 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
356 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
358 /* if no usage of r0 then return it */
359 if (!r0iu && !r0ou) {
360 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
361 (*aopp)->type = AOP_R0;
363 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
366 /* if no usage of r1 then return it */
367 if (!r1iu && !r1ou) {
368 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
369 (*aopp)->type = AOP_R1;
371 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
374 /* now we know they both have usage */
375 /* if r0 not used in this instruction */
377 /* push it if not already pushed */
379 //pic16_emitcode ("push","%s",
380 // pic16_regWithIdx(R0_IDX)->dname);
384 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
385 (*aopp)->type = AOP_R0;
387 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
390 /* if r1 not used then */
393 /* push it if not already pushed */
395 //pic16_emitcode ("push","%s",
396 // pic16_regWithIdx(R1_IDX)->dname);
400 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
401 (*aopp)->type = AOP_R1;
402 return pic16_regWithIdx(R1_IDX);
406 /* I said end of world but not quite end of world yet */
407 /* if this is a result then we can push it on the stack*/
409 (*aopp)->type = AOP_STK;
413 /* other wise this is true end of the world */
414 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
415 "getFreePtr should never reach here");
419 /*-----------------------------------------------------------------*/
420 /* newAsmop - creates a new asmOp */
421 /*-----------------------------------------------------------------*/
422 static asmop *newAsmop (short type)
426 aop = Safe_calloc(1,sizeof(asmop));
431 static void genSetDPTR(int n)
435 pic16_emitcode(";", "Select standard DPTR");
436 pic16_emitcode("mov", "dps, #0x00");
440 pic16_emitcode(";", "Select alternate DPTR");
441 pic16_emitcode("mov", "dps, #0x01");
445 /*-----------------------------------------------------------------*/
446 /* resolveIfx - converts an iCode ifx into a form more useful for */
447 /* generating code */
448 /*-----------------------------------------------------------------*/
449 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
452 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
458 resIfx->condition = 1; /* assume that the ifx is true */
459 resIfx->generated = 0; /* indicate that the ifx has not been used */
462 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
465 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
466 __FUNCTION__,__LINE__,resIfx->lbl->key);
471 resIfx->lbl = IC_TRUE(ifx);
473 resIfx->lbl = IC_FALSE(ifx);
474 resIfx->condition = 0;
478 DEBUGpic16_emitcode("; ***","ifx true is non-null");
480 DEBUGpic16_emitcode("; ***","ifx false is non-null");
484 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
488 /*-----------------------------------------------------------------*/
489 /* pointerCode - returns the code for a pointer type */
490 /*-----------------------------------------------------------------*/
491 static int pointerCode (sym_link *etype)
494 return PTR_TYPE(SPEC_OCLS(etype));
498 /*-----------------------------------------------------------------*/
499 /* aopForSym - for a true symbol */
500 /*-----------------------------------------------------------------*/
501 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
504 memmap *space= SPEC_OCLS(sym->etype);
506 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
507 /* if already has one */
509 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
513 /* if symbol was initially placed onStack then we must re-place it
514 * to direct memory, since pic16 does not have a specific stack */
517 SPEC_OCLS( sym->etype ) = data;
523 /* assign depending on the storage class */
524 /* if it is on the stack or indirectly addressable */
525 /* space we need to assign either r0 or r1 to it */
526 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
528 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
529 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
531 sym->aop = aop = newAsmop(0);
532 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
533 aop->size = getSize(sym->type);
535 /* now assign the address of the variable to
536 the pointer register */
537 if (aop->type != AOP_STK) {
541 pic16_emitcode("push","acc");
543 pic16_emitcode("mov","a,_bp");
544 pic16_emitcode("add","a,#0x%02x",
546 ((char)(sym->stack - _G.nRegsSaved )) :
547 ((char)sym->stack)) & 0xff);
548 pic16_emitcode("mov","%s,a",
549 aop->aopu.aop_ptr->name);
552 pic16_emitcode("pop","acc");
554 pic16_emitcode("mov","%s,#%s",
555 aop->aopu.aop_ptr->name,
557 aop->paged = space->paged;
559 aop->aopu.aop_stk = sym->stack;
564 if (sym->onStack && options.stack10bit)
566 /* It's on the 10 bit stack, which is located in
570 //DEBUGpic16_emitcode(";","%d",__LINE__);
573 pic16_emitcode("push","acc");
575 pic16_emitcode("mov","a,_bp");
576 pic16_emitcode("add","a,#0x%02x",
578 ((char)(sym->stack - _G.nRegsSaved )) :
579 ((char)sym->stack)) & 0xff);
582 pic16_emitcode ("mov","dpx1,#0x40");
583 pic16_emitcode ("mov","dph1,#0x00");
584 pic16_emitcode ("mov","dpl1, a");
588 pic16_emitcode("pop","acc");
590 sym->aop = aop = newAsmop(AOP_DPTR2);
591 aop->size = getSize(sym->type);
595 //DEBUGpic16_emitcode(";","%d",__LINE__);
596 /* if in bit space */
597 if (IN_BITSPACE(space)) {
598 sym->aop = aop = newAsmop (AOP_CRY);
599 aop->aopu.aop_dir = sym->rname ;
600 aop->size = getSize(sym->type);
601 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
604 /* if it is in direct space */
605 if (IN_DIRSPACE(space)) {
606 sym->aop = aop = newAsmop (AOP_DIR);
607 aop->aopu.aop_dir = sym->rname ;
608 aop->size = getSize(sym->type);
609 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
610 pic16_allocDirReg( IC_LEFT(ic) );
615 /* special case for a function */
616 if (IS_FUNC(sym->type)) {
617 sym->aop = aop = newAsmop(AOP_IMMD);
618 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
619 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
620 strcpy(aop->aopu.aop_immd,sym->rname);
621 aop->size = FPTRSIZE;
622 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
628 /* only remaining is far space */
629 /* in which case DPTR gets the address */
630 sym->aop = aop = newAsmop(AOP_PCODE);
632 /* change the next if to 1 to revert to good old immediate code */
633 if(IN_CODESPACE(space)) {
634 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
635 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
636 PCOI(aop->aopu.pcop)->index = 0;
638 /* try to allocate via direct register */
639 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset); // Patch 8
640 // aop->size = getSize( sym->type );
643 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
644 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
647 if(!pic16_allocDirReg (IC_LEFT(ic)))
651 if(IN_DIRSPACE( space ))
653 else if(IN_CODESPACE( space ))
654 aop->size = FPTRSIZE;
655 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
656 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
661 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
663 /* if it is in code space */
664 if (IN_CODESPACE(space))
670 /*-----------------------------------------------------------------*/
671 /* aopForRemat - rematerialzes an object */
672 /*-----------------------------------------------------------------*/
673 static asmop *aopForRemat (operand *op) // x symbol *sym)
675 symbol *sym = OP_SYMBOL(op);
676 iCode *ic = NULL, *oldic;
677 asmop *aop = newAsmop(AOP_PCODE);
683 ic = sym->rematiCode;
685 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
687 if(IS_OP_POINTER(op)) {
688 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
694 // pic16_emitpcomment("ic: %s\n", printILine(ic));
697 val += (int) operandLitValue(IC_RIGHT(ic));
698 } else if (ic->op == '-') {
699 val -= (int) operandLitValue(IC_RIGHT(ic));
703 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
706 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
708 if(!op->isaddr)viaimmd++; else viaimmd=0;
710 /* set the following if to 1 to revert to good old immediate code */
711 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
714 pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__);
716 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
719 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
721 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
724 PCOI(aop->aopu.pcop)->index = val;
726 pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__);
728 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
729 // aop->size = AOP_SIZE( IC_LEFT(ic) );
733 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
734 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
736 val, IS_PTR_CONST(operandType(op)));
738 val, IS_CODEPTR(operandType(op)));
741 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
743 pic16_allocDirReg (IC_LEFT(ic));
745 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
751 static int aopIdx (asmop *aop, int offset)
756 if(aop->type != AOP_REG)
759 return aop->aopu.aop_reg[offset]->rIdx;
762 /*-----------------------------------------------------------------*/
763 /* regsInCommon - two operands have some registers in common */
764 /*-----------------------------------------------------------------*/
765 static bool regsInCommon (operand *op1, operand *op2)
770 /* if they have registers in common */
771 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
774 sym1 = OP_SYMBOL(op1);
775 sym2 = OP_SYMBOL(op2);
777 if (sym1->nRegs == 0 || sym2->nRegs == 0)
780 for (i = 0 ; i < sym1->nRegs ; i++) {
785 for (j = 0 ; j < sym2->nRegs ;j++ ) {
789 if (sym2->regs[j] == sym1->regs[i])
797 /*-----------------------------------------------------------------*/
798 /* operandsEqu - equivalent */
799 /*-----------------------------------------------------------------*/
800 static bool operandsEqu ( operand *op1, operand *op2)
804 /* if they not symbols */
805 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
808 sym1 = OP_SYMBOL(op1);
809 sym2 = OP_SYMBOL(op2);
811 /* if both are itemps & one is spilt
812 and the other is not then false */
813 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
814 sym1->isspilt != sym2->isspilt )
817 /* if they are the same */
821 if (strcmp(sym1->rname,sym2->rname) == 0)
825 /* if left is a tmp & right is not */
829 (sym1->usl.spillLoc == sym2))
836 (sym2->usl.spillLoc == sym1))
842 /*-----------------------------------------------------------------*/
843 /* pic16_sameRegs - two asmops have the same registers */
844 /*-----------------------------------------------------------------*/
845 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
852 if (aop1->type != AOP_REG ||
853 aop2->type != AOP_REG )
856 if (aop1->size != aop2->size )
859 for (i = 0 ; i < aop1->size ; i++ )
860 if (aop1->aopu.aop_reg[i] !=
861 aop2->aopu.aop_reg[i] )
867 /*-----------------------------------------------------------------*/
868 /* pic16_aopOp - allocates an asmop for an operand : */
869 /*-----------------------------------------------------------------*/
870 void pic16_aopOp (operand *op, iCode *ic, bool result)
879 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
881 /* if this a literal */
882 if (IS_OP_LITERAL(op)) {
883 op->aop = aop = newAsmop(AOP_LIT);
884 aop->aopu.aop_lit = op->operand.valOperand;
885 aop->size = getSize(operandType(op));
890 sym_link *type = operandType(op);
892 if(IS_PTR_CONST(type))
896 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
899 /* if already has a asmop then continue */
903 /* if the underlying symbol has a aop */
904 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
905 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
906 op->aop = OP_SYMBOL(op)->aop;
910 /* if this is a true symbol */
911 if (IS_TRUE_SYMOP(op)) {
912 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
913 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
917 /* this is a temporary : this has
923 e) can be a return use only */
927 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
928 /* if the type is a conditional */
929 if (sym->regType == REG_CND) {
930 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
935 /* if it is spilt then two situations
937 b) has a spill location */
938 if (sym->isspilt || sym->nRegs == 0) {
940 DEBUGpic16_emitcode(";","%d",__LINE__);
941 /* rematerialize it NOW */
944 sym->aop = op->aop = aop =
946 aop->size = getSize(sym->type);
947 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
954 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
955 aop->size = getSize(sym->type);
956 for ( i = 0 ; i < 1 ; i++ ) {
957 aop->aopu.aop_str[i] = accUse[i];
958 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
960 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
961 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
969 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
970 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
971 //pic16_allocDirReg (IC_LEFT(ic));
972 aop->size = getSize(sym->type);
977 aop = op->aop = sym->aop = newAsmop(AOP_STR);
978 aop->size = getSize(sym->type);
979 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
980 aop->aopu.aop_str[i] = fReturn[i];
982 DEBUGpic16_emitcode(";","%d",__LINE__);
986 /* else spill location */
987 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
988 /* force a new aop if sizes differ */
989 sym->usl.spillLoc->aop = NULL;
991 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
992 __FUNCTION__,__LINE__,
993 sym->usl.spillLoc->rname,
994 sym->rname, sym->usl.spillLoc->offset);
996 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
997 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
998 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1000 sym->usl.spillLoc->offset);
1001 aop->size = getSize(sym->type);
1007 sym_link *type = operandType(op);
1009 if(IS_PTR_CONST(type))
1011 if(IS_CODEPTR(type))
1013 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1016 /* must be in a register */
1017 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1018 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1019 aop->size = sym->nRegs;
1020 for ( i = 0 ; i < sym->nRegs ;i++)
1021 aop->aopu.aop_reg[i] = sym->regs[i];
1024 /*-----------------------------------------------------------------*/
1025 /* pic16_freeAsmop - free up the asmop given to an operand */
1026 /*----------------------------------------------------------------*/
1027 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1044 /* depending on the asmop type only three cases need work AOP_RO
1045 , AOP_R1 && AOP_STK */
1047 switch (aop->type) {
1051 pic16_emitcode ("pop","ar0");
1055 bitVectUnSetBit(ic->rUsed,R0_IDX);
1061 pic16_emitcode ("pop","ar1");
1065 bitVectUnSetBit(ic->rUsed,R1_IDX);
1071 int stk = aop->aopu.aop_stk + aop->size;
1072 bitVectUnSetBit(ic->rUsed,R0_IDX);
1073 bitVectUnSetBit(ic->rUsed,R1_IDX);
1075 getFreePtr(ic,&aop,FALSE);
1077 if (options.stack10bit)
1079 /* I'm not sure what to do here yet... */
1082 "*** Warning: probably generating bad code for "
1083 "10 bit stack mode.\n");
1087 pic16_emitcode ("mov","a,_bp");
1088 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1089 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1091 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1095 pic16_emitcode("pop","acc");
1096 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1098 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1101 pic16_freeAsmop(op,NULL,ic,TRUE);
1103 pic16_emitcode("pop","ar0");
1108 pic16_emitcode("pop","ar1");
1116 /* all other cases just dealloc */
1120 OP_SYMBOL(op)->aop = NULL;
1121 /* if the symbol has a spill */
1123 SPIL_LOC(op)->aop = NULL;
1128 /*-----------------------------------------------------------------*/
1129 /* pic16_aopGet - for fetching value of the aop */
1130 /*-----------------------------------------------------------------*/
1131 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1136 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1138 /* offset is greater than size then zero */
1139 if (offset > (aop->size - 1) &&
1140 aop->type != AOP_LIT)
1143 /* depending on type */
1144 switch (aop->type) {
1148 DEBUGpic16_emitcode(";","%d",__LINE__);
1149 /* if we need to increment it */
1150 while (offset > aop->coff) {
1151 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1155 while (offset < aop->coff) {
1156 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1160 aop->coff = offset ;
1162 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1163 return (dname ? "acc" : "a");
1165 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1166 rs = Safe_calloc(1,strlen(s)+1);
1172 DEBUGpic16_emitcode(";","%d",__LINE__);
1173 if (aop->type == AOP_DPTR2)
1178 while (offset > aop->coff) {
1179 pic16_emitcode ("inc","dptr");
1183 while (offset < aop->coff) {
1184 pic16_emitcode("lcall","__decdptr");
1190 pic16_emitcode("clr","a");
1191 pic16_emitcode("movc","a,@a+dptr");
1194 pic16_emitcode("movx","a,@dptr");
1197 if (aop->type == AOP_DPTR2)
1202 return (dname ? "acc" : "a");
1207 sprintf (s,"%s",aop->aopu.aop_immd);
1210 sprintf(s,"(%s >> %d)",
1215 aop->aopu.aop_immd);
1216 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1217 rs = Safe_calloc(1,strlen(s)+1);
1223 sprintf(s,"(%s + %d)",
1226 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1228 sprintf(s,"%s",aop->aopu.aop_dir);
1229 rs = Safe_calloc(1,strlen(s)+1);
1235 // return aop->aopu.aop_reg[offset]->dname;
1237 return aop->aopu.aop_reg[offset]->name;
1240 //pic16_emitcode(";","%d",__LINE__);
1241 return aop->aopu.aop_dir;
1244 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1245 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1247 return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1250 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1251 rs = Safe_calloc(1,strlen(s)+1);
1256 aop->coff = offset ;
1257 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1260 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1262 return aop->aopu.aop_str[offset];
1266 pCodeOp *pcop = aop->aopu.pcop;
1267 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1269 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1270 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1271 sprintf(s,"%s", pcop->name);
1273 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1276 rs = Safe_calloc(1,strlen(s)+1);
1282 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1283 "aopget got unsupported aop->type");
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1290 /*-----------------------------------------------------------------*/
1291 pCodeOp *pic16_popGetTempReg(void)
1296 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1301 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1302 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1303 PCOR(pcop)->r->wasUsed=1;
1304 PCOR(pcop)->r->isFree=0;
1306 /* push value on stack */
1307 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1315 /*-----------------------------------------------------------------*/
1316 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1317 /*-----------------------------------------------------------------*/
1318 void pic16_popReleaseTempReg(pCodeOp *pcop)
1320 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1322 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1323 PCOR(pcop)->r->isFree = 1;
1325 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1328 /*-----------------------------------------------------------------*/
1329 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1330 /*-----------------------------------------------------------------*/
1331 pCodeOp *pic16_popGetLabel(unsigned int key)
1334 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1339 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1342 /*-----------------------------------------------------------------*/
1343 /* pic16_popCopyReg - copy a pcode operator */
1344 /*-----------------------------------------------------------------*/
1345 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1349 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1350 pcor->pcop.type = pc->pcop.type;
1352 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1353 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1355 pcor->pcop.name = NULL;
1358 pcor->rIdx = pc->rIdx;
1361 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1366 /*-----------------------------------------------------------------*/
1367 /* pic16_popGetLit - asm operator to pcode operator conversion */
1368 /*-----------------------------------------------------------------*/
1369 pCodeOp *pic16_popGetLit(unsigned int lit)
1371 return pic16_newpCodeOpLit(lit);
1374 /*-----------------------------------------------------------------*/
1375 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1376 /*-----------------------------------------------------------------*/
1377 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1379 return pic16_newpCodeOpLit2(lit, arg2);
1383 /*-----------------------------------------------------------------*/
1384 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1385 /*-----------------------------------------------------------------*/
1386 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1388 return pic16_newpCodeOpImmd(name, offset,index, 0);
1392 /*-----------------------------------------------------------------*/
1393 /* pic16_popGet - asm operator to pcode operator conversion */
1394 /*-----------------------------------------------------------------*/
1395 pCodeOp *pic16_popGetWithString(char *str)
1401 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1405 pcop = pic16_newpCodeOp(str,PO_STR);
1410 /*-----------------------------------------------------------------*/
1411 /* pic16_popRegFromString - */
1412 /*-----------------------------------------------------------------*/
1413 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1416 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1417 pcop->type = PO_DIR;
1419 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1420 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1425 pcop->name = Safe_calloc(1,strlen(str)+1);
1426 strcpy(pcop->name,str);
1428 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1430 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1431 if(PCOR(pcop)->r == NULL) {
1432 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1433 // __FUNCTION__, __LINE__, str, size, offset);
1434 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1436 //fprintf(stderr, "allocating new register -> %s\n", str);
1438 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1440 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1442 PCOR(pcop)->instance = offset;
1447 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1451 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1453 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1454 PCOR(pcop)->rIdx = rIdx;
1455 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1456 PCOR(pcop)->r->isFree = 0;
1457 PCOR(pcop)->r->wasUsed = 1;
1459 pcop->type = PCOR(pcop)->r->pc_type;
1464 /*---------------------------------------------------------------------------------*/
1465 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1467 /*---------------------------------------------------------------------------------*/
1468 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1473 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1475 /* comment the following check, so errors to throw up */
1476 // if(!pcop2)return NULL;
1478 temp = pic16_popGet(aop_dst, offset);
1479 pcop2->pcop2 = temp;
1486 /*--------------------------------------------------------------------------------.-*/
1487 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1488 /* VR 030601 , adapted by Hans Dorn */
1489 /*--------------------------------------------------------------------------------.-*/
1490 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1494 pcop2 = (pCodeOpReg2 *)src;
1502 /*---------------------------------------------------------------------------------*/
1503 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1504 /* movff instruction */
1505 /*---------------------------------------------------------------------------------*/
1506 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1511 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1512 pcop2->pcop2 = pic16_popCopyReg(dst);
1514 /* the pCodeOp may be already allocated */
1515 pcop2 = (pCodeOpReg2 *)(src);
1516 pcop2->pcop2 = (pCodeOp *)(dst);
1523 /*-----------------------------------------------------------------*/
1524 /* pic16_popGet - asm operator to pcode operator conversion */
1525 /*-----------------------------------------------------------------*/
1526 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1528 //char *s = buffer ;
1532 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1533 /* offset is greater than
1536 // if (offset > (aop->size - 1) &&
1537 // aop->type != AOP_LIT)
1538 // return NULL; //zero;
1540 /* depending on type */
1541 switch (aop->type) {
1547 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1548 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1555 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1556 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1560 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1562 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1564 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1566 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1567 PCOR(pcop)->rIdx = rIdx;
1568 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1569 PCOR(pcop)->r->wasUsed=1;
1570 PCOR(pcop)->r->isFree=0;
1572 PCOR(pcop)->instance = offset;
1573 pcop->type = PCOR(pcop)->r->pc_type;
1574 // rs = aop->aopu.aop_reg[offset]->name;
1575 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1579 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1580 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1586 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1587 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1591 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1593 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1595 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1596 PCOR(pcop)->rIdx = rIdx;
1597 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1598 PCOR(pcop)->r->wasUsed=1;
1599 PCOR(pcop)->r->isFree=0;
1601 PCOR(pcop)->instance = offset;
1602 pcop->type = PCOR(pcop)->r->pc_type;
1603 rs = aop->aopu.aop_reg[offset]->name;
1604 DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1609 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1611 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1612 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1613 //if(PCOR(pcop)->r == NULL)
1614 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1618 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1619 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1622 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1623 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1626 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1627 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1628 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1629 pcop->type = PCOR(pcop)->r->pc_type;
1630 pcop->name = PCOR(pcop)->r->name;
1636 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1638 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1639 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1641 switch( aop->aopu.pcop->type ) {
1642 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1643 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1645 assert( 0 ); /* should never reach here */;
1648 PCOI(pcop)->offset = offset;
1653 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1654 "pic16_popGet got unsupported aop->type");
1657 /*-----------------------------------------------------------------*/
1658 /* pic16_aopPut - puts a string for a aop */
1659 /*-----------------------------------------------------------------*/
1660 void pic16_aopPut (asmop *aop, char *s, int offset)
1665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1667 if (aop->size && offset > ( aop->size - 1)) {
1668 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1669 "pic16_aopPut got offset > aop->size");
1673 /* will assign value to value */
1674 /* depending on where it is ofcourse */
1675 switch (aop->type) {
1678 sprintf(d,"(%s + %d)",
1679 aop->aopu.aop_dir,offset);
1680 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1683 sprintf(d,"%s",aop->aopu.aop_dir);
1686 DEBUGpic16_emitcode(";","%d",__LINE__);
1688 pic16_emitcode("movf","%s,w",s);
1689 pic16_emitcode("movwf","%s",d);
1692 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1693 if(offset >= aop->size) {
1694 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1697 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1700 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1707 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1708 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1711 strcmp(s,"r0") == 0 ||
1712 strcmp(s,"r1") == 0 ||
1713 strcmp(s,"r2") == 0 ||
1714 strcmp(s,"r3") == 0 ||
1715 strcmp(s,"r4") == 0 ||
1716 strcmp(s,"r5") == 0 ||
1717 strcmp(s,"r6") == 0 ||
1718 strcmp(s,"r7") == 0 )
1719 pic16_emitcode("mov","%s,%s ; %d",
1720 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1724 if(strcmp(s,"W")==0 )
1725 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1727 pic16_emitcode("movwf","%s",
1728 aop->aopu.aop_reg[offset]->name);
1730 if(strcmp(s,zero)==0) {
1731 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1733 } else if(strcmp(s,"W")==0) {
1734 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1735 pcop->type = PO_GPR_REGISTER;
1737 PCOR(pcop)->rIdx = -1;
1738 PCOR(pcop)->r = NULL;
1740 DEBUGpic16_emitcode(";","%d",__LINE__);
1741 pcop->name = Safe_strdup(s);
1742 pic16_emitpcode(POC_MOVFW,pcop);
1743 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1744 } else if(strcmp(s,one)==0) {
1745 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1746 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1748 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1756 if (aop->type == AOP_DPTR2)
1762 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1763 "pic16_aopPut writting to code space");
1767 while (offset > aop->coff) {
1769 pic16_emitcode ("inc","dptr");
1772 while (offset < aop->coff) {
1774 pic16_emitcode("lcall","__decdptr");
1779 /* if not in accumulater */
1782 pic16_emitcode ("movx","@dptr,a");
1784 if (aop->type == AOP_DPTR2)
1792 while (offset > aop->coff) {
1794 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1796 while (offset < aop->coff) {
1798 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1804 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1809 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1811 if (strcmp(s,"r0") == 0 ||
1812 strcmp(s,"r1") == 0 ||
1813 strcmp(s,"r2") == 0 ||
1814 strcmp(s,"r3") == 0 ||
1815 strcmp(s,"r4") == 0 ||
1816 strcmp(s,"r5") == 0 ||
1817 strcmp(s,"r6") == 0 ||
1818 strcmp(s,"r7") == 0 ) {
1820 sprintf(buffer,"a%s",s);
1821 pic16_emitcode("mov","@%s,%s",
1822 aop->aopu.aop_ptr->name,buffer);
1824 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1829 if (strcmp(s,"a") == 0)
1830 pic16_emitcode("push","acc");
1832 pic16_emitcode("push","%s",s);
1837 /* if bit variable */
1838 if (!aop->aopu.aop_dir) {
1839 pic16_emitcode("clr","a");
1840 pic16_emitcode("rlc","a");
1843 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1846 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1849 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1851 lbl = newiTempLabel(NULL);
1853 if (strcmp(s,"a")) {
1856 pic16_emitcode("clr","c");
1857 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1858 pic16_emitcode("cpl","c");
1859 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1860 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1867 if (strcmp(aop->aopu.aop_str[offset],s))
1868 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1873 if (!offset && (strcmp(s,"acc") == 0))
1876 if (strcmp(aop->aopu.aop_str[offset],s))
1877 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1881 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1882 "pic16_aopPut got unsupported aop->type");
1888 /*-----------------------------------------------------------------*/
1889 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1890 /*-----------------------------------------------------------------*/
1891 static void mov2w (asmop *aop, int offset)
1897 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1899 if ( aop->type == AOP_PCODE ||
1900 aop->type == AOP_LIT )
1901 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1903 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1908 /* push pcop into stack */
1909 void pic16_pushpCodeOp(pCodeOp *pcop)
1911 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1915 /* pop pcop from stack */
1916 void pic16_poppCodeOp(pCodeOp *pcop)
1918 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1922 /*-----------------------------------------------------------------*/
1923 /* pushw - pushes wreg to stack */
1924 /*-----------------------------------------------------------------*/
1927 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1928 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1932 /*-----------------------------------------------------------------*/
1933 /* pushaop - pushes aop to stack */
1934 /*-----------------------------------------------------------------*/
1935 void pushaop(asmop *aop, int offset)
1937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1938 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1941 /*-----------------------------------------------------------------*/
1942 /* popaop - pops aop from stack */
1943 /*-----------------------------------------------------------------*/
1944 void popaop(asmop *aop, int offset)
1946 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1947 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1950 void popaopidx(asmop *aop, int offset, int index)
1954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1956 if(STACK_MODEL_LARGE)ofs++;
1958 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1959 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1962 /*-----------------------------------------------------------------*/
1963 /* reAdjustPreg - points a register back to where it should */
1964 /*-----------------------------------------------------------------*/
1965 static void reAdjustPreg (asmop *aop)
1969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1971 if ((size = aop->size) <= 1)
1974 switch (aop->type) {
1978 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1982 if (aop->type == AOP_DPTR2)
1988 pic16_emitcode("lcall","__decdptr");
1991 if (aop->type == AOP_DPTR2)
2003 /*-----------------------------------------------------------------*/
2004 /* opIsGptr: returns non-zero if the passed operand is */
2005 /* a generic pointer type. */
2006 /*-----------------------------------------------------------------*/
2007 static int opIsGptr(operand *op)
2009 sym_link *type = operandType(op);
2011 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2012 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2020 /*-----------------------------------------------------------------*/
2021 /* pic16_getDataSize - get the operand data size */
2022 /*-----------------------------------------------------------------*/
2023 int pic16_getDataSize(operand *op)
2025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2028 return AOP_SIZE(op);
2030 // tsd- in the pic port, the genptr size is 1, so this code here
2031 // fails. ( in the 8051 port, the size was 4).
2034 size = AOP_SIZE(op);
2035 if (size == GPTRSIZE)
2037 sym_link *type = operandType(op);
2038 if (IS_GENPTR(type))
2040 /* generic pointer; arithmetic operations
2041 * should ignore the high byte (pointer type).
2044 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2051 /*-----------------------------------------------------------------*/
2052 /* pic16_outAcc - output Acc */
2053 /*-----------------------------------------------------------------*/
2054 void pic16_outAcc(operand *result)
2057 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2058 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2061 size = pic16_getDataSize(result);
2063 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2066 /* unsigned or positive */
2068 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2073 /*-----------------------------------------------------------------*/
2074 /* pic16_outBitC - output a bit C */
2075 /*-----------------------------------------------------------------*/
2076 void pic16_outBitC(operand *result)
2079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2080 /* if the result is bit */
2081 if (AOP_TYPE(result) == AOP_CRY)
2082 pic16_aopPut(AOP(result),"c",0);
2084 pic16_emitcode("clr","a ; %d", __LINE__);
2085 pic16_emitcode("rlc","a");
2086 pic16_outAcc(result);
2090 /*-----------------------------------------------------------------*/
2091 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2092 /*-----------------------------------------------------------------*/
2093 void pic16_toBoolean(operand *oper)
2095 int size = AOP_SIZE(oper) - 1;
2098 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 if ( AOP_TYPE(oper) != AOP_ACC) {
2101 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2104 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2109 #if !defined(GEN_Not)
2110 /*-----------------------------------------------------------------*/
2111 /* genNot - generate code for ! operation */
2112 /*-----------------------------------------------------------------*/
2113 static void pic16_genNot (iCode *ic)
2118 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2119 /* assign asmOps to operand & result */
2120 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2121 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2123 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2124 /* if in bit space then a special case */
2125 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2126 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2127 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2128 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2130 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2131 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2132 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2137 size = AOP_SIZE(IC_LEFT(ic));
2139 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2140 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2141 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2144 pic16_toBoolean(IC_LEFT(ic));
2146 tlbl = newiTempLabel(NULL);
2147 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2148 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2149 pic16_outBitC(IC_RESULT(ic));
2152 /* release the aops */
2153 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2154 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2159 #if !defined(GEN_Cpl)
2160 /*-----------------------------------------------------------------*/
2161 /* genCpl - generate code for complement */
2162 /*-----------------------------------------------------------------*/
2163 static void pic16_genCpl (iCode *ic)
2169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2170 /* assign asmOps to operand & result */
2171 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2172 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2174 /* if both are in bit space then
2176 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2177 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2179 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2180 pic16_emitcode("cpl","c");
2181 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2185 size = AOP_SIZE(IC_RESULT(ic));
2188 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2190 pic16_emitcode("cpl","a");
2191 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2193 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2194 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2196 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2197 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2205 /* release the aops */
2206 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2207 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2211 /*-----------------------------------------------------------------*/
2212 /* genUminusFloat - unary minus for floating points */
2213 /*-----------------------------------------------------------------*/
2214 static void genUminusFloat(operand *op,operand *result)
2216 int size ,offset =0 ;
2219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2220 /* for this we just need to flip the
2221 first it then copy the rest in place */
2222 size = AOP_SIZE(op) - 1;
2223 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2227 pic16_emitcode("cpl","acc.7");
2228 pic16_aopPut(AOP(result),"a",3);
2231 pic16_aopPut(AOP(result),
2232 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2238 /*-----------------------------------------------------------------*/
2239 /* genUminus - unary minus code generation */
2240 /*-----------------------------------------------------------------*/
2241 static void genUminus (iCode *ic)
2244 sym_link *optype, *rtype;
2247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2249 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2250 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2252 /* if both in bit space then special
2254 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2255 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2257 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2258 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2259 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2264 optype = operandType(IC_LEFT(ic));
2265 rtype = operandType(IC_RESULT(ic));
2267 /* if float then do float stuff */
2268 if (IS_FLOAT(optype)) {
2269 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2273 /* otherwise subtract from zero by taking the 2's complement */
2274 size = AOP_SIZE(IC_LEFT(ic));
2276 for(i=0; i<size; i++) {
2277 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2278 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2280 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2285 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2286 for(i=1; i<size; i++) {
2288 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2292 /* release the aops */
2293 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2294 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2297 /*-----------------------------------------------------------------*/
2298 /* saveRegisters - will look for a call and save the registers */
2299 /*-----------------------------------------------------------------*/
2300 static void saveRegisters(iCode *lic)
2307 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2309 for (ic = lic ; ic ; ic = ic->next)
2310 if (ic->op == CALL || ic->op == PCALL)
2314 fprintf(stderr,"found parameter push with no function call\n");
2318 /* if the registers have been saved already then
2320 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2323 /* find the registers in use at this time
2324 and push them away to safety */
2325 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2329 if (options.useXstack) {
2330 if (bitVectBitValue(rsave,R0_IDX))
2331 pic16_emitcode("mov","b,r0");
2332 pic16_emitcode("mov","r0,%s",spname);
2333 for (i = 0 ; i < pic16_nRegs ; i++) {
2334 if (bitVectBitValue(rsave,i)) {
2336 pic16_emitcode("mov","a,b");
2338 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2339 pic16_emitcode("movx","@r0,a");
2340 pic16_emitcode("inc","r0");
2343 pic16_emitcode("mov","%s,r0",spname);
2344 if (bitVectBitValue(rsave,R0_IDX))
2345 pic16_emitcode("mov","r0,b");
2347 //for (i = 0 ; i < pic16_nRegs ; i++) {
2348 // if (bitVectBitValue(rsave,i))
2349 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2352 dtype = operandType(IC_LEFT(ic));
2353 if (currFunc && dtype &&
2354 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2355 IFFUNC_ISISR(currFunc->type) &&
2358 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2361 /*-----------------------------------------------------------------*/
2362 /* unsaveRegisters - pop the pushed registers */
2363 /*-----------------------------------------------------------------*/
2364 static void unsaveRegisters (iCode *ic)
2369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2370 /* find the registers in use at this time
2371 and push them away to safety */
2372 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2375 if (options.useXstack) {
2376 pic16_emitcode("mov","r0,%s",spname);
2377 for (i = pic16_nRegs ; i >= 0 ; i--) {
2378 if (bitVectBitValue(rsave,i)) {
2379 pic16_emitcode("dec","r0");
2380 pic16_emitcode("movx","a,@r0");
2382 pic16_emitcode("mov","b,a");
2384 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2388 pic16_emitcode("mov","%s,r0",spname);
2389 if (bitVectBitValue(rsave,R0_IDX))
2390 pic16_emitcode("mov","r0,b");
2392 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2393 // if (bitVectBitValue(rsave,i))
2394 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2400 /*-----------------------------------------------------------------*/
2402 /*-----------------------------------------------------------------*/
2403 static void pushSide(operand * oper, int size)
2406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2408 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2409 if (AOP_TYPE(oper) != AOP_REG &&
2410 AOP_TYPE(oper) != AOP_DIR &&
2412 pic16_emitcode("mov","a,%s",l);
2413 pic16_emitcode("push","acc");
2415 pic16_emitcode("push","%s",l);
2420 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2422 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2424 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2425 pic16_emitpcode(POC_MOVFW, src);
2426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2428 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2429 src, pic16_popGet(AOP(op), offset)));
2434 /*-----------------------------------------------------------------*/
2435 /* assignResultValue - assign results to oper, rescall==1 is */
2436 /* called from genCall() or genPCall() */
2437 /*-----------------------------------------------------------------*/
2438 static void assignResultValue(operand * oper, int rescall)
2440 int size = AOP_SIZE(oper);
2442 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2443 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2446 /* assign result from a call/pcall function() */
2448 /* function results are stored in a special order,
2449 * see top of file with Function return policy, or manual */
2452 /* 8-bits, result in WREG */
2453 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2456 /* 16-bits, result in PRODL:WREG */
2457 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2461 /* 24-bits, result in PRODH:PRODL:WREG */
2462 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2466 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2467 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2470 /* >32-bits, result on stack, and FSR0 points to beginning.
2471 * Fix stack when done */
2474 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2475 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2477 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2482 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2483 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2484 if(STACK_MODEL_LARGE) {
2486 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2490 if(!GpsuedoStkPtr) {
2491 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2492 /* The last byte in the assignment is in W */
2494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2499 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2500 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2502 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2510 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2520 /*-----------------------------------------------------------------*/
2521 /* genIpush - genrate code for pushing this gets a little complex */
2522 /*-----------------------------------------------------------------*/
2523 static void genIpush (iCode *ic)
2526 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2528 int size, offset = 0 ;
2532 /* if this is not a parm push : ie. it is spill push
2533 and spill push is always done on the local stack */
2534 if (!ic->parmPush) {
2536 /* and the item is spilt then do nothing */
2537 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2540 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2541 size = AOP_SIZE(IC_LEFT(ic));
2542 /* push it on the stack */
2544 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2549 pic16_emitcode("push","%s",l);
2554 /* this is a paramter push: in this case we call
2555 the routine to find the call and save those
2556 registers that need to be saved */
2559 /* then do the push */
2560 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2563 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2564 size = AOP_SIZE(IC_LEFT(ic));
2567 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2568 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2569 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2571 pic16_emitcode("mov","a,%s",l);
2572 pic16_emitcode("push","acc");
2574 pic16_emitcode("push","%s",l);
2577 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2581 /*-----------------------------------------------------------------*/
2582 /* genIpop - recover the registers: can happen only for spilling */
2583 /*-----------------------------------------------------------------*/
2584 static void genIpop (iCode *ic)
2586 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2591 /* if the temp was not pushed then */
2592 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2595 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2596 size = AOP_SIZE(IC_LEFT(ic));
2599 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2602 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2606 /*-----------------------------------------------------------------*/
2607 /* unsaverbank - restores the resgister bank from stack */
2608 /*-----------------------------------------------------------------*/
2609 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2611 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2617 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2619 if (options.useXstack) {
2621 r = getFreePtr(ic,&aop,FALSE);
2624 pic16_emitcode("mov","%s,_spx",r->name);
2625 pic16_emitcode("movx","a,@%s",r->name);
2626 pic16_emitcode("mov","psw,a");
2627 pic16_emitcode("dec","%s",r->name);
2630 pic16_emitcode ("pop","psw");
2633 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2634 if (options.useXstack) {
2635 pic16_emitcode("movx","a,@%s",r->name);
2636 //pic16_emitcode("mov","(%s+%d),a",
2637 // regspic16[i].base,8*bank+regspic16[i].offset);
2638 pic16_emitcode("dec","%s",r->name);
2641 pic16_emitcode("pop",""); //"(%s+%d)",
2642 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2645 if (options.useXstack) {
2647 pic16_emitcode("mov","_spx,%s",r->name);
2648 pic16_freeAsmop(NULL,aop,ic,TRUE);
2654 /*-----------------------------------------------------------------*/
2655 /* saverbank - saves an entire register bank on the stack */
2656 /*-----------------------------------------------------------------*/
2657 static void saverbank (int bank, iCode *ic, bool pushPsw)
2659 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2666 if (options.useXstack) {
2669 r = getFreePtr(ic,&aop,FALSE);
2670 pic16_emitcode("mov","%s,_spx",r->name);
2674 for (i = 0 ; i < pic16_nRegs ;i++) {
2675 if (options.useXstack) {
2676 pic16_emitcode("inc","%s",r->name);
2677 //pic16_emitcode("mov","a,(%s+%d)",
2678 // regspic16[i].base,8*bank+regspic16[i].offset);
2679 pic16_emitcode("movx","@%s,a",r->name);
2681 pic16_emitcode("push","");// "(%s+%d)",
2682 //regspic16[i].base,8*bank+regspic16[i].offset);
2686 if (options.useXstack) {
2687 pic16_emitcode("mov","a,psw");
2688 pic16_emitcode("movx","@%s,a",r->name);
2689 pic16_emitcode("inc","%s",r->name);
2690 pic16_emitcode("mov","_spx,%s",r->name);
2691 pic16_freeAsmop (NULL,aop,ic,TRUE);
2694 pic16_emitcode("push","psw");
2696 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2704 /*-----------------------------------------------------------------*/
2705 /* genCall - generates a call statement */
2706 /*-----------------------------------------------------------------*/
2707 static void genCall (iCode *ic)
2712 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2714 /* if caller saves & we have not saved then */
2718 /* if we are calling a function that is not using
2719 * the same register bank then we need to save the
2720 * destination registers on the stack */
2721 dtype = operandType(IC_LEFT(ic));
2722 if (currFunc && dtype &&
2723 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2724 IFFUNC_ISISR(currFunc->type) &&
2727 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2729 /* if send set is not empty the assign */
2733 /* For the Pic port, there is no data stack.
2734 * So parameters passed to functions are stored
2735 * in registers. (The pCode optimizer will get
2736 * rid of most of these :). */
2738 int psuedoStkPtr=-1;
2739 int firstTimeThruLoop = 1;
2741 _G.sendSet = reverseSet(_G.sendSet);
2743 /* First figure how many parameters are getting passed */
2744 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2745 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2746 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2747 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2750 stackParms = psuedoStkPtr;
2752 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2753 int size, offset = 0;
2755 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2756 size = AOP_SIZE(IC_LEFT(sic));
2759 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2760 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2761 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2763 if(!firstTimeThruLoop) {
2764 /* If this is not the first time we've been through the loop
2765 * then we need to save the parameter in a temporary
2766 * register. The last byte of the last parameter is
2770 --psuedoStkPtr; // sanity check
2773 firstTimeThruLoop=0;
2775 mov2w (AOP(IC_LEFT(sic)), offset);
2778 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2784 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2785 OP_SYMBOL(IC_LEFT(ic))->rname :
2786 OP_SYMBOL(IC_LEFT(ic))->name));
2789 /* if we need assign a result value */
2790 if ((IS_ITEMP(IC_RESULT(ic)) &&
2791 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2792 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2793 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2796 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2799 assignResultValue(IC_RESULT(ic), 1);
2801 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2802 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2804 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2808 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2809 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2810 if(STACK_MODEL_LARGE) {
2812 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2816 /* adjust the stack for parameters if required */
2817 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2819 if (ic->parmBytes) {
2822 if (ic->parmBytes > 3) {
2823 pic16_emitcode("mov","a,%s",spname);
2824 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2825 pic16_emitcode("mov","%s,a",spname);
2827 for ( i = 0 ; i < ic->parmBytes ;i++)
2828 pic16_emitcode("dec","%s",spname);
2832 /* if register bank was saved then pop them */
2834 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2836 /* if we hade saved some registers then unsave them */
2837 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2838 unsaveRegisters (ic);
2844 /*-----------------------------------------------------------------*/ // patch 14
2845 /* genPcall - generates a call by pointer statement */
2846 /*-----------------------------------------------------------------*/
2848 // new version, created from genCall
2850 static void genPcall (iCode *ic)
2854 symbol *retlbl = newiTempLabel(NULL);
2855 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
2857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2859 /* if caller saves & we have not saved then */
2863 /* if we are calling a function that is not using
2864 * the same register bank then we need to save the
2865 * destination registers on the stack */
2866 dtype = operandType(IC_LEFT(ic));
2867 if (currFunc && dtype &&
2868 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2869 IFFUNC_ISISR(currFunc->type) &&
2872 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2874 /* if send set is not empty the assign */
2878 /* For the Pic port, there is no data stack.
2879 * So parameters passed to functions are stored
2880 * in registers. (The pCode optimizer will get
2881 * rid of most of these :). */
2883 int psuedoStkPtr=-1;
2884 int firstTimeThruLoop = 1;
2886 _G.sendSet = reverseSet(_G.sendSet);
2888 /* First figure how many parameters are getting passed */
2889 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2890 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2891 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2892 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2895 stackParms = psuedoStkPtr;
2897 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2898 int size, offset = 0;
2900 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2901 size = AOP_SIZE(IC_LEFT(sic));
2904 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2905 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2906 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2908 if(!firstTimeThruLoop) {
2909 /* If this is not the first time we've been through the loop
2910 * then we need to save the parameter in a temporary
2911 * register. The last byte of the last parameter is
2915 --psuedoStkPtr; // sanity check
2918 firstTimeThruLoop=0;
2920 mov2w (AOP(IC_LEFT(sic)), offset);
2923 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2928 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2930 // push return address
2931 // push $ on return stack, then replace with retlbl
2933 // Note: retlbl is supplied as dummy operand to PUSH
2934 // This has the nice side effect of keeping the label from being optimized out :o)
2935 pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key));
2937 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
2938 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
2939 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
2940 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
2941 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
2942 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
2944 /* make the call by writing the pointer into pc */
2945 // FIXME Disabled writes to PCLATU because of gpsim problems
2947 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
2950 "WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
2951 Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
2954 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
2955 // note: MOVFF to PCL not allowed
2956 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
2957 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
2959 /* return address is here: (X) */
2960 pic16_emitpLabel(retlbl->key);
2962 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2965 /* if we need assign a result value */
2966 if ((IS_ITEMP(IC_RESULT(ic)) &&
2967 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2968 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2969 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2972 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2975 assignResultValue(IC_RESULT(ic), 1);
2977 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2978 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2980 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2984 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2985 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2986 if(STACK_MODEL_LARGE) {
2988 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2992 /* adjust the stack for parameters if required */
2993 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2995 if (ic->parmBytes) {
2998 if (ic->parmBytes > 3) {
2999 pic16_emitcode("mov","a,%s",spname);
3000 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3001 pic16_emitcode("mov","%s,a",spname);
3003 for ( i = 0 ; i < ic->parmBytes ;i++)
3004 pic16_emitcode("dec","%s",spname);
3007 /* if register bank was saved then pop them */
3009 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3011 /* if we hade saved some registers then unsave them */
3012 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3013 unsaveRegisters (ic);
3018 // old version, kept for reference
3020 /*-----------------------------------------------------------------*/
3021 /* genPcall - generates a call by pointer statement */
3022 /*-----------------------------------------------------------------*/
3023 static void genPcall (iCode *ic)
3026 symbol *rlbl = newiTempLabel(NULL);
3029 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3030 /* if caller saves & we have not saved then */
3034 /* if we are calling a function that is not using
3035 the same register bank then we need to save the
3036 destination registers on the stack */
3037 dtype = operandType(IC_LEFT(ic));
3038 if (currFunc && dtype &&
3039 IFFUNC_ISISR(currFunc->type) &&
3040 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3041 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3044 /* push the return address on to the stack */
3045 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
3046 pic16_emitcode("push","acc");
3047 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
3048 pic16_emitcode("push","acc");
3050 if (options.model == MODEL_FLAT24)
3052 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
3053 pic16_emitcode("push","acc");
3056 /* now push the calling address */
3057 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3059 pushSide(IC_LEFT(ic), FPTRSIZE);
3061 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3063 /* if send set is not empty the assign */
3067 for (sic = setFirstItem(_G.sendSet) ; sic ;
3068 sic = setNextItem(_G.sendSet)) {
3069 int size, offset = 0;
3070 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3071 size = AOP_SIZE(IC_LEFT(sic));
3073 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
3075 if (strcmp(l,fReturn[offset]))
3076 pic16_emitcode("mov","%s,%s",
3081 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3086 pic16_emitcode("ret","");
3087 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
3090 /* if we need assign a result value */
3091 if ((IS_ITEMP(IC_RESULT(ic)) &&
3092 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3093 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
3094 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3097 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3100 assignResultValue(IC_RESULT(ic), 1);
3102 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3105 /* adjust the stack for parameters if
3107 if (ic->parmBytes) {
3109 if (ic->parmBytes > 3) {
3110 pic16_emitcode("mov","a,%s",spname);
3111 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3112 pic16_emitcode("mov","%s,a",spname);
3114 for ( i = 0 ; i < ic->parmBytes ;i++)
3115 pic16_emitcode("dec","%s",spname);
3119 /* if register bank was saved then unsave them */
3120 if (currFunc && dtype &&
3121 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3122 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3124 /* if we hade saved some registers then
3127 unsaveRegisters (ic);
3133 /*-----------------------------------------------------------------*/
3134 /* resultRemat - result is rematerializable */
3135 /*-----------------------------------------------------------------*/
3136 static int resultRemat (iCode *ic)
3138 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3139 if (SKIP_IC(ic) || ic->op == IFX)
3142 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3143 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3144 if (sym->remat && !POINTER_SET(ic))
3151 #if defined(__BORLANDC__) || defined(_MSC_VER)
3152 #define STRCASECMP stricmp
3154 #define STRCASECMP strcasecmp
3158 /*-----------------------------------------------------------------*/
3159 /* inExcludeList - return 1 if the string is in exclude Reg list */
3160 /*-----------------------------------------------------------------*/
3161 static bool inExcludeList(char *s)
3163 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3167 if (options.excludeRegs[i] &&
3168 STRCASECMP(options.excludeRegs[i],"none") == 0)
3171 for ( i = 0 ; options.excludeRegs[i]; i++) {
3172 if (options.excludeRegs[i] &&
3173 STRCASECMP(s,options.excludeRegs[i]) == 0)
3180 /*-----------------------------------------------------------------*/
3181 /* genFunction - generated code for function entry */
3182 /*-----------------------------------------------------------------*/
3183 static void genFunction (iCode *ic)
3188 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
3190 labelOffset += (max_key+4);
3195 ftype = operandType(IC_LEFT(ic));
3196 sym = OP_SYMBOL(IC_LEFT(ic));
3198 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3199 /* create an absolute section at the interrupt vector:
3200 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3208 sym = OP_SYMBOL( IC_LEFT(ic));
3210 if(interrupts[i]->name
3211 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3218 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3219 __FILE__, __LINE__, sym->name);
3222 _G.interruptvector = found;
3225 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3226 asym = newSymbol(asymname, 0);
3228 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3229 pic16_addpBlock( apb );
3231 pic16_addpCode2pBlock(apb,
3232 pic16_newpCodeCharP(";-----------------------------------------"));
3235 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3237 pic16_addpCode2pBlock(apb,
3238 pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3240 /* mark the end of this tiny function */
3241 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3246 abSym = Safe_calloc(1, sizeof(absSym));
3247 abSym->name = Safe_strdup( asymname );
3249 switch( _G.interruptvector ) {
3250 case 0: abSym->address = 0x000000; break;
3251 case 1: abSym->address = 0x000008; break;
3252 case 2: abSym->address = 0x000018; break;
3255 addSet(&absSymSet, abSym);
3260 /* create the function header */
3261 pic16_emitcode(";","-----------------------------------------");
3262 pic16_emitcode(";"," function %s",sym->name);
3263 pic16_emitcode(";","-----------------------------------------");
3265 pic16_emitcode("","%s:",sym->rname);
3266 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3272 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3273 if(!strcmp(ab->name, sym->name)) {
3274 pic16_pBlockConvert2Absolute(pb);
3281 if(IFFUNC_ISNAKED(ftype)) {
3282 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3286 /* if critical function then turn interrupts off */
3287 if (IFFUNC_ISCRITICAL(ftype))
3288 pic16_emitcode("clr","ea");
3290 /* if this is an interrupt service routine then
3291 * save acc, b, dpl, dph */
3292 if (IFFUNC_ISISR(sym->type)) {
3294 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3295 if(!(_G.interruptvector == 1)) {
3297 /* do not save WREG,STATUS,BSR for high priority interrupts
3298 * because they are stored in the hardware shadow registers already */
3300 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3301 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3302 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3305 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3306 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3307 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3308 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3310 // pic16_pBlockConvert2ISR(pb);
3312 /* if any registers used */
3313 if (sym->regsUsed) {
3314 /* save the registers used */
3315 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3316 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3317 if (bitVectBitValue(sym->regsUsed,i)) {
3318 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3319 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3320 // pic16_regWithIdx(i)->name);
3322 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3328 /* emit code to setup stack frame if user enabled,
3329 * and function is not main() */
3331 // fprintf(stderr, "function name: %s\n", sym->name);
3332 if(strcmp(sym->name, "main")) {
3333 if(/*!options.ommitFramePtr || */sym->regsUsed) {
3334 /* setup the stack frame */
3335 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3336 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3337 if(STACK_MODEL_LARGE)
3338 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3342 /* if callee-save to be used for this function
3343 * then save the registers being used in this function */
3344 // if (IFFUNC_CALLEESAVES(sym->type))
3348 // fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
3350 // pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3352 /* if any registers used */
3353 if (sym->regsUsed) {
3354 /* save the registers used */
3355 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3356 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3357 if (bitVectBitValue(sym->regsUsed,i)) {
3359 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3360 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3361 // pic16_regWithIdx(i)->name);
3363 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3365 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3366 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3367 // &pic16_pc_postdec1, 0));
3379 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3381 if (options.useXstack) {
3382 pic16_emitcode("mov","r0,%s",spname);
3383 pic16_emitcode("mov","a,_bp");
3384 pic16_emitcode("movx","@r0,a");
3385 pic16_emitcode("inc","%s",spname);
3387 /* set up the stack */
3388 pic16_emitcode ("push","_bp"); /* save the callers stack */
3390 pic16_emitcode ("mov","_bp,%s",spname);
3393 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3395 /* adjust the stack for the function */
3400 werror(W_STACK_OVERFLOW,sym->name);
3402 if (i > 3 && sym->recvSize < 4) {
3403 pic16_emitcode ("mov","a,sp");
3404 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3405 pic16_emitcode ("mov","sp,a");
3408 pic16_emitcode("inc","sp");
3412 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3414 pic16_emitcode ("mov","a,_spx");
3415 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3416 pic16_emitcode ("mov","_spx,a");
3421 /*-----------------------------------------------------------------*/
3422 /* genEndFunction - generates epilogue for functions */
3423 /*-----------------------------------------------------------------*/
3424 static void genEndFunction (iCode *ic)
3426 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3430 if(IFFUNC_ISNAKED(sym->type)) {
3431 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3436 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3438 pic16_emitcode ("mov","%s,_bp",spname);
3442 /* if use external stack but some variables were
3443 added to the local stack then decrement the
3445 if (options.useXstack && sym->stack) {
3446 pic16_emitcode("mov","a,sp");
3447 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3448 pic16_emitcode("mov","sp,a");
3453 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3454 if (options.useXstack) {
3455 pic16_emitcode("mov","r0,%s",spname);
3456 pic16_emitcode("movx","a,@r0");
3457 pic16_emitcode("mov","_bp,a");
3458 pic16_emitcode("dec","%s",spname);
3462 pic16_emitcode ("pop","_bp");
3467 if (IFFUNC_ISISR(sym->type)) {
3468 /* now we need to restore the registers */
3469 /* if any registers used */
3470 if (sym->regsUsed) {
3473 /* restore registers used */
3474 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3475 for ( i = sym->regsUsed->size; i >= 0; i--) {
3476 if (bitVectBitValue(sym->regsUsed,i)) {
3478 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3479 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3480 // pic16_regWithIdx(i)->name);
3482 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3484 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3485 // &pic16_pc_preinc1,
3486 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3492 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3493 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3494 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3495 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3497 if(!(_G.interruptvector == 1)) {
3498 /* do not restore interrupt vector for WREG,STATUS,BSR
3499 * for high priority interrupt, see genFunction */
3501 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3502 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3503 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3506 _G.interruptvector = 0; /* sanity check */
3508 // pic16_pBlockConvert2ISR(pb);
3511 /* if debug then send end of function */
3512 /* if (options.debug && currFunc) */
3515 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3516 FileBaseName(ic->filename),currFunc->lastLine,
3517 ic->level,ic->block);
3518 if (IS_STATIC(currFunc->etype))
3519 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3521 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3525 pic16_emitpcodeNULLop(POC_RETFIE);
3527 if (IFFUNC_ISCRITICAL(sym->type))
3528 pic16_emitcode("setb","ea");
3531 // pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3533 /* if any registers used */
3534 if (sym->regsUsed) {
3536 /* save the registers used */
3537 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3538 for ( i = sym->regsUsed->size; i >= 0; i--) {
3539 if (bitVectBitValue(sym->regsUsed,i)) {
3541 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3542 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3543 // pic16_regWithIdx(i)->name);
3545 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3547 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3548 // &pic16_pc_preinc1,
3549 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3556 pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
3557 /* if debug then send end of function */
3560 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3561 FileBaseName(ic->filename),currFunc->lastLine,
3562 ic->level,ic->block);
3563 if (IS_STATIC(currFunc->etype))
3564 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3566 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3570 /* insert code to restore stack frame, if user enabled it
3571 * and function is not main() */
3574 if(strcmp(sym->name, "main")) {
3575 if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
3576 /* restore stack frame */
3577 if(STACK_MODEL_LARGE)
3578 pic16_emitpcode(POC_MOVFF,
3579 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3580 pic16_emitpcode(POC_MOVFF,
3581 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3585 pic16_emitcode ("return","");
3586 pic16_emitpcodeNULLop(POC_RETURN);
3588 /* Mark the end of a function */
3589 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3595 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3597 // (AOP(left)->aopu.pcop->type == PO_DIR)?
3599 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3600 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
3601 pic16_emitpcode(POC_MOVWF, dest);
3603 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3604 pic16_popGet(AOP(op), offset), dest));
3608 /*-----------------------------------------------------------------*/
3609 /* genRet - generate code for return statement */
3610 /*-----------------------------------------------------------------*/
3611 static void genRet (iCode *ic)
3616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3617 /* if we have no return value then
3618 * just generate the "ret" */
3623 /* we have something to return then
3624 * move the return value into place */
3625 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3626 size = AOP_SIZE(IC_LEFT(ic));
3630 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3631 // pic16_emitpcode(POC_MOVFF,
3632 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3635 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3636 // pic16_emitpcode(POC_MOVFF,
3637 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3640 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3641 // pic16_emitpcode(POC_MOVFF,
3642 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3645 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3647 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3648 // pic16_emitpcode(POC_MOVFF,
3649 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3652 /* >32-bits, setup stack and FSR0 */
3654 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3655 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3657 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3659 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3664 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3665 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3667 if(STACK_MODEL_LARGE) {
3668 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3669 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3671 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3676 /* old code, left here for reference -- VR */
3680 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3682 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3683 pic16_emitpcomment("push %s",l);
3686 DEBUGpic16_emitcode(";", "%d", __LINE__);
3687 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3688 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3690 if (strcmp(fReturn[offset],l)) {
3691 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3692 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3693 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3695 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3699 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3709 if (strcmp(fReturn[pushed],"a"))
3710 pic16_emitcode("pop",fReturn[pushed]);
3712 pic16_emitcode("pop","acc");
3718 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3721 /* generate a jump to the return label
3722 * if the next is not the return statement */
3723 if (!(ic->next && ic->next->op == LABEL
3724 && IC_LABEL(ic->next) == returnLabel)) {
3726 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3727 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3731 /*-----------------------------------------------------------------*/
3732 /* genLabel - generates a label */
3733 /*-----------------------------------------------------------------*/
3734 static void genLabel (iCode *ic)
3738 /* special case never generate */
3739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3740 if (IC_LABEL(ic) == entryLabel)
3743 pic16_emitpLabel(IC_LABEL(ic)->key);
3744 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3747 /*-----------------------------------------------------------------*/
3748 /* genGoto - generates a goto */
3749 /*-----------------------------------------------------------------*/
3751 static void genGoto (iCode *ic)
3753 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3754 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3758 /*-----------------------------------------------------------------*/
3759 /* genMultbits :- multiplication of bits */
3760 /*-----------------------------------------------------------------*/
3761 static void genMultbits (operand *left,
3765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3767 if(!pic16_sameRegs(AOP(result),AOP(right)))
3768 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3770 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3771 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3772 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3777 /*-----------------------------------------------------------------*/
3778 /* genMultOneByte : 8 bit multiplication & division */
3779 /*-----------------------------------------------------------------*/
3780 static void genMultOneByte (operand *left,
3785 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3786 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3787 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3789 /* (if two literals, the value is computed before) */
3790 /* if one literal, literal on the right */
3791 if (AOP_TYPE(left) == AOP_LIT){
3797 /* size is already checked in genMult == 1 */
3798 // size = AOP_SIZE(result);
3800 if (AOP_TYPE(right) == AOP_LIT){
3801 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3802 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3803 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3804 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3806 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3807 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3808 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3809 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3812 pic16_genMult8X8_8 (left, right,result);
3816 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3817 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3818 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3819 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3821 if (SPEC_USIGN(opetype)){
3822 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3823 pic16_genUMult8X8_16 (left, right, result, NULL);
3826 /* for filling the MSBs */
3827 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3828 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3832 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3834 pic16_emitcode("mov","a,b");
3836 /* adjust the MSB if left or right neg */
3838 /* if one literal */
3839 if (AOP_TYPE(right) == AOP_LIT){
3840 pic16_emitcode("multiply ","right is a lit");
3841 /* AND literal negative */
3842 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3843 /* adjust MSB (c==0 after mul) */
3844 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3848 pic16_genSMult8X8_16 (left, right, result, NULL);
3852 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3854 pic16_emitcode("rlc","a");
3855 pic16_emitcode("subb","a,acc");
3863 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3864 //pic16_aopPut(AOP(result),"a",offset++);
3871 /*-----------------------------------------------------------------*/
3872 /* genMultOneWord : 16 bit multiplication */
3873 /*-----------------------------------------------------------------*/
3874 static void genMultOneWord (operand *left,
3879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3880 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3881 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3883 /* (if two literals, the value is computed before)
3884 * if one literal, literal on the right */
3885 if (AOP_TYPE(left) == AOP_LIT){
3891 /* size is checked already == 2 */
3892 // size = AOP_SIZE(result);
3894 if (AOP_TYPE(right) == AOP_LIT) {
3895 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3896 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3897 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3898 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3900 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3901 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3902 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3903 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3906 pic16_genMult16X16_16(left, right,result);
3909 /*-----------------------------------------------------------------*/
3910 /* genMultOneLong : 32 bit multiplication */
3911 /*-----------------------------------------------------------------*/
3912 static void genMultOneLong (operand *left,
3917 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3918 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3919 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3921 /* (if two literals, the value is computed before)
3922 * if one literal, literal on the right */
3923 if (AOP_TYPE(left) == AOP_LIT){
3929 /* size is checked already == 4 */
3930 // size = AOP_SIZE(result);
3932 if (AOP_TYPE(right) == AOP_LIT) {
3933 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3934 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3935 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3936 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3938 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3939 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3940 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3941 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3944 pic16_genMult32X32_32(left, right,result);
3949 /*-----------------------------------------------------------------*/
3950 /* genMult - generates code for multiplication */
3951 /*-----------------------------------------------------------------*/
3952 static void genMult (iCode *ic)
3954 operand *left = IC_LEFT(ic);
3955 operand *right = IC_RIGHT(ic);
3956 operand *result= IC_RESULT(ic);
3958 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3959 /* assign the amsops */
3960 pic16_aopOp (left,ic,FALSE);
3961 pic16_aopOp (right,ic,FALSE);
3962 pic16_aopOp (result,ic,TRUE);
3964 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3966 /* special cases first *
3968 if (AOP_TYPE(left) == AOP_CRY
3969 && AOP_TYPE(right)== AOP_CRY) {
3970 genMultbits(left,right,result);
3974 /* if both are of size == 1 */
3975 if(AOP_SIZE(left) == 1
3976 && AOP_SIZE(right) == 1) {
3977 genMultOneByte(left,right,result);
3981 /* if both are of size == 2 */
3982 if(AOP_SIZE(left) == 2
3983 && AOP_SIZE(right) == 2) {
3984 genMultOneWord(left, right, result);
3988 /* if both are of size == 4 */
3989 if(AOP_SIZE(left) == 4
3990 && AOP_SIZE(right) == 4) {
3991 genMultOneLong(left, right, result);
3995 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
3998 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
3999 /* should have been converted to function call */
4003 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4004 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4005 pic16_freeAsmop(result,NULL,ic,TRUE);
4008 /*-----------------------------------------------------------------*/
4009 /* genDivbits :- division of bits */
4010 /*-----------------------------------------------------------------*/
4011 static void genDivbits (operand *left,
4018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4019 /* the result must be bit */
4020 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4021 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4025 pic16_emitcode("div","ab");
4026 pic16_emitcode("rrc","a");
4027 pic16_aopPut(AOP(result),"c",0);
4030 /*-----------------------------------------------------------------*/
4031 /* genDivOneByte : 8 bit division */
4032 /*-----------------------------------------------------------------*/
4033 static void genDivOneByte (operand *left,
4037 sym_link *opetype = operandType(result);
4042 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4043 size = AOP_SIZE(result) - 1;
4045 /* signed or unsigned */
4046 if (SPEC_USIGN(opetype)) {
4047 /* unsigned is easy */
4048 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4049 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4051 pic16_emitcode("div","ab");
4052 pic16_aopPut(AOP(result),"a",0);
4054 pic16_aopPut(AOP(result),zero,offset++);
4058 /* signed is a little bit more difficult */
4060 /* save the signs of the operands */
4061 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4063 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4064 pic16_emitcode("push","acc"); /* save it on the stack */
4066 /* now sign adjust for both left & right */
4067 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4069 lbl = newiTempLabel(NULL);
4070 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4071 pic16_emitcode("cpl","a");
4072 pic16_emitcode("inc","a");
4073 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4074 pic16_emitcode("mov","b,a");
4076 /* sign adjust left side */
4077 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4080 lbl = newiTempLabel(NULL);
4081 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4082 pic16_emitcode("cpl","a");
4083 pic16_emitcode("inc","a");
4084 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4086 /* now the division */
4087 pic16_emitcode("div","ab");
4088 /* we are interested in the lower order
4090 pic16_emitcode("mov","b,a");
4091 lbl = newiTempLabel(NULL);
4092 pic16_emitcode("pop","acc");
4093 /* if there was an over flow we don't
4094 adjust the sign of the result */
4095 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4096 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4098 pic16_emitcode("clr","a");
4099 pic16_emitcode("subb","a,b");
4100 pic16_emitcode("mov","b,a");
4101 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4103 /* now we are done */
4104 pic16_aopPut(AOP(result),"b",0);
4106 pic16_emitcode("mov","c,b.7");
4107 pic16_emitcode("subb","a,acc");
4110 pic16_aopPut(AOP(result),"a",offset++);
4114 /*-----------------------------------------------------------------*/
4115 /* genDiv - generates code for division */
4116 /*-----------------------------------------------------------------*/
4117 static void genDiv (iCode *ic)
4119 operand *left = IC_LEFT(ic);
4120 operand *right = IC_RIGHT(ic);
4121 operand *result= IC_RESULT(ic);
4123 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4124 /* assign the amsops */
4125 pic16_aopOp (left,ic,FALSE);
4126 pic16_aopOp (right,ic,FALSE);
4127 pic16_aopOp (result,ic,TRUE);
4129 /* special cases first */
4131 if (AOP_TYPE(left) == AOP_CRY &&
4132 AOP_TYPE(right)== AOP_CRY) {
4133 genDivbits(left,right,result);
4137 /* if both are of size == 1 */
4138 if (AOP_SIZE(left) == 1 &&
4139 AOP_SIZE(right) == 1 ) {
4140 genDivOneByte(left,right,result);
4144 /* should have been converted to function call */
4147 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4148 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4149 pic16_freeAsmop(result,NULL,ic,TRUE);
4152 /*-----------------------------------------------------------------*/
4153 /* genModbits :- modulus of bits */
4154 /*-----------------------------------------------------------------*/
4155 static void genModbits (operand *left,
4162 /* the result must be bit */
4163 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4164 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4168 pic16_emitcode("div","ab");
4169 pic16_emitcode("mov","a,b");
4170 pic16_emitcode("rrc","a");
4171 pic16_aopPut(AOP(result),"c",0);
4174 /*-----------------------------------------------------------------*/
4175 /* genModOneByte : 8 bit modulus */
4176 /*-----------------------------------------------------------------*/
4177 static void genModOneByte (operand *left,
4181 sym_link *opetype = operandType(result);
4185 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4186 /* signed or unsigned */
4187 if (SPEC_USIGN(opetype)) {
4188 /* unsigned is easy */
4189 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4190 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4192 pic16_emitcode("div","ab");
4193 pic16_aopPut(AOP(result),"b",0);
4197 /* signed is a little bit more difficult */
4199 /* save the signs of the operands */
4200 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4203 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4204 pic16_emitcode("push","acc"); /* save it on the stack */
4206 /* now sign adjust for both left & right */
4207 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4210 lbl = newiTempLabel(NULL);
4211 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4212 pic16_emitcode("cpl","a");
4213 pic16_emitcode("inc","a");
4214 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4215 pic16_emitcode("mov","b,a");
4217 /* sign adjust left side */
4218 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4221 lbl = newiTempLabel(NULL);
4222 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4223 pic16_emitcode("cpl","a");
4224 pic16_emitcode("inc","a");
4225 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4227 /* now the multiplication */
4228 pic16_emitcode("div","ab");
4229 /* we are interested in the lower order
4231 lbl = newiTempLabel(NULL);
4232 pic16_emitcode("pop","acc");
4233 /* if there was an over flow we don't
4234 adjust the sign of the result */
4235 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4236 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4238 pic16_emitcode("clr","a");
4239 pic16_emitcode("subb","a,b");
4240 pic16_emitcode("mov","b,a");
4241 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4243 /* now we are done */
4244 pic16_aopPut(AOP(result),"b",0);
4248 /*-----------------------------------------------------------------*/
4249 /* genMod - generates code for division */
4250 /*-----------------------------------------------------------------*/
4251 static void genMod (iCode *ic)
4253 operand *left = IC_LEFT(ic);
4254 operand *right = IC_RIGHT(ic);
4255 operand *result= IC_RESULT(ic);
4257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4258 /* assign the amsops */
4259 pic16_aopOp (left,ic,FALSE);
4260 pic16_aopOp (right,ic,FALSE);
4261 pic16_aopOp (result,ic,TRUE);
4263 /* special cases first */
4265 if (AOP_TYPE(left) == AOP_CRY &&
4266 AOP_TYPE(right)== AOP_CRY) {
4267 genModbits(left,right,result);
4271 /* if both are of size == 1 */
4272 if (AOP_SIZE(left) == 1 &&
4273 AOP_SIZE(right) == 1 ) {
4274 genModOneByte(left,right,result);
4278 /* should have been converted to function call */
4282 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4283 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4284 pic16_freeAsmop(result,NULL,ic,TRUE);
4287 /*-----------------------------------------------------------------*/
4288 /* genIfxJump :- will create a jump depending on the ifx */
4289 /*-----------------------------------------------------------------*/
4291 note: May need to add parameter to indicate when a variable is in bit space.
4293 static void genIfxJump (iCode *ic, char *jval)
4296 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4297 /* if true label then we jump if condition
4299 if ( IC_TRUE(ic) ) {
4301 if(strcmp(jval,"a") == 0)
4303 else if (strcmp(jval,"c") == 0)
4306 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4307 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
4310 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4311 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
4315 /* false label is present */
4316 if(strcmp(jval,"a") == 0)
4318 else if (strcmp(jval,"c") == 0)
4321 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4322 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
4325 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4326 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
4331 /* mark the icode as generated */
4338 /*-----------------------------------------------------------------*/
4340 /*-----------------------------------------------------------------*/
4341 static void genSkip(iCode *ifx,int status_bit)
4343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4347 if ( IC_TRUE(ifx) ) {
4348 switch(status_bit) {
4363 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4364 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4368 switch(status_bit) {
4382 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4383 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4390 /*-----------------------------------------------------------------*/
4392 /*-----------------------------------------------------------------*/
4393 static void genSkipc(resolvedIfx *rifx)
4395 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4405 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4406 rifx->generated = 1;
4409 /*-----------------------------------------------------------------*/
4411 /*-----------------------------------------------------------------*/
4412 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4414 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4419 if( (rifx->condition ^ invert_condition) & 1)
4424 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4425 rifx->generated = 1;
4429 /*-----------------------------------------------------------------*/
4431 /*-----------------------------------------------------------------*/
4432 static void genSkipz(iCode *ifx, int condition)
4443 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4445 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4448 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4450 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4455 /*-----------------------------------------------------------------*/
4457 /*-----------------------------------------------------------------*/
4458 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4464 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4466 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4469 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4470 rifx->generated = 1;
4474 /*-----------------------------------------------------------------*/
4475 /* genChkZeroes :- greater or less than comparison */
4476 /* For each byte in a literal that is zero, inclusive or the */
4477 /* the corresponding byte in the operand with W */
4478 /* returns true if any of the bytes are zero */
4479 /*-----------------------------------------------------------------*/
4480 static int genChkZeroes(operand *op, int lit, int size)
4487 i = (lit >> (size*8)) & 0xff;
4491 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4493 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4502 /*-----------------------------------------------------------------*/
4503 /* genCmp :- greater or less than comparison */
4504 /*-----------------------------------------------------------------*/
4505 static void genCmp (operand *left,operand *right,
4506 operand *result, iCode *ifx, int sign)
4508 int size; //, offset = 0 ;
4509 unsigned long lit = 0L,i = 0;
4510 resolvedIfx rFalseIfx;
4511 // resolvedIfx rTrueIfx;
4513 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4516 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4517 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4521 resolveIfx(&rFalseIfx,ifx);
4522 truelbl = newiTempLabel(NULL);
4523 size = max(AOP_SIZE(left),AOP_SIZE(right));
4525 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4529 /* if literal is on the right then swap with left */
4530 if ((AOP_TYPE(right) == AOP_LIT)) {
4531 operand *tmp = right ;
4532 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4533 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4536 lit = (lit - 1) & mask;
4539 rFalseIfx.condition ^= 1;
4542 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4543 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4547 //if(IC_TRUE(ifx) == NULL)
4548 /* if left & right are bit variables */
4549 if (AOP_TYPE(left) == AOP_CRY &&
4550 AOP_TYPE(right) == AOP_CRY ) {
4551 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4552 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4554 /* subtract right from left if at the
4555 end the carry flag is set then we know that
4556 left is greater than right */
4558 symbol *lbl = newiTempLabel(NULL);
4561 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4562 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
4566 if(AOP_TYPE(right) == AOP_LIT) {
4568 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4570 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4577 genSkipCond(&rFalseIfx,left,size-1,7);
4579 /* no need to compare to 0...*/
4580 /* NOTE: this is a de-generate compare that most certainly
4581 * creates some dead code. */
4582 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4584 if(ifx) ifx->generated = 1;
4591 //i = (lit >> (size*8)) & 0xff;
4592 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4594 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4596 i = ((0-lit) & 0xff);
4599 /* lit is 0x7f, all signed chars are less than
4600 * this except for 0x7f itself */
4601 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4602 genSkipz2(&rFalseIfx,0);
4604 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4605 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4606 genSkipc(&rFalseIfx);
4611 genSkipz2(&rFalseIfx,1);
4613 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4614 genSkipc(&rFalseIfx);
4618 if(ifx) ifx->generated = 1;
4622 /* chars are out of the way. now do ints and longs */
4625 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4632 genSkipCond(&rFalseIfx,left,size,7);
4633 if(ifx) ifx->generated = 1;
4638 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4640 //rFalseIfx.condition ^= 1;
4641 //genSkipCond(&rFalseIfx,left,size,7);
4642 //rFalseIfx.condition ^= 1;
4644 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4645 if(rFalseIfx.condition)
4646 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4648 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4650 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4651 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4652 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4655 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4657 if(rFalseIfx.condition) {
4659 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4665 genSkipc(&rFalseIfx);
4666 pic16_emitpLabel(truelbl->key);
4667 if(ifx) ifx->generated = 1;
4674 if( (lit & 0xff) == 0) {
4675 /* lower byte is zero */
4676 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4677 i = ((lit >> 8) & 0xff) ^0x80;
4678 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4679 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4680 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4681 genSkipc(&rFalseIfx);
4684 if(ifx) ifx->generated = 1;
4689 /* Special cases for signed longs */
4690 if( (lit & 0xffffff) == 0) {
4691 /* lower byte is zero */
4692 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4693 i = ((lit >> 8*3) & 0xff) ^0x80;
4694 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4695 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4696 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4697 genSkipc(&rFalseIfx);
4700 if(ifx) ifx->generated = 1;
4708 if(lit & (0x80 << (size*8))) {
4709 /* lit is negative */
4710 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4712 //genSkipCond(&rFalseIfx,left,size,7);
4714 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4716 if(rFalseIfx.condition)
4717 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4719 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4723 /* lit is positive */
4724 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4725 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4726 if(rFalseIfx.condition)
4727 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4729 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4734 This works, but is only good for ints.
4735 It also requires a "known zero" register.
4736 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4737 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4738 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4739 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4740 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4741 genSkipc(&rFalseIfx);
4743 pic16_emitpLabel(truelbl->key);
4744 if(ifx) ifx->generated = 1;
4748 /* There are no more special cases, so perform a general compare */
4750 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4751 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4755 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4757 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4759 //rFalseIfx.condition ^= 1;
4760 genSkipc(&rFalseIfx);
4762 pic16_emitpLabel(truelbl->key);
4764 if(ifx) ifx->generated = 1;
4771 /* sign is out of the way. So now do an unsigned compare */
4772 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4775 /* General case - compare to an unsigned literal on the right.*/
4777 i = (lit >> (size*8)) & 0xff;
4778 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4779 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4781 i = (lit >> (size*8)) & 0xff;
4784 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4786 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4788 /* this byte of the lit is zero,
4789 *if it's not the last then OR in the variable */
4791 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4796 pic16_emitpLabel(lbl->key);
4797 // pic16_emitpLabel(truelbl->key);
4798 //if(emitFinalCheck)
4799 genSkipc(&rFalseIfx);
4801 pic16_emitpLabel(truelbl->key);
4803 if(ifx) ifx->generated = 1;
4810 if(AOP_TYPE(left) == AOP_LIT) {
4811 //symbol *lbl = newiTempLabel(NULL);
4813 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4816 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4819 if((lit == 0) && (sign == 0)){
4822 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4824 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4826 genSkipz2(&rFalseIfx,0);
4827 if(ifx) ifx->generated = 1;
4834 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4835 /* degenerate compare can never be true */
4836 if(rFalseIfx.condition == 0)
4837 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4839 if(ifx) ifx->generated = 1;
4844 /* signed comparisons to a literal byte */
4846 int lp1 = (lit+1) & 0xff;
4848 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4851 rFalseIfx.condition ^= 1;
4852 genSkipCond(&rFalseIfx,right,0,7);
4855 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4856 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4857 genSkipz2(&rFalseIfx,1);
4860 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4861 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4862 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4863 rFalseIfx.condition ^= 1;
4864 genSkipc(&rFalseIfx);
4868 /* unsigned comparisons to a literal byte */
4870 switch(lit & 0xff ) {
4872 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4873 genSkipz2(&rFalseIfx,0);
4876 rFalseIfx.condition ^= 1;
4877 genSkipCond(&rFalseIfx,right,0,7);
4881 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4882 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4883 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4884 rFalseIfx.condition ^= 1;
4885 if (AOP_TYPE(result) == AOP_CRY)
4886 genSkipc(&rFalseIfx);
4888 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4889 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4895 if(ifx) ifx->generated = 1;
4901 /* Size is greater than 1 */
4909 /* this means lit = 0xffffffff, or -1 */
4912 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4913 rFalseIfx.condition ^= 1;
4914 genSkipCond(&rFalseIfx,right,size,7);
4915 if(ifx) ifx->generated = 1;
4922 if(rFalseIfx.condition) {
4923 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4924 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4927 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4929 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4933 if(rFalseIfx.condition) {
4934 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4935 pic16_emitpLabel(truelbl->key);
4937 rFalseIfx.condition ^= 1;
4938 genSkipCond(&rFalseIfx,right,s,7);
4941 if(ifx) ifx->generated = 1;
4945 if((size == 1) && (0 == (lp1&0xff))) {
4946 /* lower byte of signed word is zero */
4947 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4948 i = ((lp1 >> 8) & 0xff) ^0x80;
4949 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4950 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4951 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4952 rFalseIfx.condition ^= 1;
4953 genSkipc(&rFalseIfx);
4956 if(ifx) ifx->generated = 1;
4960 if(lit & (0x80 << (size*8))) {
4961 /* Lit is less than zero */
4962 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4963 //rFalseIfx.condition ^= 1;
4964 //genSkipCond(&rFalseIfx,left,size,7);
4965 //rFalseIfx.condition ^= 1;
4966 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4967 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4969 if(rFalseIfx.condition)
4970 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4972 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4976 /* Lit is greater than or equal to zero */
4977 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4978 //rFalseIfx.condition ^= 1;
4979 //genSkipCond(&rFalseIfx,right,size,7);
4980 //rFalseIfx.condition ^= 1;
4982 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4983 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4985 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4986 if(rFalseIfx.condition)
4987 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4989 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4994 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4995 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4999 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
5001 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5003 rFalseIfx.condition ^= 1;
5004 //rFalseIfx.condition = 1;
5005 genSkipc(&rFalseIfx);
5007 pic16_emitpLabel(truelbl->key);
5009 if(ifx) ifx->generated = 1;
5014 /* compare word or long to an unsigned literal on the right.*/
5019 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5022 break; /* handled above */
5025 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5027 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5028 genSkipz2(&rFalseIfx,0);
5032 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5034 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5037 if(rFalseIfx.condition)
5038 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5040 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5043 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5044 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5046 rFalseIfx.condition ^= 1;
5047 genSkipc(&rFalseIfx);
5050 pic16_emitpLabel(truelbl->key);
5052 if(ifx) ifx->generated = 1;
5058 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5059 i = (lit >> (size*8)) & 0xff;
5061 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5062 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5065 i = (lit >> (size*8)) & 0xff;
5068 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5070 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5072 /* this byte of the lit is zero,
5073 * if it's not the last then OR in the variable */
5075 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5080 pic16_emitpLabel(lbl->key);
5082 rFalseIfx.condition ^= 1;
5084 genSkipc(&rFalseIfx);
5088 pic16_emitpLabel(truelbl->key);
5089 if(ifx) ifx->generated = 1;
5093 /* Compare two variables */
5095 DEBUGpic16_emitcode(";sign","%d",sign);
5099 /* Sigh. thus sucks... */
5101 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5102 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5103 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5104 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5105 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5106 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5108 /* Signed char comparison */
5109 /* Special thanks to Nikolai Golovchenko for this snippet */
5110 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5111 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5112 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5113 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5114 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5115 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5117 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5118 genSkipc(&rFalseIfx);
5120 if(ifx) ifx->generated = 1;
5126 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5127 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5131 /* The rest of the bytes of a multi-byte compare */
5135 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5138 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5139 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5144 pic16_emitpLabel(lbl->key);
5146 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5147 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5148 (AOP_TYPE(result) == AOP_REG)) {
5149 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5150 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5152 genSkipc(&rFalseIfx);
5154 //genSkipc(&rFalseIfx);
5155 if(ifx) ifx->generated = 1;
5162 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5163 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5164 pic16_outBitC(result);
5166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5167 /* if the result is used in the next
5168 ifx conditional branch then generate
5169 code a little differently */
5171 genIfxJump (ifx,"c");
5173 pic16_outBitC(result);
5174 /* leave the result in acc */
5179 /*-----------------------------------------------------------------*/
5180 /* genCmpGt :- greater than comparison */
5181 /*-----------------------------------------------------------------*/
5182 static void genCmpGt (iCode *ic, iCode *ifx)
5184 operand *left, *right, *result;
5185 sym_link *letype , *retype;
5188 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5190 right= IC_RIGHT(ic);
5191 result = IC_RESULT(ic);
5193 letype = getSpec(operandType(left));
5194 retype =getSpec(operandType(right));
5195 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5196 /* assign the amsops */
5197 pic16_aopOp (left,ic,FALSE);
5198 pic16_aopOp (right,ic,FALSE);
5199 pic16_aopOp (result,ic,TRUE);
5201 genCmp(right, left, result, ifx, sign);
5203 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5204 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5205 pic16_freeAsmop(result,NULL,ic,TRUE);
5208 /*-----------------------------------------------------------------*/
5209 /* genCmpLt - less than comparisons */
5210 /*-----------------------------------------------------------------*/
5211 static void genCmpLt (iCode *ic, iCode *ifx)
5213 operand *left, *right, *result;
5214 sym_link *letype , *retype;
5217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5219 right= IC_RIGHT(ic);
5220 result = IC_RESULT(ic);
5222 letype = getSpec(operandType(left));
5223 retype =getSpec(operandType(right));
5224 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5226 /* assign the amsops */
5227 pic16_aopOp (left,ic,FALSE);
5228 pic16_aopOp (right,ic,FALSE);
5229 pic16_aopOp (result,ic,TRUE);
5231 genCmp(left, right, result, ifx, sign);
5233 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5234 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5235 pic16_freeAsmop(result,NULL,ic,TRUE);
5240 // FIXME reenable literal optimisation when the pic16 port is stable
5242 /*-----------------------------------------------------------------*/
5243 /* genc16bit2lit - compare a 16 bit value to a literal */
5244 /*-----------------------------------------------------------------*/
5245 static void genc16bit2lit(operand *op, int lit, int offset)
5249 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5250 if( (lit&0xff) == 0)
5255 switch( BYTEofLONG(lit,i)) {
5257 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5260 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5263 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5266 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5267 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5272 switch( BYTEofLONG(lit,i)) {
5274 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5278 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5282 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5285 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5287 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5296 /*-----------------------------------------------------------------*/
5297 /* gencjneshort - compare and jump if not equal */
5298 /*-----------------------------------------------------------------*/
5299 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5301 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5303 int res_offset = 0; /* the result may be a different size then left or right */
5304 int res_size = AOP_SIZE(result);
5306 symbol *lbl, *lbl_done;
5308 unsigned long lit = 0L;
5309 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5312 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5314 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5315 resolveIfx(&rIfx,ifx);
5316 lbl = newiTempLabel(NULL);
5317 lbl_done = newiTempLabel(NULL);
5320 /* if the left side is a literal or
5321 if the right is in a pointer register and left
5323 if ((AOP_TYPE(left) == AOP_LIT) ||
5324 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5329 if(AOP_TYPE(right) == AOP_LIT)
5330 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5332 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5333 preserve_result = 1;
5335 if(result && !preserve_result)
5338 for(i = 0; i < AOP_SIZE(result); i++)
5339 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5343 /* if the right side is a literal then anything goes */
5344 if (AOP_TYPE(right) == AOP_LIT &&
5345 AOP_TYPE(left) != AOP_DIR ) {
5348 genc16bit2lit(left, lit, 0);
5350 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5353 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5356 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5357 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5359 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5363 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5365 if(res_offset < res_size-1)
5373 /* if the right side is in a register or in direct space or
5374 if the left is a pointer register & right is not */
5375 else if (AOP_TYPE(right) == AOP_REG ||
5376 AOP_TYPE(right) == AOP_DIR ||
5377 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5378 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5379 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5380 int lbl_key = lbl->key;
5383 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5384 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5386 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5387 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5388 __FUNCTION__,__LINE__);
5392 /* switch(size) { */
5394 /* genc16bit2lit(left, lit, 0); */
5396 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5401 if((AOP_TYPE(left) == AOP_DIR) &&
5402 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5404 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5405 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5407 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5409 switch (lit & 0xff) {
5411 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5414 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5415 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5416 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5420 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5421 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5422 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5423 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5427 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5428 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5433 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5436 if(AOP_TYPE(result) == AOP_CRY) {
5437 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5442 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5444 /* fix me. probably need to check result size too */
5445 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5450 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5451 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5458 if(res_offset < res_size-1)
5463 } else if(AOP_TYPE(right) == AOP_REG &&
5464 AOP_TYPE(left) != AOP_DIR){
5467 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5468 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5469 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5474 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5476 if(res_offset < res_size-1)
5481 /* right is a pointer reg need both a & b */
5483 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5485 pic16_emitcode("mov","b,%s",l);
5486 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5487 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5492 if(result && preserve_result)
5495 for(i = 0; i < AOP_SIZE(result); i++)
5496 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5499 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
5501 if(result && preserve_result)
5502 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
5505 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5507 pic16_emitpLabel(lbl->key);
5509 if(result && preserve_result)
5512 for(i = 0; i < AOP_SIZE(result); i++)
5513 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5515 pic16_emitpLabel(lbl_done->key);
5518 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5526 /*-----------------------------------------------------------------*/
5527 /* gencjne - compare and jump if not equal */
5528 /*-----------------------------------------------------------------*/
5529 static void gencjne(operand *left, operand *right, iCode *ifx)
5531 symbol *tlbl = newiTempLabel(NULL);
5533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5534 gencjneshort(left, right, lbl);
5536 pic16_emitcode("mov","a,%s",one);
5537 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5538 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5539 pic16_emitcode("clr","a");
5540 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5542 pic16_emitpLabel(lbl->key);
5543 pic16_emitpLabel(tlbl->key);
5549 /*-----------------------------------------------------------------*/
5550 /* is_LitOp - check if operand has to be treated as literal */
5551 /*-----------------------------------------------------------------*/
5552 static bool is_LitOp(operand *op)
5554 return (AOP_TYPE(op) == AOP_LIT)
5555 || ( (AOP_TYPE(op) == AOP_PCODE)
5556 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
5557 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
5561 /*-----------------------------------------------------------------*/
5562 /* genCmpEq - generates code for equal to */
5563 /*-----------------------------------------------------------------*/
5564 static void genCmpEq (iCode *ic, iCode *ifx)
5566 operand *left, *right, *result;
5567 symbol *falselbl = newiTempLabel(NULL);
5568 symbol *donelbl = newiTempLabel(NULL);
5570 int preserve_result = 0;
5571 int generate_result = 0;
5574 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5575 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5576 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5578 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5579 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5581 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
5583 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5584 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
5588 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
5590 operand *tmp = right ;
5595 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5596 preserve_result = 1;
5598 if(result && AOP_SIZE(result))
5599 generate_result = 1;
5601 if(generate_result && !preserve_result)
5603 for(i = 0; i < AOP_SIZE(result); i++)
5604 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5607 for(i=0; i < AOP_SIZE(left); i++)
5609 if(AOP_TYPE(left) != AOP_ACC)
5612 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
5614 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
5617 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
5619 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
5621 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
5626 if(generate_result && preserve_result)
5628 for(i = 0; i < AOP_SIZE(result); i++)
5629 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5633 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
5635 if(generate_result && preserve_result)
5636 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5638 if(ifx && IC_TRUE(ifx))
5639 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5641 if(ifx && IC_FALSE(ifx))
5642 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5644 pic16_emitpLabel(falselbl->key);
5648 if(ifx && IC_FALSE(ifx))
5649 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5651 if(generate_result && preserve_result)
5653 for(i = 0; i < AOP_SIZE(result); i++)
5654 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5657 pic16_emitpLabel(donelbl->key);
5663 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5664 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5665 pic16_freeAsmop(result,NULL,ic,TRUE);
5671 // old version kept for reference
5673 /*-----------------------------------------------------------------*/
5674 /* genCmpEq - generates code for equal to */
5675 /*-----------------------------------------------------------------*/
5676 static void genCmpEq (iCode *ic, iCode *ifx)
5678 operand *left, *right, *result;
5679 unsigned long lit = 0L;
5681 symbol *falselbl = newiTempLabel(NULL);
5684 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5687 DEBUGpic16_emitcode ("; ifx is non-null","");
5689 DEBUGpic16_emitcode ("; ifx is null","");
5691 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5692 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5693 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5695 size = max(AOP_SIZE(left),AOP_SIZE(right));
5697 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5699 /* if literal, literal on the right or
5700 if the right is in a pointer register and left
5702 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5703 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5704 operand *tmp = right ;
5710 if(ifx && !AOP_SIZE(result)){
5712 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5713 /* if they are both bit variables */
5714 if (AOP_TYPE(left) == AOP_CRY &&
5715 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5716 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5717 if(AOP_TYPE(right) == AOP_LIT){
5718 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5720 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5721 pic16_emitcode("cpl","c");
5722 } else if(lit == 1L) {
5723 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5725 pic16_emitcode("clr","c");
5727 /* AOP_TYPE(right) == AOP_CRY */
5729 symbol *lbl = newiTempLabel(NULL);
5730 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5731 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5732 pic16_emitcode("cpl","c");
5733 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5735 /* if true label then we jump if condition
5737 tlbl = newiTempLabel(NULL);
5738 if ( IC_TRUE(ifx) ) {
5739 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5740 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5742 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5743 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5745 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5748 /* left and right are both bit variables, result is carry */
5751 resolveIfx(&rIfx,ifx);
5753 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5754 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5755 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5756 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5761 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5763 /* They're not both bit variables. Is the right a literal? */
5764 if(AOP_TYPE(right) == AOP_LIT) {
5765 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5770 switch(lit & 0xff) {
5772 if ( IC_TRUE(ifx) ) {
5773 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5775 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5777 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5778 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5782 if ( IC_TRUE(ifx) ) {
5783 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5785 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5787 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5788 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5792 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5794 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5799 /* end of size == 1 */
5803 genc16bit2lit(left,lit,offset);
5806 /* end of size == 2 */
5811 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5812 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5813 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5814 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5817 /* search for patterns that can be optimized */
5819 genc16bit2lit(left,lit,0);
5823 emitSKPZ; // if hi word unequal
5825 emitSKPNZ; // if hi word equal
5827 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5828 genc16bit2lit(left,lit,2);
5831 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5832 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5836 pic16_emitpLabel(falselbl->key);
5845 } else if(AOP_TYPE(right) == AOP_CRY ) {
5846 /* we know the left is not a bit, but that the right is */
5847 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5848 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5849 pic16_popGet(AOP(right),offset));
5850 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5852 /* if the two are equal, then W will be 0 and the Z bit is set
5853 * we could test Z now, or go ahead and check the high order bytes if
5854 * the variable we're comparing is larger than a byte. */
5857 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5859 if ( IC_TRUE(ifx) ) {
5861 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5862 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5865 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5866 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5870 /* They're both variables that are larger than bits */
5873 tlbl = newiTempLabel(NULL);
5876 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5877 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5879 if ( IC_TRUE(ifx) ) {
5883 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5885 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5886 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5890 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5893 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5894 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5899 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5901 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5902 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5906 if(s>1 && IC_TRUE(ifx)) {
5907 pic16_emitpLabel(tlbl->key);
5908 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5912 /* mark the icode as generated */
5917 /* if they are both bit variables */
5918 if (AOP_TYPE(left) == AOP_CRY &&
5919 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5920 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5921 if(AOP_TYPE(right) == AOP_LIT){
5922 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5924 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5925 pic16_emitcode("cpl","c");
5926 } else if(lit == 1L) {
5927 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5929 pic16_emitcode("clr","c");
5931 /* AOP_TYPE(right) == AOP_CRY */
5933 symbol *lbl = newiTempLabel(NULL);
5934 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5935 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5936 pic16_emitcode("cpl","c");
5937 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5940 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5941 pic16_outBitC(result);
5945 genIfxJump (ifx,"c");
5948 /* if the result is used in an arithmetic operation
5949 then put the result in place */
5950 pic16_outBitC(result);
5953 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5954 gencjne(left,right,result,ifx);
5957 gencjne(left,right,newiTempLabel(NULL));
5959 if(IC_TRUE(ifx)->key)
5960 gencjne(left,right,IC_TRUE(ifx)->key);
5962 gencjne(left,right,IC_FALSE(ifx)->key);
5966 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5967 pic16_aopPut(AOP(result),"a",0);
5972 genIfxJump (ifx,"a");
5976 /* if the result is used in an arithmetic operation
5977 then put the result in place */
5979 if (AOP_TYPE(result) != AOP_CRY)
5980 pic16_outAcc(result);
5982 /* leave the result in acc */
5986 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5987 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5988 pic16_freeAsmop(result,NULL,ic,TRUE);
5992 /*-----------------------------------------------------------------*/
5993 /* ifxForOp - returns the icode containing the ifx for operand */
5994 /*-----------------------------------------------------------------*/
5995 static iCode *ifxForOp ( operand *op, iCode *ic )
5997 /* if true symbol then needs to be assigned */
5998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5999 if (IS_TRUE_SYMOP(op))
6002 /* if this has register type condition and
6003 the next instruction is ifx with the same operand
6004 and live to of the operand is upto the ifx only then */
6006 ic->next->op == IFX &&
6007 IC_COND(ic->next)->key == op->key &&
6008 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6012 ic->next->op == IFX &&
6013 IC_COND(ic->next)->key == op->key) {
6014 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6018 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6020 ic->next->op == IFX)
6021 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6024 ic->next->op == IFX &&
6025 IC_COND(ic->next)->key == op->key) {
6026 DEBUGpic16_emitcode ("; "," key is okay");
6027 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6028 OP_SYMBOL(op)->liveTo,
6033 /* the code below is completely untested
6034 * it just allows ulong2fs.c compile -- VR */
6037 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6038 __FILE__, __FUNCTION__, __LINE__);
6040 /* if this has register type condition and
6041 the next instruction is ifx with the same operand
6042 and live to of the operand is upto the ifx only then */
6044 ic->next->op == IFX &&
6045 IC_COND(ic->next)->key == op->key &&
6046 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6050 ic->next->op == IFX &&
6051 IC_COND(ic->next)->key == op->key) {
6052 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6056 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6057 __FILE__, __FUNCTION__, __LINE__);
6059 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6063 /*-----------------------------------------------------------------*/
6064 /* genAndOp - for && operation */
6065 /*-----------------------------------------------------------------*/
6066 static void genAndOp (iCode *ic)
6068 operand *left,*right, *result;
6071 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6072 /* note here that && operations that are in an
6073 if statement are taken away by backPatchLabels
6074 only those used in arthmetic operations remain */
6075 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6076 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6077 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6079 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6081 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6082 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6083 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6085 /* if both are bit variables */
6086 /* if (AOP_TYPE(left) == AOP_CRY && */
6087 /* AOP_TYPE(right) == AOP_CRY ) { */
6088 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6089 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6090 /* pic16_outBitC(result); */
6092 /* tlbl = newiTempLabel(NULL); */
6093 /* pic16_toBoolean(left); */
6094 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6095 /* pic16_toBoolean(right); */
6096 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6097 /* pic16_outBitAcc(result); */
6100 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6101 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6102 pic16_freeAsmop(result,NULL,ic,TRUE);
6106 /*-----------------------------------------------------------------*/
6107 /* genOrOp - for || operation */
6108 /*-----------------------------------------------------------------*/
6111 modified this code, but it doesn't appear to ever get called
6114 static void genOrOp (iCode *ic)
6116 operand *left,*right, *result;
6119 /* note here that || operations that are in an
6120 if statement are taken away by backPatchLabels
6121 only those used in arthmetic operations remain */
6122 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6123 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6124 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6125 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6127 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6129 /* if both are bit variables */
6130 if (AOP_TYPE(left) == AOP_CRY &&
6131 AOP_TYPE(right) == AOP_CRY ) {
6132 pic16_emitcode("clrc","");
6133 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6134 AOP(left)->aopu.aop_dir,
6135 AOP(left)->aopu.aop_dir);
6136 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6137 AOP(right)->aopu.aop_dir,
6138 AOP(right)->aopu.aop_dir);
6139 pic16_emitcode("setc","");
6142 tlbl = newiTempLabel(NULL);
6143 pic16_toBoolean(left);
6145 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
6146 pic16_toBoolean(right);
6147 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
6149 pic16_outBitAcc(result);
6152 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6153 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6154 pic16_freeAsmop(result,NULL,ic,TRUE);
6157 /*-----------------------------------------------------------------*/
6158 /* isLiteralBit - test if lit == 2^n */
6159 /*-----------------------------------------------------------------*/
6160 static int isLiteralBit(unsigned long lit)
6162 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6163 0x100L,0x200L,0x400L,0x800L,
6164 0x1000L,0x2000L,0x4000L,0x8000L,
6165 0x10000L,0x20000L,0x40000L,0x80000L,
6166 0x100000L,0x200000L,0x400000L,0x800000L,
6167 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6168 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6171 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6172 for(idx = 0; idx < 32; idx++)
6178 /*-----------------------------------------------------------------*/
6179 /* continueIfTrue - */
6180 /*-----------------------------------------------------------------*/
6181 static void continueIfTrue (iCode *ic)
6183 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6185 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6189 /*-----------------------------------------------------------------*/
6191 /*-----------------------------------------------------------------*/
6192 static void jumpIfTrue (iCode *ic)
6194 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6196 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6200 /*-----------------------------------------------------------------*/
6201 /* jmpTrueOrFalse - */
6202 /*-----------------------------------------------------------------*/
6203 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6205 // ugly but optimized by peephole
6206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6208 symbol *nlbl = newiTempLabel(NULL);
6209 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6210 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6211 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6212 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6215 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6216 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6221 /*-----------------------------------------------------------------*/
6222 /* genAnd - code for and */
6223 /*-----------------------------------------------------------------*/
6224 static void genAnd (iCode *ic, iCode *ifx)
6226 operand *left, *right, *result;
6228 unsigned long lit = 0L;
6233 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6234 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6235 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6236 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6238 resolveIfx(&rIfx,ifx);
6240 /* if left is a literal & right is not then exchange them */
6241 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6242 AOP_NEEDSACC(left)) {
6243 operand *tmp = right ;
6248 /* if result = right then exchange them */
6249 if(pic16_sameRegs(AOP(result),AOP(right))){
6250 operand *tmp = right ;
6255 /* if right is bit then exchange them */
6256 if (AOP_TYPE(right) == AOP_CRY &&
6257 AOP_TYPE(left) != AOP_CRY){
6258 operand *tmp = right ;
6262 if(AOP_TYPE(right) == AOP_LIT)
6263 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6265 size = AOP_SIZE(result);
6267 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6270 // result = bit & yy;
6271 if (AOP_TYPE(left) == AOP_CRY){
6272 // c = bit & literal;
6273 if(AOP_TYPE(right) == AOP_LIT){
6275 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6278 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6281 if(size && (AOP_TYPE(result) == AOP_CRY)){
6282 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6285 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6289 pic16_emitcode("clr","c");
6292 if (AOP_TYPE(right) == AOP_CRY){
6294 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6295 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6298 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6300 pic16_emitcode("rrc","a");
6301 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6307 pic16_outBitC(result);
6309 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6310 genIfxJump(ifx, "c");
6314 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6315 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6316 if((AOP_TYPE(right) == AOP_LIT) &&
6317 (AOP_TYPE(result) == AOP_CRY) &&
6318 (AOP_TYPE(left) != AOP_CRY)){
6319 int posbit = isLiteralBit(lit);
6323 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6326 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6332 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6333 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6335 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6336 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6339 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6340 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6341 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6348 symbol *tlbl = newiTempLabel(NULL);
6349 int sizel = AOP_SIZE(left);
6351 pic16_emitcode("setb","c");
6353 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
6354 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6356 if((posbit = isLiteralBit(bytelit)) != 0)
6357 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
6359 if(bytelit != 0x0FFL)
6360 pic16_emitcode("anl","a,%s",
6361 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
6362 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6367 // bit = left & literal
6369 pic16_emitcode("clr","c");
6370 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6372 // if(left & literal)
6375 jmpTrueOrFalse(ifx, tlbl);
6379 pic16_outBitC(result);
6383 /* if left is same as result */
6384 if(pic16_sameRegs(AOP(result),AOP(left))){
6386 for(;size--; offset++,lit>>=8) {
6387 if(AOP_TYPE(right) == AOP_LIT){
6388 switch(lit & 0xff) {
6390 /* and'ing with 0 has clears the result */
6391 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6392 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6395 /* and'ing with 0xff is a nop when the result and left are the same */
6400 int p = my_powof2( (~lit) & 0xff );
6402 /* only one bit is set in the literal, so use a bcf instruction */
6403 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
6404 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6407 pic16_emitcode("movlw","0x%x", (lit & 0xff));
6408 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6409 if(know_W != (lit&0xff))
6410 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6412 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6417 if (AOP_TYPE(left) == AOP_ACC) {
6418 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6420 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6421 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6428 // left & result in different registers
6429 if(AOP_TYPE(result) == AOP_CRY){
6431 // if(size), result in bit
6432 // if(!size && ifx), conditional oper: if(left & right)
6433 symbol *tlbl = newiTempLabel(NULL);
6434 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
6436 pic16_emitcode("setb","c");
6438 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6439 pic16_emitcode("anl","a,%s",
6440 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6441 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6446 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6447 pic16_outBitC(result);
6449 jmpTrueOrFalse(ifx, tlbl);
6451 for(;(size--);offset++) {
6453 // result = left & right
6454 if(AOP_TYPE(right) == AOP_LIT){
6455 int t = (lit >> (offset*8)) & 0x0FFL;
6458 pic16_emitcode("clrf","%s",
6459 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6460 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6463 pic16_emitcode("movf","%s,w",
6464 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6465 pic16_emitcode("movwf","%s",
6466 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6467 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6468 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6471 pic16_emitcode("movlw","0x%x",t);
6472 pic16_emitcode("andwf","%s,w",
6473 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6474 pic16_emitcode("movwf","%s",
6475 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6477 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6478 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6479 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6484 if (AOP_TYPE(left) == AOP_ACC) {
6485 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6486 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6488 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6489 pic16_emitcode("andwf","%s,w",
6490 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6491 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6492 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6494 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6495 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6501 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6502 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6503 pic16_freeAsmop(result,NULL,ic,TRUE);
6506 /*-----------------------------------------------------------------*/
6507 /* genOr - code for or */
6508 /*-----------------------------------------------------------------*/
6509 static void genOr (iCode *ic, iCode *ifx)
6511 operand *left, *right, *result;
6513 unsigned long lit = 0L;
6515 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6517 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6518 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6519 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6521 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6523 /* if left is a literal & right is not then exchange them */
6524 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6525 AOP_NEEDSACC(left)) {
6526 operand *tmp = right ;
6531 /* if result = right then exchange them */
6532 if(pic16_sameRegs(AOP(result),AOP(right))){
6533 operand *tmp = right ;
6538 /* if right is bit then exchange them */
6539 if (AOP_TYPE(right) == AOP_CRY &&
6540 AOP_TYPE(left) != AOP_CRY){
6541 operand *tmp = right ;
6546 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6548 if(AOP_TYPE(right) == AOP_LIT)
6549 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6551 size = AOP_SIZE(result);
6555 if (AOP_TYPE(left) == AOP_CRY){
6556 if(AOP_TYPE(right) == AOP_LIT){
6557 // c = bit & literal;
6559 // lit != 0 => result = 1
6560 if(AOP_TYPE(result) == AOP_CRY){
6562 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6563 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6564 // AOP(result)->aopu.aop_dir,
6565 // AOP(result)->aopu.aop_dir);
6567 continueIfTrue(ifx);
6571 // lit == 0 => result = left
6572 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6574 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6577 if (AOP_TYPE(right) == AOP_CRY){
6578 if(pic16_sameRegs(AOP(result),AOP(left))){
6580 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6581 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6582 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6584 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6585 AOP(result)->aopu.aop_dir,
6586 AOP(result)->aopu.aop_dir);
6587 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6588 AOP(right)->aopu.aop_dir,
6589 AOP(right)->aopu.aop_dir);
6590 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6591 AOP(result)->aopu.aop_dir,
6592 AOP(result)->aopu.aop_dir);
6594 if( AOP_TYPE(result) == AOP_ACC) {
6595 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6596 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6597 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6598 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6602 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6603 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6604 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6605 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6607 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6608 AOP(result)->aopu.aop_dir,
6609 AOP(result)->aopu.aop_dir);
6610 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6611 AOP(right)->aopu.aop_dir,
6612 AOP(right)->aopu.aop_dir);
6613 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6614 AOP(left)->aopu.aop_dir,
6615 AOP(left)->aopu.aop_dir);
6616 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6617 AOP(result)->aopu.aop_dir,
6618 AOP(result)->aopu.aop_dir);
6623 symbol *tlbl = newiTempLabel(NULL);
6624 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6627 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6628 if( AOP_TYPE(right) == AOP_ACC) {
6629 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6631 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6632 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6637 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6638 pic16_emitcode(";XXX setb","c");
6639 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6640 AOP(left)->aopu.aop_dir,tlbl->key+100);
6641 pic16_toBoolean(right);
6642 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6643 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6644 jmpTrueOrFalse(ifx, tlbl);
6648 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6655 pic16_outBitC(result);
6657 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6658 genIfxJump(ifx, "c");
6662 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6663 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6664 if((AOP_TYPE(right) == AOP_LIT) &&
6665 (AOP_TYPE(result) == AOP_CRY) &&
6666 (AOP_TYPE(left) != AOP_CRY)){
6668 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6671 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6673 continueIfTrue(ifx);
6676 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6677 // lit = 0, result = boolean(left)
6679 pic16_emitcode(";XXX setb","c");
6680 pic16_toBoolean(right);
6682 symbol *tlbl = newiTempLabel(NULL);
6683 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6685 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6687 genIfxJump (ifx,"a");
6691 pic16_outBitC(result);
6695 /* if left is same as result */
6696 if(pic16_sameRegs(AOP(result),AOP(left))){
6698 for(;size--; offset++,lit>>=8) {
6699 if(AOP_TYPE(right) == AOP_LIT){
6700 if((lit & 0xff) == 0)
6701 /* or'ing with 0 has no effect */
6704 int p = my_powof2(lit & 0xff);
6706 /* only one bit is set in the literal, so use a bsf instruction */
6707 pic16_emitpcode(POC_BSF,
6708 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6710 if(know_W != (lit & 0xff))
6711 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6712 know_W = lit & 0xff;
6713 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6718 if (AOP_TYPE(left) == AOP_ACC) {
6719 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6720 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6722 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6723 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6725 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6726 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6732 // left & result in different registers
6733 if(AOP_TYPE(result) == AOP_CRY){
6735 // if(size), result in bit
6736 // if(!size && ifx), conditional oper: if(left | right)
6737 symbol *tlbl = newiTempLabel(NULL);
6738 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6739 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6743 pic16_emitcode(";XXX setb","c");
6745 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6746 pic16_emitcode(";XXX orl","a,%s",
6747 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6748 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6753 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6754 pic16_outBitC(result);
6756 jmpTrueOrFalse(ifx, tlbl);
6757 } else for(;(size--);offset++){
6759 // result = left & right
6760 if(AOP_TYPE(right) == AOP_LIT){
6761 int t = (lit >> (offset*8)) & 0x0FFL;
6764 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6765 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6767 pic16_emitcode("movf","%s,w",
6768 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6769 pic16_emitcode("movwf","%s",
6770 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6773 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6774 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6775 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6777 pic16_emitcode("movlw","0x%x",t);
6778 pic16_emitcode("iorwf","%s,w",
6779 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6780 pic16_emitcode("movwf","%s",
6781 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6787 // faster than result <- left, anl result,right
6788 // and better if result is SFR
6789 if (AOP_TYPE(left) == AOP_ACC) {
6790 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6791 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6793 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6794 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6796 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6797 pic16_emitcode("iorwf","%s,w",
6798 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6800 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6801 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6806 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6807 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6808 pic16_freeAsmop(result,NULL,ic,TRUE);
6811 /*-----------------------------------------------------------------*/
6812 /* genXor - code for xclusive or */
6813 /*-----------------------------------------------------------------*/
6814 static void genXor (iCode *ic, iCode *ifx)
6816 operand *left, *right, *result;
6818 unsigned long lit = 0L;
6820 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6822 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6823 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6824 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6826 /* if left is a literal & right is not ||
6827 if left needs acc & right does not */
6828 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6829 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6830 operand *tmp = right ;
6835 /* if result = right then exchange them */
6836 if(pic16_sameRegs(AOP(result),AOP(right))){
6837 operand *tmp = right ;
6842 /* if right is bit then exchange them */
6843 if (AOP_TYPE(right) == AOP_CRY &&
6844 AOP_TYPE(left) != AOP_CRY){
6845 operand *tmp = right ;
6849 if(AOP_TYPE(right) == AOP_LIT)
6850 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6852 size = AOP_SIZE(result);
6856 if (AOP_TYPE(left) == AOP_CRY){
6857 if(AOP_TYPE(right) == AOP_LIT){
6858 // c = bit & literal;
6860 // lit>>1 != 0 => result = 1
6861 if(AOP_TYPE(result) == AOP_CRY){
6863 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6864 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6866 continueIfTrue(ifx);
6869 pic16_emitcode("setb","c");
6873 // lit == 0, result = left
6874 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6876 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6878 // lit == 1, result = not(left)
6879 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6880 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6881 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6882 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6885 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6886 pic16_emitcode("cpl","c");
6893 symbol *tlbl = newiTempLabel(NULL);
6894 if (AOP_TYPE(right) == AOP_CRY){
6896 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6899 int sizer = AOP_SIZE(right);
6901 // if val>>1 != 0, result = 1
6902 pic16_emitcode("setb","c");
6904 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6906 // test the msb of the lsb
6907 pic16_emitcode("anl","a,#0xfe");
6908 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6912 pic16_emitcode("rrc","a");
6914 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6915 pic16_emitcode("cpl","c");
6916 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6921 pic16_outBitC(result);
6923 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6924 genIfxJump(ifx, "c");
6928 if(pic16_sameRegs(AOP(result),AOP(left))){
6929 /* if left is same as result */
6930 for(;size--; offset++) {
6931 if(AOP_TYPE(right) == AOP_LIT){
6932 int t = (lit >> (offset*8)) & 0x0FFL;
6936 if (IS_AOP_PREG(left)) {
6937 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6938 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6939 pic16_aopPut(AOP(result),"a",offset);
6941 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6942 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6943 pic16_emitcode("xrl","%s,%s",
6944 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6945 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6948 if (AOP_TYPE(left) == AOP_ACC)
6949 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6951 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6952 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6954 if (IS_AOP_PREG(left)) {
6955 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6956 pic16_aopPut(AOP(result),"a",offset);
6958 pic16_emitcode("xrl","%s,a",
6959 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6965 // left & result in different registers
6966 if(AOP_TYPE(result) == AOP_CRY){
6968 // if(size), result in bit
6969 // if(!size && ifx), conditional oper: if(left ^ right)
6970 symbol *tlbl = newiTempLabel(NULL);
6971 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6973 pic16_emitcode("setb","c");
6975 if((AOP_TYPE(right) == AOP_LIT) &&
6976 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6977 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6979 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6980 pic16_emitcode("xrl","a,%s",
6981 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6983 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6988 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6989 pic16_outBitC(result);
6991 jmpTrueOrFalse(ifx, tlbl);
6992 } else for(;(size--);offset++){
6994 // result = left & right
6995 if(AOP_TYPE(right) == AOP_LIT){
6996 int t = (lit >> (offset*8)) & 0x0FFL;
6999 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
7000 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7001 pic16_emitcode("movf","%s,w",
7002 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7003 pic16_emitcode("movwf","%s",
7004 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7007 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7008 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7009 pic16_emitcode("comf","%s,w",
7010 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7011 pic16_emitcode("movwf","%s",
7012 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7015 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7016 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7017 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7018 pic16_emitcode("movlw","0x%x",t);
7019 pic16_emitcode("xorwf","%s,w",
7020 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7021 pic16_emitcode("movwf","%s",
7022 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7028 // faster than result <- left, anl result,right
7029 // and better if result is SFR
7030 if (AOP_TYPE(left) == AOP_ACC) {
7031 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7032 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7034 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7035 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7036 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7037 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7039 if ( AOP_TYPE(result) != AOP_ACC){
7040 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7041 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7047 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7048 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7049 pic16_freeAsmop(result,NULL,ic,TRUE);
7052 /*-----------------------------------------------------------------*/
7053 /* genInline - write the inline code out */
7054 /*-----------------------------------------------------------------*/
7055 static void genInline (iCode *ic)
7057 char *buffer, *bp, *bp1;
7059 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7061 _G.inLine += (!options.asmpeep);
7063 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7064 strcpy(buffer,IC_INLINE(ic));
7066 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7068 /* emit each line as a code */
7074 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7082 /* print label, use this special format with NULL directive
7083 * to denote that the argument should not be indented with tab */
7084 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7091 if ((bp1 != bp) && *bp1)
7092 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7097 _G.inLine -= (!options.asmpeep);
7100 /*-----------------------------------------------------------------*/
7101 /* genRRC - rotate right with carry */
7102 /*-----------------------------------------------------------------*/
7103 static void genRRC (iCode *ic)
7105 operand *left , *result ;
7106 int size, offset = 0, same;
7108 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7110 /* rotate right with carry */
7112 result=IC_RESULT(ic);
7113 pic16_aopOp (left,ic,FALSE);
7114 pic16_aopOp (result,ic,FALSE);
7116 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7118 same = pic16_sameRegs(AOP(result),AOP(left));
7120 size = AOP_SIZE(result);
7122 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7124 /* get the lsb and put it into the carry */
7125 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7132 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7134 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7135 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7141 pic16_freeAsmop(left,NULL,ic,TRUE);
7142 pic16_freeAsmop(result,NULL,ic,TRUE);
7145 /*-----------------------------------------------------------------*/
7146 /* genRLC - generate code for rotate left with carry */
7147 /*-----------------------------------------------------------------*/
7148 static void genRLC (iCode *ic)
7150 operand *left , *result ;
7151 int size, offset = 0;
7154 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7155 /* rotate right with carry */
7157 result=IC_RESULT(ic);
7158 pic16_aopOp (left,ic,FALSE);
7159 pic16_aopOp (result,ic,FALSE);
7161 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7163 same = pic16_sameRegs(AOP(result),AOP(left));
7165 /* move it to the result */
7166 size = AOP_SIZE(result);
7168 /* get the msb and put it into the carry */
7169 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7176 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7178 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7179 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7186 pic16_freeAsmop(left,NULL,ic,TRUE);
7187 pic16_freeAsmop(result,NULL,ic,TRUE);
7191 /* gpasm can get the highest order bit with HIGH/UPPER
7192 * so the following probably is not needed -- VR */
7194 /*-----------------------------------------------------------------*/
7195 /* genGetHbit - generates code get highest order bit */
7196 /*-----------------------------------------------------------------*/
7197 static void genGetHbit (iCode *ic)
7199 operand *left, *result;
7201 result=IC_RESULT(ic);
7202 pic16_aopOp (left,ic,FALSE);
7203 pic16_aopOp (result,ic,FALSE);
7205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7206 /* get the highest order byte into a */
7207 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7208 if(AOP_TYPE(result) == AOP_CRY){
7209 pic16_emitcode("rlc","a");
7210 pic16_outBitC(result);
7213 pic16_emitcode("rl","a");
7214 pic16_emitcode("anl","a,#0x01");
7215 pic16_outAcc(result);
7219 pic16_freeAsmop(left,NULL,ic,TRUE);
7220 pic16_freeAsmop(result,NULL,ic,TRUE);
7224 /*-----------------------------------------------------------------*/
7225 /* AccRol - rotate left accumulator by known count */
7226 /*-----------------------------------------------------------------*/
7227 static void AccRol (int shCount)
7229 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7230 shCount &= 0x0007; // shCount : 0..7
7235 pic16_emitcode("rl","a");
7238 pic16_emitcode("rl","a");
7239 pic16_emitcode("rl","a");
7242 pic16_emitcode("swap","a");
7243 pic16_emitcode("rr","a");
7246 pic16_emitcode("swap","a");
7249 pic16_emitcode("swap","a");
7250 pic16_emitcode("rl","a");
7253 pic16_emitcode("rr","a");
7254 pic16_emitcode("rr","a");
7257 pic16_emitcode("rr","a");
7263 /*-----------------------------------------------------------------*/
7264 /* AccLsh - left shift accumulator by known count */
7265 /*-----------------------------------------------------------------*/
7266 static void AccLsh (int shCount)
7268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7274 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7277 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7278 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7281 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7282 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7285 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7288 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7289 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7292 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7293 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7296 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7300 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7303 /*-----------------------------------------------------------------*/
7304 /* AccRsh - right shift accumulator by known count */
7305 /*-----------------------------------------------------------------*/
7306 static void AccRsh (int shCount, int andmask)
7308 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7313 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7314 // andmask = 0; /* no need */
7317 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7318 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7319 // andmask = 0; /* no need */
7322 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7323 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7326 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7329 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7330 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7333 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7334 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7337 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7342 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
7344 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
7348 /*-----------------------------------------------------------------*/
7349 /* AccSRsh - signed right shift accumulator by known count */
7350 /*-----------------------------------------------------------------*/
7351 static void AccSRsh (int shCount)
7354 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7357 pic16_emitcode("mov","c,acc.7");
7358 pic16_emitcode("rrc","a");
7359 } else if(shCount == 2){
7360 pic16_emitcode("mov","c,acc.7");
7361 pic16_emitcode("rrc","a");
7362 pic16_emitcode("mov","c,acc.7");
7363 pic16_emitcode("rrc","a");
7365 tlbl = newiTempLabel(NULL);
7366 /* rotate right accumulator */
7367 AccRol(8 - shCount);
7368 /* and kill the higher order bits */
7369 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
7370 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
7371 pic16_emitcode("orl","a,#0x%02x",
7372 (unsigned char)~SRMask[shCount]);
7373 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7378 /*-----------------------------------------------------------------*/
7379 /* shiftR1Left2Result - shift right one byte from left to result */
7380 /*-----------------------------------------------------------------*/
7381 static void shiftR1Left2ResultSigned (operand *left, int offl,
7382 operand *result, int offr,
7387 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7389 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7393 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7395 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7397 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7398 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7404 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7406 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7408 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7409 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7411 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7412 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7418 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7420 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7421 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7424 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7425 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7426 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7428 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7429 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
7431 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7435 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7436 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7437 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7438 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
7439 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7443 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7445 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7446 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7448 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7449 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
7450 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7451 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
7452 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7457 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7458 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7459 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
7460 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7461 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
7462 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7464 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7465 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7466 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7467 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7468 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
7474 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7475 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7476 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7477 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7479 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7480 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7481 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7489 /*-----------------------------------------------------------------*/
7490 /* shiftR1Left2Result - shift right one byte from left to result */
7491 /*-----------------------------------------------------------------*/
7492 static void shiftR1Left2Result (operand *left, int offl,
7493 operand *result, int offr,
7494 int shCount, int sign)
7498 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7500 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7502 /* Copy the msb into the carry if signed. */
7504 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
7514 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7516 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7517 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7523 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7525 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7526 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7529 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7534 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7536 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7537 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7540 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7541 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7542 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7543 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7547 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7548 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7549 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7553 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7554 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7555 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7557 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7562 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7563 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7564 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7565 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7566 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7571 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7572 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7573 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7582 /*-----------------------------------------------------------------*/
7583 /* shiftL1Left2Result - shift left one byte from left to result */
7584 /*-----------------------------------------------------------------*/
7585 static void shiftL1Left2Result (operand *left, int offl,
7586 operand *result, int offr, int shCount)
7591 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7593 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7594 DEBUGpic16_emitcode ("; ***","same = %d",same);
7595 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7597 /* shift left accumulator */
7598 //AccLsh(shCount); // don't comment out just yet...
7599 // pic16_aopPut(AOP(result),"a",offr);
7603 /* Shift left 1 bit position */
7604 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7606 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7608 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7609 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7613 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7614 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7615 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7616 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7619 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7620 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7621 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7622 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7623 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7626 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7627 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7628 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7631 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7632 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7633 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7634 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7637 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7638 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7639 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7640 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7641 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7644 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7645 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7646 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7650 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7655 /*-----------------------------------------------------------------*/
7656 /* movLeft2Result - move byte from left to result */
7657 /*-----------------------------------------------------------------*/
7658 static void movLeft2Result (operand *left, int offl,
7659 operand *result, int offr)
7662 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7663 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7664 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7666 if (*l == '@' && (IS_AOP_PREG(result))) {
7667 pic16_emitcode("mov","a,%s",l);
7668 pic16_aopPut(AOP(result),"a",offr);
7670 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7671 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7676 /*-----------------------------------------------------------------*/
7677 /* shiftL2Left2Result - shift left two bytes from left to result */
7678 /*-----------------------------------------------------------------*/
7679 static void shiftL2Left2Result (operand *left, int offl,
7680 operand *result, int offr, int shCount)
7682 int same = pic16_sameRegs(AOP(result), AOP(left));
7685 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7687 if (same && (offl != offr)) { // shift bytes
7690 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7691 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7693 } else { // just treat as different later on
7706 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7707 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7708 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7712 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7713 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7720 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7721 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7722 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7723 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7724 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7725 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7727 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7728 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7732 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7733 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7734 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7735 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7736 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7737 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7738 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7739 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7740 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7741 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7744 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7745 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7746 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7747 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7748 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7758 /* note, use a mov/add for the shift since the mov has a
7759 chance of getting optimized out */
7760 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7761 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7762 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7763 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7764 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7768 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7769 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7775 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7776 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7777 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7778 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7779 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7780 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7781 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7782 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7786 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7787 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7791 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7792 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7793 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7794 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7796 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7797 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7798 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7799 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7800 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7801 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7802 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7803 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7806 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7807 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7808 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7809 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7810 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7815 /*-----------------------------------------------------------------*/
7816 /* shiftR2Left2Result - shift right two bytes from left to result */
7817 /*-----------------------------------------------------------------*/
7818 static void shiftR2Left2Result (operand *left, int offl,
7819 operand *result, int offr,
7820 int shCount, int sign)
7822 int same = pic16_sameRegs(AOP(result), AOP(left));
7824 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7826 if (same && (offl != offr)) { // shift right bytes
7829 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7830 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7832 } else { // just treat as different later on
7844 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7849 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7850 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7852 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7853 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7854 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7855 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7860 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7863 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7864 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7871 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7872 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7873 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7875 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7876 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7877 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7878 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7880 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7881 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7882 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7884 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7885 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7886 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7887 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7888 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7892 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7893 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7897 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7898 pic16_emitpcode(POC_BTFSC,
7899 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7900 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7908 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7909 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7911 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7912 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7913 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7914 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7916 pic16_emitpcode(POC_BTFSC,
7917 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7918 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7920 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7921 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7922 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7923 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7925 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7926 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7927 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7928 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7929 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7930 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7931 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7932 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7934 pic16_emitpcode(POC_BTFSC,
7935 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7936 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7938 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7939 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7946 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7947 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7948 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7949 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7952 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7954 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7959 /*-----------------------------------------------------------------*/
7960 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7961 /*-----------------------------------------------------------------*/
7962 static void shiftLLeftOrResult (operand *left, int offl,
7963 operand *result, int offr, int shCount)
7965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7967 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7968 /* shift left accumulator */
7970 /* or with result */
7971 /* back to result */
7972 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7975 /*-----------------------------------------------------------------*/
7976 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7977 /*-----------------------------------------------------------------*/
7978 static void shiftRLeftOrResult (operand *left, int offl,
7979 operand *result, int offr, int shCount)
7981 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7983 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7984 /* shift right accumulator */
7986 /* or with result */
7987 /* back to result */
7988 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7991 /*-----------------------------------------------------------------*/
7992 /* genlshOne - left shift a one byte quantity by known count */
7993 /*-----------------------------------------------------------------*/
7994 static void genlshOne (operand *result, operand *left, int shCount)
7996 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7997 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8000 /*-----------------------------------------------------------------*/
8001 /* genlshTwo - left shift two bytes by known amount != 0 */
8002 /*-----------------------------------------------------------------*/
8003 static void genlshTwo (operand *result,operand *left, int shCount)
8007 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8008 size = pic16_getDataSize(result);
8010 /* if shCount >= 8 */
8016 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8018 movLeft2Result(left, LSB, result, MSB16);
8020 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8023 /* 1 <= shCount <= 7 */
8026 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8028 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8032 /*-----------------------------------------------------------------*/
8033 /* shiftLLong - shift left one long from left to result */
8034 /* offr = LSB or MSB16 */
8035 /*-----------------------------------------------------------------*/
8036 static void shiftLLong (operand *left, operand *result, int offr )
8038 int size = AOP_SIZE(result);
8039 int same = pic16_sameRegs(AOP(left),AOP(result));
8042 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8044 if (same && (offr == MSB16)) { //shift one byte
8045 for(i=size-1;i>=MSB16;i--) {
8046 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8047 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8050 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8053 if (size >= LSB+offr ){
8055 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8057 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8058 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8062 if(size >= MSB16+offr){
8064 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8066 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8067 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8071 if(size >= MSB24+offr){
8073 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8075 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8076 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8080 if(size > MSB32+offr){
8082 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8084 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8085 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8089 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8093 /*-----------------------------------------------------------------*/
8094 /* genlshFour - shift four byte by a known amount != 0 */
8095 /*-----------------------------------------------------------------*/
8096 static void genlshFour (operand *result, operand *left, int shCount)
8100 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8101 size = AOP_SIZE(result);
8103 /* if shifting more that 3 bytes */
8104 if (shCount >= 24 ) {
8107 /* lowest order of left goes to the highest
8108 order of the destination */
8109 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8111 movLeft2Result(left, LSB, result, MSB32);
8113 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8114 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8115 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8120 /* more than two bytes */
8121 else if ( shCount >= 16 ) {
8122 /* lower order two bytes goes to higher order two bytes */
8124 /* if some more remaining */
8126 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8128 movLeft2Result(left, MSB16, result, MSB32);
8129 movLeft2Result(left, LSB, result, MSB24);
8131 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8132 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8136 /* if more than 1 byte */
8137 else if ( shCount >= 8 ) {
8138 /* lower order three bytes goes to higher order three bytes */
8142 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8144 movLeft2Result(left, LSB, result, MSB16);
8146 else{ /* size = 4 */
8148 movLeft2Result(left, MSB24, result, MSB32);
8149 movLeft2Result(left, MSB16, result, MSB24);
8150 movLeft2Result(left, LSB, result, MSB16);
8151 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8153 else if(shCount == 1)
8154 shiftLLong(left, result, MSB16);
8156 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8157 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8158 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8159 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8164 /* 1 <= shCount <= 7 */
8165 else if(shCount <= 3)
8167 shiftLLong(left, result, LSB);
8168 while(--shCount >= 1)
8169 shiftLLong(result, result, LSB);
8171 /* 3 <= shCount <= 7, optimize */
8173 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8174 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8175 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8179 /*-----------------------------------------------------------------*/
8180 /* genLeftShiftLiteral - left shifting by known count */
8181 /*-----------------------------------------------------------------*/
8182 static void genLeftShiftLiteral (operand *left,
8187 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8190 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8191 pic16_freeAsmop(right,NULL,ic,TRUE);
8193 pic16_aopOp(left,ic,FALSE);
8194 pic16_aopOp(result,ic,FALSE);
8196 size = getSize(operandType(result));
8199 pic16_emitcode("; shift left ","result %d, left %d",size,
8203 /* I suppose that the left size >= result size */
8206 movLeft2Result(left, size, result, size);
8210 else if(shCount >= (size * 8))
8212 pic16_aopPut(AOP(result),zero,size);
8216 genlshOne (result,left,shCount);
8221 genlshTwo (result,left,shCount);
8225 genlshFour (result,left,shCount);
8229 pic16_freeAsmop(left,NULL,ic,TRUE);
8230 pic16_freeAsmop(result,NULL,ic,TRUE);
8233 /*-----------------------------------------------------------------*
8234 * genMultiAsm - repeat assembly instruction for size of register.
8235 * if endian == 1, then the high byte (i.e base address + size of
8236 * register) is used first else the low byte is used first;
8237 *-----------------------------------------------------------------*/
8238 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8256 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8261 /*-----------------------------------------------------------------*/
8262 /* genLeftShift - generates code for left shifting */
8263 /*-----------------------------------------------------------------*/
8264 static void genLeftShift (iCode *ic)
8266 operand *left,*right, *result;
8269 symbol *tlbl , *tlbl1;
8272 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8274 right = IC_RIGHT(ic);
8276 result = IC_RESULT(ic);
8278 pic16_aopOp(right,ic,FALSE);
8280 /* if the shift count is known then do it
8281 as efficiently as possible */
8282 if (AOP_TYPE(right) == AOP_LIT) {
8283 genLeftShiftLiteral (left,right,result,ic);
8287 /* shift count is unknown then we have to form
8288 a loop get the loop count in B : Note: we take
8289 only the lower order byte since shifting
8290 more that 32 bits make no sense anyway, ( the
8291 largest size of an object can be only 32 bits ) */
8294 pic16_aopOp(left,ic,FALSE);
8295 pic16_aopOp(result,ic,FALSE);
8297 /* now move the left to the result if they are not the
8299 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8300 AOP_SIZE(result) > 1) {
8302 size = AOP_SIZE(result);
8305 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8306 if (*l == '@' && (IS_AOP_PREG(result))) {
8308 pic16_emitcode("mov","a,%s",l);
8309 pic16_aopPut(AOP(result),"a",offset);
8311 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8312 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8313 //pic16_aopPut(AOP(result),l,offset);
8319 size = AOP_SIZE(result);
8321 /* if it is only one byte then */
8323 if(optimized_for_speed) {
8324 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8325 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8326 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
8327 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8328 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8329 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
8330 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8331 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8332 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8333 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8334 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
8335 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8338 tlbl = newiTempLabel(NULL);
8339 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8340 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8341 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8344 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8345 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8346 pic16_emitpLabel(tlbl->key);
8347 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8348 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8350 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8355 if (pic16_sameRegs(AOP(left),AOP(result))) {
8357 tlbl = newiTempLabel(NULL);
8358 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8359 genMultiAsm(POC_RRCF, result, size,1);
8360 pic16_emitpLabel(tlbl->key);
8361 genMultiAsm(POC_RLCF, result, size,0);
8362 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8364 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8368 //tlbl = newiTempLabel(NULL);
8370 //tlbl1 = newiTempLabel(NULL);
8372 //reAdjustPreg(AOP(result));
8374 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8375 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8376 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8378 //pic16_emitcode("add","a,acc");
8379 //pic16_aopPut(AOP(result),"a",offset++);
8381 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8383 // pic16_emitcode("rlc","a");
8384 // pic16_aopPut(AOP(result),"a",offset++);
8386 //reAdjustPreg(AOP(result));
8388 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8389 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8392 tlbl = newiTempLabel(NULL);
8393 tlbl1= newiTempLabel(NULL);
8395 size = AOP_SIZE(result);
8398 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8400 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8402 /* offset should be 0, 1 or 3 */
8404 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8406 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8408 pic16_emitpcode(POC_MOVWF, pctemp);
8411 pic16_emitpLabel(tlbl->key);
8414 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8416 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8418 pic16_emitpcode(POC_DECFSZ, pctemp);
8419 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8420 pic16_emitpLabel(tlbl1->key);
8422 pic16_popReleaseTempReg(pctemp);
8426 pic16_freeAsmop (right,NULL,ic,TRUE);
8427 pic16_freeAsmop(left,NULL,ic,TRUE);
8428 pic16_freeAsmop(result,NULL,ic,TRUE);
8431 /*-----------------------------------------------------------------*/
8432 /* genrshOne - right shift a one byte quantity by known count */
8433 /*-----------------------------------------------------------------*/
8434 static void genrshOne (operand *result, operand *left,
8435 int shCount, int sign)
8437 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8438 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
8441 /*-----------------------------------------------------------------*/
8442 /* genrshTwo - right shift two bytes by known amount != 0 */
8443 /*-----------------------------------------------------------------*/
8444 static void genrshTwo (operand *result,operand *left,
8445 int shCount, int sign)
8447 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8448 /* if shCount >= 8 */
8452 shiftR1Left2Result(left, MSB16, result, LSB,
8455 movLeft2Result(left, MSB16, result, LSB);
8457 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8460 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
8461 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
8465 /* 1 <= shCount <= 7 */
8467 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
8470 /*-----------------------------------------------------------------*/
8471 /* shiftRLong - shift right one long from left to result */
8472 /* offl = LSB or MSB16 */
8473 /*-----------------------------------------------------------------*/
8474 static void shiftRLong (operand *left, int offl,
8475 operand *result, int sign)
8477 int size = AOP_SIZE(result);
8478 int same = pic16_sameRegs(AOP(left),AOP(result));
8480 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
8482 if (same && (offl == MSB16)) { //shift one byte right
8483 for(i=MSB16;i<size;i++) {
8484 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
8485 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
8490 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
8496 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
8498 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
8499 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
8503 /* add sign of "a" */
8504 pic16_addSign(result, MSB32, sign);
8508 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
8510 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
8511 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
8515 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
8517 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
8518 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
8522 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
8525 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
8526 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
8531 /*-----------------------------------------------------------------*/
8532 /* genrshFour - shift four byte by a known amount != 0 */
8533 /*-----------------------------------------------------------------*/
8534 static void genrshFour (operand *result, operand *left,
8535 int shCount, int sign)
8537 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8538 /* if shifting more that 3 bytes */
8539 if(shCount >= 24 ) {
8542 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8544 movLeft2Result(left, MSB32, result, LSB);
8546 pic16_addSign(result, MSB16, sign);
8548 else if(shCount >= 16){
8551 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8553 movLeft2Result(left, MSB24, result, LSB);
8554 movLeft2Result(left, MSB32, result, MSB16);
8556 pic16_addSign(result, MSB24, sign);
8558 else if(shCount >= 8){
8561 shiftRLong(left, MSB16, result, sign);
8562 else if(shCount == 0){
8563 movLeft2Result(left, MSB16, result, LSB);
8564 movLeft2Result(left, MSB24, result, MSB16);
8565 movLeft2Result(left, MSB32, result, MSB24);
8566 pic16_addSign(result, MSB32, sign);
8568 else{ //shcount >= 2
8569 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8570 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8571 /* the last shift is signed */
8572 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8573 pic16_addSign(result, MSB32, sign);
8576 else{ /* 1 <= shCount <= 7 */
8578 shiftRLong(left, LSB, result, sign);
8580 shiftRLong(result, LSB, result, sign);
8583 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8584 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8585 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8590 /*-----------------------------------------------------------------*/
8591 /* genRightShiftLiteral - right shifting by known count */
8592 /*-----------------------------------------------------------------*/
8593 static void genRightShiftLiteral (operand *left,
8599 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8602 pic16_freeAsmop(right,NULL,ic,TRUE);
8604 pic16_aopOp(left,ic,FALSE);
8605 pic16_aopOp(result,ic,FALSE);
8607 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8610 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8614 lsize = pic16_getDataSize(left);
8615 res_size = pic16_getDataSize(result);
8616 /* test the LEFT size !!! */
8618 /* I suppose that the left size >= result size */
8621 movLeft2Result(left, lsize, result, res_size);
8624 else if(shCount >= (lsize * 8)){
8627 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8629 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8630 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8635 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8636 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8637 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8639 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8644 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8651 genrshOne (result,left,shCount,sign);
8655 genrshTwo (result,left,shCount,sign);
8659 genrshFour (result,left,shCount,sign);
8667 pic16_freeAsmop(left,NULL,ic,TRUE);
8668 pic16_freeAsmop(result,NULL,ic,TRUE);
8671 /*-----------------------------------------------------------------*/
8672 /* genSignedRightShift - right shift of signed number */
8673 /*-----------------------------------------------------------------*/
8674 static void genSignedRightShift (iCode *ic)
8676 operand *right, *left, *result;
8679 symbol *tlbl, *tlbl1 ;
8682 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8684 /* we do it the hard way put the shift count in b
8685 and loop thru preserving the sign */
8686 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8688 right = IC_RIGHT(ic);
8690 result = IC_RESULT(ic);
8692 pic16_aopOp(right,ic,FALSE);
8693 pic16_aopOp(left,ic,FALSE);
8694 pic16_aopOp(result,ic,FALSE);
8697 if ( AOP_TYPE(right) == AOP_LIT) {
8698 genRightShiftLiteral (left,right,result,ic,1);
8701 /* shift count is unknown then we have to form
8702 a loop get the loop count in B : Note: we take
8703 only the lower order byte since shifting
8704 more that 32 bits make no sense anyway, ( the
8705 largest size of an object can be only 32 bits ) */
8707 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8708 //pic16_emitcode("inc","b");
8709 //pic16_freeAsmop (right,NULL,ic,TRUE);
8710 //pic16_aopOp(left,ic,FALSE);
8711 //pic16_aopOp(result,ic,FALSE);
8713 /* now move the left to the result if they are not the
8715 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8716 AOP_SIZE(result) > 1) {
8718 size = AOP_SIZE(result);
8722 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8723 if (*l == '@' && IS_AOP_PREG(result)) {
8725 pic16_emitcode("mov","a,%s",l);
8726 pic16_aopPut(AOP(result),"a",offset);
8728 pic16_aopPut(AOP(result),l,offset);
8730 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8731 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8737 /* mov the highest order bit to OVR */
8738 tlbl = newiTempLabel(NULL);
8739 tlbl1= newiTempLabel(NULL);
8741 size = AOP_SIZE(result);
8744 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8746 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8748 /* offset should be 0, 1 or 3 */
8749 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8751 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8753 pic16_emitpcode(POC_MOVWF, pctemp);
8756 pic16_emitpLabel(tlbl->key);
8758 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8759 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8762 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8765 pic16_emitpcode(POC_DECFSZ, pctemp);
8766 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8767 pic16_emitpLabel(tlbl1->key);
8769 pic16_popReleaseTempReg(pctemp);
8771 size = AOP_SIZE(result);
8773 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8774 pic16_emitcode("rlc","a");
8775 pic16_emitcode("mov","ov,c");
8776 /* if it is only one byte then */
8778 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8780 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8781 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8782 pic16_emitcode("mov","c,ov");
8783 pic16_emitcode("rrc","a");
8784 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8785 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8786 pic16_aopPut(AOP(result),"a",0);
8790 reAdjustPreg(AOP(result));
8791 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8792 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8793 pic16_emitcode("mov","c,ov");
8795 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8797 pic16_emitcode("rrc","a");
8798 pic16_aopPut(AOP(result),"a",offset--);
8800 reAdjustPreg(AOP(result));
8801 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8802 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8807 pic16_freeAsmop(left,NULL,ic,TRUE);
8808 pic16_freeAsmop(result,NULL,ic,TRUE);
8809 pic16_freeAsmop(right,NULL,ic,TRUE);
8812 /*-----------------------------------------------------------------*/
8813 /* genRightShift - generate code for right shifting */
8814 /*-----------------------------------------------------------------*/
8815 static void genRightShift (iCode *ic)
8817 operand *right, *left, *result;
8821 symbol *tlbl, *tlbl1 ;
8823 /* if signed then we do it the hard way preserve the
8824 sign bit moving it inwards */
8825 letype = getSpec(operandType(IC_LEFT(ic)));
8826 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8828 if (!SPEC_USIGN(letype)) {
8829 genSignedRightShift (ic);
8833 /* signed & unsigned types are treated the same : i.e. the
8834 signed is NOT propagated inwards : quoting from the
8835 ANSI - standard : "for E1 >> E2, is equivalent to division
8836 by 2**E2 if unsigned or if it has a non-negative value,
8837 otherwise the result is implementation defined ", MY definition
8838 is that the sign does not get propagated */
8840 right = IC_RIGHT(ic);
8842 result = IC_RESULT(ic);
8844 pic16_aopOp(right,ic,FALSE);
8846 /* if the shift count is known then do it
8847 as efficiently as possible */
8848 if (AOP_TYPE(right) == AOP_LIT) {
8849 genRightShiftLiteral (left,right,result,ic, 0);
8853 /* shift count is unknown then we have to form
8854 a loop get the loop count in B : Note: we take
8855 only the lower order byte since shifting
8856 more that 32 bits make no sense anyway, ( the
8857 largest size of an object can be only 32 bits ) */
8859 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8860 pic16_emitcode("inc","b");
8861 pic16_aopOp(left,ic,FALSE);
8862 pic16_aopOp(result,ic,FALSE);
8864 /* now move the left to the result if they are not the
8866 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8867 AOP_SIZE(result) > 1) {
8869 size = AOP_SIZE(result);
8872 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8873 if (*l == '@' && IS_AOP_PREG(result)) {
8875 pic16_emitcode("mov","a,%s",l);
8876 pic16_aopPut(AOP(result),"a",offset);
8878 pic16_aopPut(AOP(result),l,offset);
8883 tlbl = newiTempLabel(NULL);
8884 tlbl1= newiTempLabel(NULL);
8885 size = AOP_SIZE(result);
8888 /* if it is only one byte then */
8891 tlbl = newiTempLabel(NULL);
8892 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8893 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8894 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8897 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8898 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8899 pic16_emitpLabel(tlbl->key);
8900 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8901 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8903 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8908 reAdjustPreg(AOP(result));
8909 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8910 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8913 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8915 pic16_emitcode("rrc","a");
8916 pic16_aopPut(AOP(result),"a",offset--);
8918 reAdjustPreg(AOP(result));
8920 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8921 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8924 pic16_freeAsmop(left,NULL,ic,TRUE);
8925 pic16_freeAsmop (right,NULL,ic,TRUE);
8926 pic16_freeAsmop(result,NULL,ic,TRUE);
8929 /*-----------------------------------------------------------------*/
8930 /* genUnpackBits - generates code for unpacking bits */
8931 /*-----------------------------------------------------------------*/
8932 static void genUnpackBits (operand *result, char *rname, int ptype)
8939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8940 etype = getSpec(operandType(result));
8942 /* read the first byte */
8949 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8952 pic16_emitcode("clr","a");
8953 pic16_emitcode("movc","a","@a+dptr");
8958 /* if we have bitdisplacement then it fits */
8959 /* into this byte completely or if length is */
8960 /* less than a byte */
8961 if ((shCnt = SPEC_BSTR(etype)) ||
8962 (SPEC_BLEN(etype) <= 8)) {
8964 /* shift right acc */
8967 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8968 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8970 /* VR -- normally I would use the following, but since we use the hack,
8971 * to avoid the masking from AccRsh, why not mask it right now? */
8974 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8977 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8983 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8984 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8987 /* bit field did not fit in a byte */
8988 rlen = SPEC_BLEN(etype) - 8;
8989 pic16_aopPut(AOP(result),"a",offset++);
8996 pic16_emitcode("inc","%s",rname);
8997 pic16_emitcode("mov","a,@%s",rname);
9001 pic16_emitcode("inc","%s",rname);
9002 pic16_emitcode("movx","a,@%s",rname);
9006 pic16_emitcode("inc","dptr");
9007 pic16_emitcode("movx","a,@dptr");
9011 pic16_emitcode("clr","a");
9012 pic16_emitcode("inc","dptr");
9013 pic16_emitcode("movc","a","@a+dptr");
9017 pic16_emitcode("inc","dptr");
9018 pic16_emitcode("lcall","__gptrget");
9023 /* if we are done */
9027 pic16_aopPut(AOP(result),"a",offset++);
9032 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9033 pic16_aopPut(AOP(result),"a",offset);
9040 static void genDataPointerGet(operand *left,
9044 int size, offset = 0, leoffset=0 ;
9046 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9047 pic16_aopOp(result, ic, FALSE);
9049 size = AOP_SIZE(result);
9050 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9054 /* The following tests may save a redudant movff instruction when
9055 * accessing unions */
9057 /* if they are the same */
9058 if (operandsEqu (left, result)) {
9059 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9065 /* if they are the same registers */
9066 if (pic16_sameRegs(AOP(left),AOP(result))) {
9067 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9073 if ( AOP_TYPE(left) == AOP_PCODE) {
9074 fprintf(stderr,"genDataPointerGet %s, %d\n",
9075 AOP(left)->aopu.pcop->name,
9076 (AOP(left)->aopu.pcop->type == PO_DIR)?
9077 PCOR(AOP(left)->aopu.pcop)->instance:
9078 PCOI(AOP(left)->aopu.pcop)->offset);
9082 if(AOP(left)->aopu.pcop->type == PO_DIR)
9083 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
9085 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9088 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
9090 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
9091 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
9092 mov2w(AOP(left), offset); // patch 8
9093 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
9095 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
9096 pic16_popGet(AOP(left), offset), //patch 8
9097 pic16_popGet(AOP(result), offset)));
9105 pic16_freeAsmop(result,NULL,ic,TRUE);
9108 void pic16_loadFSR0(operand *op)
9110 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9114 /*-----------------------------------------------------------------*/
9115 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
9116 /*-----------------------------------------------------------------*/
9117 static void genNearPointerGet (operand *left,
9122 //regs *preg = NULL ;
9123 sym_link *rtype, *retype;
9124 sym_link *ltype = operandType(left);
9126 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9127 rtype = operandType(result);
9128 retype= getSpec(rtype);
9130 pic16_aopOp(left,ic,FALSE);
9132 pic16_DumpOp("(left)",left);
9133 pic16_DumpOp("(result)",result);
9135 /* if left is rematerialisable and
9136 * result is not bit variable type and
9137 * the left is pointer to data space i.e
9138 * lower 128 bytes of space */
9139 if (AOP_TYPE(left) == AOP_PCODE
9140 && !IS_BITFIELD(retype)
9141 && DCL_TYPE(ltype) == POINTER) {
9143 genDataPointerGet (left,result,ic);
9144 pic16_freeAsmop(left, NULL, ic, TRUE);
9148 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9150 /* if the value is already in a pointer register
9151 * then don't need anything more */
9152 if (!AOP_INPREG(AOP(left))) {
9153 /* otherwise get a free pointer register */
9154 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9156 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
9157 if( (AOP_TYPE(left) == AOP_PCODE)
9158 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9159 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
9161 pic16_loadFSR0( left ); // patch 10
9163 // set up FSR0 with address from left
9164 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9165 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9169 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9171 pic16_aopOp (result,ic,FALSE);
9173 /* if bitfield then unpack the bits */
9174 if (IS_BITFIELD(retype))
9175 genUnpackBits (result, NULL, POINTER);
9177 /* we have can just get the values */
9178 int size = AOP_SIZE(result);
9181 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9184 /* fsr0 is loaded already -- VR */
9185 // pic16_loadFSR0( left );
9187 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
9188 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9192 pic16_emitpcode(POC_MOVFF,
9193 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
9194 pic16_popGet(AOP(result), offset++)));
9196 pic16_emitpcode(POC_MOVFF,
9197 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
9198 pic16_popGet(AOP(result), offset++)));
9202 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
9203 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
9205 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9209 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
9211 pic16_emitcode("mov","a,@%s",rname);
9212 pic16_aopPut(AOP(result),"a",offset);
9214 sprintf(buffer,"@%s",rname);
9215 pic16_aopPut(AOP(result),buffer,offset);
9219 pic16_emitcode("inc","%s",rname);
9224 /* now some housekeeping stuff */
9226 /* we had to allocate for this iCode */
9227 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9228 pic16_freeAsmop(NULL,aop,ic,TRUE);
9230 /* we did not allocate which means left
9231 already in a pointer register, then
9232 if size > 0 && this could be used again
9233 we have to point it back to where it
9235 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9236 if (AOP_SIZE(result) > 1 &&
9237 !OP_SYMBOL(left)->remat &&
9238 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9240 // int size = AOP_SIZE(result) - 1;
9242 // pic16_emitcode("dec","%s",rname);
9247 pic16_freeAsmop(left,NULL,ic,TRUE);
9248 pic16_freeAsmop(result,NULL,ic,TRUE);
9252 /*-----------------------------------------------------------------*/
9253 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
9254 /*-----------------------------------------------------------------*/
9255 static void genPagedPointerGet (operand *left,
9262 sym_link *rtype, *retype;
9264 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9266 rtype = operandType(result);
9267 retype= getSpec(rtype);
9269 pic16_aopOp(left,ic,FALSE);
9271 /* if the value is already in a pointer register
9272 then don't need anything more */
9273 if (!AOP_INPREG(AOP(left))) {
9274 /* otherwise get a free pointer register */
9276 preg = getFreePtr(ic,&aop,FALSE);
9277 pic16_emitcode("mov","%s,%s",
9279 pic16_aopGet(AOP(left),0,FALSE,TRUE));
9280 rname = preg->name ;
9282 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9284 pic16_freeAsmop(left,NULL,ic,TRUE);
9285 pic16_aopOp (result,ic,FALSE);
9287 /* if bitfield then unpack the bits */
9288 if (IS_BITFIELD(retype))
9289 genUnpackBits (result,rname,PPOINTER);
9291 /* we have can just get the values */
9292 int size = AOP_SIZE(result);
9297 pic16_emitcode("movx","a,@%s",rname);
9298 pic16_aopPut(AOP(result),"a",offset);
9303 pic16_emitcode("inc","%s",rname);
9307 /* now some housekeeping stuff */
9309 /* we had to allocate for this iCode */
9310 pic16_freeAsmop(NULL,aop,ic,TRUE);
9312 /* we did not allocate which means left
9313 already in a pointer register, then
9314 if size > 0 && this could be used again
9315 we have to point it back to where it
9317 if (AOP_SIZE(result) > 1 &&
9318 !OP_SYMBOL(left)->remat &&
9319 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9321 int size = AOP_SIZE(result) - 1;
9323 pic16_emitcode("dec","%s",rname);
9328 pic16_freeAsmop(result,NULL,ic,TRUE);
9333 /*-----------------------------------------------------------------*/
9334 /* genFarPointerGet - gget value from far space */
9335 /*-----------------------------------------------------------------*/
9336 static void genFarPointerGet (operand *left,
9337 operand *result, iCode *ic)
9340 sym_link *retype = getSpec(operandType(result));
9342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9344 pic16_aopOp(left,ic,FALSE);
9346 /* if the operand is already in dptr
9347 then we do nothing else we move the value to dptr */
9348 if (AOP_TYPE(left) != AOP_STR) {
9349 /* if this is remateriazable */
9350 if (AOP_TYPE(left) == AOP_IMMD)
9351 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9352 else { /* we need to get it byte by byte */
9353 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9354 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9355 if (options.model == MODEL_FLAT24)
9357 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9361 /* so dptr know contains the address */
9362 pic16_freeAsmop(left,NULL,ic,TRUE);
9363 pic16_aopOp(result,ic,FALSE);
9365 /* if bit then unpack */
9366 if (IS_BITFIELD(retype))
9367 genUnpackBits(result,"dptr",FPOINTER);
9369 size = AOP_SIZE(result);
9373 pic16_emitcode("movx","a,@dptr");
9374 pic16_aopPut(AOP(result),"a",offset++);
9376 pic16_emitcode("inc","dptr");
9380 pic16_freeAsmop(result,NULL,ic,TRUE);
9383 /*-----------------------------------------------------------------*/
9384 /* genCodePointerGet - get value from code space */
9385 /*-----------------------------------------------------------------*/
9386 static void genCodePointerGet (operand *left,
9387 operand *result, iCode *ic)
9390 sym_link *retype = getSpec(operandType(result));
9392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9394 pic16_aopOp(left,ic,FALSE);
9396 /* if the operand is already in dptr
9397 then we do nothing else we move the value to dptr */
9398 if (AOP_TYPE(left) != AOP_STR) {
9399 /* if this is remateriazable */
9400 if (AOP_TYPE(left) == AOP_IMMD)
9401 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9402 else { /* we need to get it byte by byte */
9403 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9404 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9405 if (options.model == MODEL_FLAT24)
9407 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9411 /* so dptr know contains the address */
9412 pic16_freeAsmop(left,NULL,ic,TRUE);
9413 pic16_aopOp(result,ic,FALSE);
9415 /* if bit then unpack */
9416 if (IS_BITFIELD(retype))
9417 genUnpackBits(result,"dptr",CPOINTER);
9419 size = AOP_SIZE(result);
9423 pic16_emitcode("clr","a");
9424 pic16_emitcode("movc","a,@a+dptr");
9425 pic16_aopPut(AOP(result),"a",offset++);
9427 pic16_emitcode("inc","dptr");
9431 pic16_freeAsmop(result,NULL,ic,TRUE);
9434 /*-----------------------------------------------------------------*/
9435 /* genGenPointerGet - gget value from generic pointer space */
9436 /*-----------------------------------------------------------------*/
9437 static void genGenPointerGet (operand *left,
9438 operand *result, iCode *ic)
9440 int size, offset, lit;
9441 sym_link *retype = getSpec(operandType(result));
9443 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9444 pic16_aopOp(left,ic,FALSE);
9445 pic16_aopOp(result,ic,FALSE);
9446 size = AOP_SIZE(result);
9448 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9450 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
9452 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
9453 // load FSR0 from immediate
9454 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9456 // pic16_loadFSR0( left );
9461 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9463 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9470 else { /* we need to get it byte by byte */
9471 // set up FSR0 with address from left
9472 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9473 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9479 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9481 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9488 /* if bit then unpack */
9489 if (IS_BITFIELD(retype))
9490 genUnpackBits(result,"BAD",GPOINTER);
9493 pic16_freeAsmop(left,NULL,ic,TRUE);
9494 pic16_freeAsmop(result,NULL,ic,TRUE);
9498 /*-----------------------------------------------------------------*/
9499 /* genConstPointerGet - get value from const generic pointer space */
9500 /*-----------------------------------------------------------------*/
9501 static void genConstPointerGet (operand *left,
9502 operand *result, iCode *ic)
9504 //sym_link *retype = getSpec(operandType(result));
9505 // symbol *albl = newiTempLabel(NULL); // patch 15
9506 // symbol *blbl = newiTempLabel(NULL); //
9507 // PIC_OPCODE poc; // patch 15
9511 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9512 pic16_aopOp(left,ic,FALSE);
9513 pic16_aopOp(result,ic,TRUE);
9514 size = AOP_SIZE(result);
9516 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9518 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
9520 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
9521 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
9522 pic16_emitpLabel(albl->key);
9524 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
9526 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
9527 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
9528 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
9529 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
9530 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
9532 pic16_emitpLabel(blbl->key);
9534 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
9538 // set up table pointer
9539 if( (AOP_TYPE(left) == AOP_PCODE)
9540 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9541 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
9543 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
9544 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
9545 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
9546 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
9547 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
9548 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
9552 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
9553 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
9554 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
9560 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
9561 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
9565 pic16_freeAsmop(left,NULL,ic,TRUE);
9566 pic16_freeAsmop(result,NULL,ic,TRUE);
9569 /*-----------------------------------------------------------------*/
9570 /* genPointerGet - generate code for pointer get */
9571 /*-----------------------------------------------------------------*/
9572 static void genPointerGet (iCode *ic)
9574 operand *left, *result ;
9575 sym_link *type, *etype;
9578 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9581 result = IC_RESULT(ic) ;
9583 /* depending on the type of pointer we need to
9584 move it to the correct pointer register */
9585 type = operandType(left);
9586 etype = getSpec(type);
9589 if (IS_PTR_CONST(type))
9591 if (IS_CODEPTR(type))
9593 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9595 /* if left is of type of pointer then it is simple */
9596 if (IS_PTR(type) && !IS_FUNC(type->next))
9597 p_type = DCL_TYPE(type);
9599 /* we have to go by the storage class */
9600 p_type = PTR_TYPE(SPEC_OCLS(etype));
9602 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9604 if (SPEC_OCLS(etype)->codesp ) {
9605 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9606 //p_type = CPOINTER ;
9609 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9610 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9611 /*p_type = FPOINTER ;*/
9613 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9614 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9615 /* p_type = PPOINTER; */
9617 if (SPEC_OCLS(etype) == idata )
9618 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9619 /* p_type = IPOINTER; */
9621 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9622 /* p_type = POINTER ; */
9625 /* now that we have the pointer type we assign
9626 the pointer values */
9631 genNearPointerGet (left,result,ic);
9635 genPagedPointerGet(left,result,ic);
9639 genFarPointerGet (left,result,ic);
9643 genConstPointerGet (left,result,ic);
9644 //pic16_emitcodePointerGet (left,result,ic);
9649 if (IS_PTR_CONST(type))
9650 genConstPointerGet (left,result,ic);
9653 genGenPointerGet (left,result,ic);
9659 /*-----------------------------------------------------------------*/
9660 /* genPackBits - generates code for packed bit storage */
9661 /*-----------------------------------------------------------------*/
9662 static void genPackBits (sym_link *etype ,
9664 char *rname, int p_type)
9672 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9673 blen = SPEC_BLEN(etype);
9674 bstr = SPEC_BSTR(etype);
9676 if(AOP_TYPE(right) == AOP_LIT) {
9677 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9680 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9682 /* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9685 /* if the bit lenth is less than or */
9686 /* it exactly fits a byte then */
9687 if((shCnt=SPEC_BSTR(etype))
9688 || SPEC_BLEN(etype) <= 8 ) {
9690 /* shift left acc */
9693 /* using PRODL as a temporary register here */
9694 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9700 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9701 // pic16_emitcode ("mov","b,a");
9702 // pic16_emitcode("mov","a,@%s",rname);
9706 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9707 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9708 (unsigned char)(0xff >> (8-bstr))) ));
9709 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9710 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9714 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9715 ((unsigned char)(0xFF << (blen+bstr)) |
9716 (unsigned char)(0xFF >> (8-bstr)) ) );
9717 pic16_emitcode ("orl","a,b");
9718 if (p_type == GPOINTER)
9719 pic16_emitcode("pop","b");
9724 pic16_emitcode("mov","@%s,a",rname);
9727 pic16_emitcode("movx","@dptr,a");
9730 DEBUGpic16_emitcode(";lcall","__gptrput");
9739 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9740 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9745 if ( SPEC_BLEN(etype) <= 8 )
9748 pic16_emitcode("inc","%s",rname);
9749 rLen = SPEC_BLEN(etype) ;
9753 /* now generate for lengths greater than one byte */
9756 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9766 pic16_emitcode("mov","@%s,a",rname);
9768 pic16_emitcode("mov","@%s,%s",rname,l);
9773 pic16_emitcode("movx","@dptr,a");
9778 DEBUGpic16_emitcode(";lcall","__gptrput");
9781 pic16_emitcode ("inc","%s",rname);
9786 /* last last was not complete */
9788 /* save the byte & read byte */
9791 pic16_emitcode ("mov","b,a");
9792 pic16_emitcode("mov","a,@%s",rname);
9796 pic16_emitcode ("mov","b,a");
9797 pic16_emitcode("movx","a,@dptr");
9801 pic16_emitcode ("push","b");
9802 pic16_emitcode ("push","acc");
9803 pic16_emitcode ("lcall","__gptrget");
9804 pic16_emitcode ("pop","b");
9808 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9809 pic16_emitcode ("orl","a,b");
9812 if (p_type == GPOINTER)
9813 pic16_emitcode("pop","b");
9818 pic16_emitcode("mov","@%s,a",rname);
9822 pic16_emitcode("movx","@dptr,a");
9826 DEBUGpic16_emitcode(";lcall","__gptrput");
9830 /*-----------------------------------------------------------------*/
9831 /* genDataPointerSet - remat pointer to data space */
9832 /*-----------------------------------------------------------------*/
9833 static void genDataPointerSet(operand *right,
9837 int size, offset = 0, resoffset=0 ;
9839 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9840 pic16_aopOp(right,ic,FALSE);
9842 size = AOP_SIZE(right);
9844 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9847 if ( AOP_TYPE(result) == AOP_PCODE) {
9848 fprintf(stderr,"genDataPointerSet %s, %d\n",
9849 AOP(result)->aopu.pcop->name,
9850 (AOP(result)->aopu.pcop->type == PO_DIR)?
9851 PCOR(AOP(result)->aopu.pcop)->instance:
9852 PCOI(AOP(result)->aopu.pcop)->offset);
9856 if(AOP(result)->aopu.pcop->type == PO_DIR)
9857 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9860 if (AOP_TYPE(right) == AOP_LIT) {
9861 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9863 lit = lit >> (8*offset);
9865 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9866 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
9868 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
9871 mov2w(AOP(right), offset);
9872 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
9878 pic16_freeAsmop(right,NULL,ic,TRUE);
9883 /*-----------------------------------------------------------------*/
9884 /* genNearPointerSet - pic16_emitcode for near pointer put */
9885 /*-----------------------------------------------------------------*/
9886 static void genNearPointerSet (operand *right,
9893 sym_link *ptype = operandType(result);
9896 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9897 retype= getSpec(operandType(right));
9898 resetype = getSpec(operandType(result));
9900 pic16_aopOp(result,ic,FALSE);
9902 /* if the result is rematerializable &
9903 * in data space & not a bit variable */
9905 /* and result is not a bit variable */
9906 if (AOP_TYPE(result) == AOP_PCODE
9907 // && AOP_TYPE(result) == AOP_IMMD
9908 && DCL_TYPE(ptype) == POINTER
9909 && !IS_BITFIELD(retype)
9910 && !IS_BITFIELD(resetype)) {
9912 genDataPointerSet (right,result,ic);
9913 pic16_freeAsmop(result,NULL,ic,TRUE);
9917 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9918 pic16_aopOp(right,ic,FALSE);
9919 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9921 /* if the value is already in a pointer register
9922 * then don't need anything more */
9923 if (!AOP_INPREG(AOP(result))) {
9924 /* otherwise get a free pointer register */
9925 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9927 if( (AOP_TYPE(result) == AOP_PCODE)
9928 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
9929 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
9931 pic16_loadFSR0( result ); // patch 10
9933 // set up FSR0 with address of result
9934 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9935 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9940 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9942 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9944 /* if bitfield then unpack the bits */
9945 if (IS_BITFIELD(resetype)) {
9946 genPackBits (resetype, right, NULL, POINTER);
9948 /* we have can just get the values */
9949 int size = AOP_SIZE(right);
9952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9954 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9957 //pic16_emitcode("mov","@%s,a",rname);
9958 pic16_emitcode("movf","indf0,w ;1");
9961 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
9962 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
9964 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
9966 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
9968 } else { // no literal //
9970 pic16_emitpcode(POC_MOVFF, //
9971 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9972 pic16_popCopyReg(&pic16_pc_postinc0))); //
9974 pic16_emitpcode(POC_MOVFF, //
9975 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9976 pic16_popCopyReg(&pic16_pc_indf0))); //
9984 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9985 /* now some housekeeping stuff */
9987 /* we had to allocate for this iCode */
9988 pic16_freeAsmop(NULL,aop,ic,TRUE);
9990 /* we did not allocate which means left
9991 * already in a pointer register, then
9992 * if size > 0 && this could be used again
9993 * we have to point it back to where it
9995 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9996 if (AOP_SIZE(right) > 1
9997 && !OP_SYMBOL(result)->remat
9998 && ( OP_SYMBOL(result)->liveTo > ic->seq
10001 int size = AOP_SIZE(right) - 1;
10004 pic16_emitcode("decf","fsr0,f");
10005 //pic16_emitcode("dec","%s",rname);
10009 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10012 pic16_freeAsmop(right,NULL,ic,TRUE);
10013 pic16_freeAsmop(result,NULL,ic,TRUE);
10016 /*-----------------------------------------------------------------*/
10017 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
10018 /*-----------------------------------------------------------------*/
10019 static void genPagedPointerSet (operand *right,
10024 regs *preg = NULL ;
10028 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10030 retype= getSpec(operandType(right));
10032 pic16_aopOp(result,ic,FALSE);
10034 /* if the value is already in a pointer register
10035 then don't need anything more */
10036 if (!AOP_INPREG(AOP(result))) {
10037 /* otherwise get a free pointer register */
10039 preg = getFreePtr(ic,&aop,FALSE);
10040 pic16_emitcode("mov","%s,%s",
10042 pic16_aopGet(AOP(result),0,FALSE,TRUE));
10043 rname = preg->name ;
10045 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10047 pic16_freeAsmop(result,NULL,ic,TRUE);
10048 pic16_aopOp (right,ic,FALSE);
10050 /* if bitfield then unpack the bits */
10051 if (IS_BITFIELD(retype))
10052 genPackBits (retype,right,rname,PPOINTER);
10054 /* we have can just get the values */
10055 int size = AOP_SIZE(right);
10059 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10062 pic16_emitcode("movx","@%s,a",rname);
10065 pic16_emitcode("inc","%s",rname);
10071 /* now some housekeeping stuff */
10073 /* we had to allocate for this iCode */
10074 pic16_freeAsmop(NULL,aop,ic,TRUE);
10076 /* we did not allocate which means left
10077 already in a pointer register, then
10078 if size > 0 && this could be used again
10079 we have to point it back to where it
10081 if (AOP_SIZE(right) > 1 &&
10082 !OP_SYMBOL(result)->remat &&
10083 ( OP_SYMBOL(result)->liveTo > ic->seq ||
10085 int size = AOP_SIZE(right) - 1;
10087 pic16_emitcode("dec","%s",rname);
10092 pic16_freeAsmop(right,NULL,ic,TRUE);
10097 /*-----------------------------------------------------------------*/
10098 /* genFarPointerSet - set value from far space */
10099 /*-----------------------------------------------------------------*/
10100 static void genFarPointerSet (operand *right,
10101 operand *result, iCode *ic)
10104 sym_link *retype = getSpec(operandType(right));
10106 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10107 pic16_aopOp(result,ic,FALSE);
10109 /* if the operand is already in dptr
10110 then we do nothing else we move the value to dptr */
10111 if (AOP_TYPE(result) != AOP_STR) {
10112 /* if this is remateriazable */
10113 if (AOP_TYPE(result) == AOP_IMMD)
10114 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
10115 else { /* we need to get it byte by byte */
10116 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
10117 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
10118 if (options.model == MODEL_FLAT24)
10120 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
10124 /* so dptr know contains the address */
10125 pic16_freeAsmop(result,NULL,ic,TRUE);
10126 pic16_aopOp(right,ic,FALSE);
10128 /* if bit then unpack */
10129 if (IS_BITFIELD(retype))
10130 genPackBits(retype,right,"dptr",FPOINTER);
10132 size = AOP_SIZE(right);
10136 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10138 pic16_emitcode("movx","@dptr,a");
10140 pic16_emitcode("inc","dptr");
10144 pic16_freeAsmop(right,NULL,ic,TRUE);
10147 /*-----------------------------------------------------------------*/
10148 /* genGenPointerSet - set value from generic pointer space */
10149 /*-----------------------------------------------------------------*/
10150 static void genGenPointerSet (operand *right,
10151 operand *result, iCode *ic)
10153 int i, size, offset, lit;
10154 sym_link *retype = getSpec(operandType(right));
10156 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10158 pic16_aopOp(result,ic,FALSE);
10159 pic16_aopOp(right,ic,FALSE);
10160 size = AOP_SIZE(right);
10163 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10165 /* if the operand is already in dptr
10166 then we do nothing else we move the value to dptr */
10167 if (AOP_TYPE(result) != AOP_STR) {
10168 /* if this is remateriazable */
10169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10170 // WARNING: anythig until "else" is untested!
10171 if (AOP_TYPE(result) == AOP_IMMD) {
10172 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10173 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
10174 // load FSR0 from immediate
10175 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10179 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10181 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10187 else { /* we need to get it byte by byte */
10188 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10189 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10191 // set up FSR0 with address of result
10192 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10193 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10195 /* hack hack! see if this the FSR. If so don't load W */
10196 if(AOP_TYPE(right) != AOP_ACC) {
10198 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10200 if(AOP_TYPE(right) == AOP_LIT)
10203 // note: pic16_popGet handles sign extension
10204 for(i=0;i<size;i++) {
10205 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
10207 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
10209 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10214 for(i=0;i<size;i++) {
10216 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10217 pic16_popCopyReg(&pic16_pc_postinc0)));
10219 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10220 pic16_popCopyReg(&pic16_pc_indf0)));
10226 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10227 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10229 } // if (AOP_TYPE(result) != AOP_IMMD)
10231 } // if (AOP_TYPE(result) != AOP_STR)
10232 /* so dptr know contains the address */
10235 /* if bit then unpack */
10236 if (IS_BITFIELD(retype))
10237 genPackBits(retype,right,"dptr",GPOINTER);
10239 size = AOP_SIZE(right);
10242 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
10244 // set up FSR0 with address of result
10245 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10246 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10249 if (AOP_TYPE(right) == AOP_LIT) {
10250 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10252 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
10254 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10256 } else { // no literal
10258 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10260 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10268 pic16_freeAsmop(right,NULL,ic,TRUE);
10269 pic16_freeAsmop(result,NULL,ic,TRUE);
10272 /*-----------------------------------------------------------------*/
10273 /* genPointerSet - stores the value into a pointer location */
10274 /*-----------------------------------------------------------------*/
10275 static void genPointerSet (iCode *ic)
10277 operand *right, *result ;
10278 sym_link *type, *etype;
10281 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10283 right = IC_RIGHT(ic);
10284 result = IC_RESULT(ic) ;
10286 /* depending on the type of pointer we need to
10287 move it to the correct pointer register */
10288 type = operandType(result);
10289 etype = getSpec(type);
10290 /* if left is of type of pointer then it is simple */
10291 if (IS_PTR(type) && !IS_FUNC(type->next)) {
10292 p_type = DCL_TYPE(type);
10295 /* we have to go by the storage class */
10296 p_type = PTR_TYPE(SPEC_OCLS(etype));
10298 /* if (SPEC_OCLS(etype)->codesp ) { */
10299 /* p_type = CPOINTER ; */
10302 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10303 /* p_type = FPOINTER ; */
10305 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10306 /* p_type = PPOINTER ; */
10308 /* if (SPEC_OCLS(etype) == idata ) */
10309 /* p_type = IPOINTER ; */
10311 /* p_type = POINTER ; */
10314 /* now that we have the pointer type we assign
10315 the pointer values */
10320 genNearPointerSet (right,result,ic);
10324 genPagedPointerSet (right,result,ic);
10328 genFarPointerSet (right,result,ic);
10332 genGenPointerSet (right,result,ic);
10336 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10337 "genPointerSet: illegal pointer type");
10341 /*-----------------------------------------------------------------*/
10342 /* genIfx - generate code for Ifx statement */
10343 /*-----------------------------------------------------------------*/
10344 static void genIfx (iCode *ic, iCode *popIc)
10346 operand *cond = IC_COND(ic);
10349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10351 pic16_aopOp(cond,ic,FALSE);
10353 /* get the value into acc */
10354 if (AOP_TYPE(cond) != AOP_CRY)
10355 pic16_toBoolean(cond);
10358 /* the result is now in the accumulator */
10359 pic16_freeAsmop(cond,NULL,ic,TRUE);
10361 /* if there was something to be popped then do it */
10365 /* if the condition is a bit variable */
10366 if (isbit && IS_ITEMP(cond) &&
10368 genIfxJump(ic,SPIL_LOC(cond)->rname);
10369 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
10372 if (isbit && !IS_ITEMP(cond))
10373 genIfxJump(ic,OP_SYMBOL(cond)->rname);
10375 genIfxJump(ic,"a");
10381 /*-----------------------------------------------------------------*/
10382 /* genAddrOf - generates code for address of */
10383 /*-----------------------------------------------------------------*/
10384 static void genAddrOf (iCode *ic)
10386 operand *result, *left;
10388 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
10389 pCodeOp *pcop0, *pcop1, *pcop2;
10391 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10393 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
10394 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
10396 sym = OP_SYMBOL( left );
10398 size = AOP_SIZE(IC_RESULT(ic));
10400 if(pic16_debug_verbose) {
10401 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
10402 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
10405 /* Assume that what we want the address of is in data space
10406 * since there is no stack on the PIC, yet! -- VR */
10408 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10411 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10414 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10418 pic16_emitpcode(POC_MOVLW, pcop0);
10419 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10420 pic16_emitpcode(POC_MOVLW, pcop1);
10421 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10422 pic16_emitpcode(POC_MOVLW, pcop2);
10423 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10426 pic16_emitpcode(POC_MOVLW, pcop0);
10427 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10428 pic16_emitpcode(POC_MOVLW, pcop1);
10429 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10431 pic16_emitpcode(POC_MOVLW, pcop0);
10432 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10435 pic16_freeAsmop(result,NULL,ic,TRUE);
10436 pic16_freeAsmop(left, NULL, ic, FALSE);
10441 /*-----------------------------------------------------------------*/
10442 /* genFarFarAssign - assignment when both are in far space */
10443 /*-----------------------------------------------------------------*/
10444 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
10446 int size = AOP_SIZE(right);
10449 /* first push the right side on to the stack */
10451 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10453 pic16_emitcode ("push","acc");
10456 pic16_freeAsmop(right,NULL,ic,FALSE);
10457 /* now assign DPTR to result */
10458 pic16_aopOp(result,ic,FALSE);
10459 size = AOP_SIZE(result);
10461 pic16_emitcode ("pop","acc");
10462 pic16_aopPut(AOP(result),"a",--offset);
10464 pic16_freeAsmop(result,NULL,ic,FALSE);
10469 /*-----------------------------------------------------------------*/
10470 /* genAssign - generate code for assignment */
10471 /*-----------------------------------------------------------------*/
10472 static void genAssign (iCode *ic)
10474 operand *result, *right;
10475 int size, offset,know_W;
10476 unsigned long lit = 0L;
10478 result = IC_RESULT(ic);
10479 right = IC_RIGHT(ic) ;
10481 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10483 /* if they are the same */
10484 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
10487 pic16_aopOp(right,ic,FALSE);
10488 pic16_aopOp(result,ic,TRUE);
10490 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10492 /* if they are the same registers */
10493 if (pic16_sameRegs(AOP(right),AOP(result)))
10496 /* if the result is a bit */
10497 if (AOP_TYPE(result) == AOP_CRY) {
10498 /* if the right size is a literal then
10499 we know what the value is */
10500 if (AOP_TYPE(right) == AOP_LIT) {
10502 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10503 pic16_popGet(AOP(result),0));
10505 if (((int) operandLitValue(right)))
10506 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10507 AOP(result)->aopu.aop_dir,
10508 AOP(result)->aopu.aop_dir);
10510 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10511 AOP(result)->aopu.aop_dir,
10512 AOP(result)->aopu.aop_dir);
10516 /* the right is also a bit variable */
10517 if (AOP_TYPE(right) == AOP_CRY) {
10518 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10519 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10520 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10522 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10523 AOP(result)->aopu.aop_dir,
10524 AOP(result)->aopu.aop_dir);
10525 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
10526 AOP(right)->aopu.aop_dir,
10527 AOP(right)->aopu.aop_dir);
10528 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10529 AOP(result)->aopu.aop_dir,
10530 AOP(result)->aopu.aop_dir);
10534 /* we need to or */
10535 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10536 pic16_toBoolean(right);
10538 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10539 //pic16_aopPut(AOP(result),"a",0);
10543 /* bit variables done */
10545 size = AOP_SIZE(result);
10547 if(AOP_TYPE(right) == AOP_LIT)
10548 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10550 /* VR - What is this?! */
10551 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
10552 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10553 if(aopIdx(AOP(result),0) == 4) {
10554 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10555 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10556 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10559 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
10564 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10565 if(AOP_TYPE(right) == AOP_LIT) {
10567 if(know_W != (lit&0xff))
10568 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
10570 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10572 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10576 } else if (AOP_TYPE(right) == AOP_CRY) {
10577 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10579 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
10580 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10582 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
10583 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10584 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10586 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10589 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
10590 normally should work, but mind that the W register live range
10591 is not checked, so if the code generator assumes that the W
10592 is already loaded after such a pair, wrong code will be generated.
10594 Checking the live range is the next step.
10595 This is experimental code yet and has not been fully tested yet.
10596 USE WITH CARE. Revert to old code by setting 0 to the condition above.
10597 Vangelis Rokas 030603 (vrokas@otenet.gr) */
10599 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
10601 /* This is the old code, which is assumed(?!) that works fine(!?) */
10603 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10604 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10613 pic16_freeAsmop (right,NULL,ic,FALSE);
10614 pic16_freeAsmop (result,NULL,ic,TRUE);
10617 /*-----------------------------------------------------------------*/
10618 /* genJumpTab - generates code for jump table */
10619 /*-----------------------------------------------------------------*/
10620 static void genJumpTab (iCode *ic)
10625 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10627 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10628 /* get the condition into accumulator */
10629 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10631 /* multiply by three */
10632 pic16_emitcode("add","a,acc");
10633 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10635 jtab = newiTempLabel(NULL);
10636 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10637 pic16_emitcode("jmp","@a+dptr");
10638 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10640 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10641 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10643 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10644 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10645 pic16_emitpLabel(jtab->key);
10647 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10649 /* now generate the jump labels */
10650 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10651 jtab = setNextItem(IC_JTLABELS(ic))) {
10652 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10653 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10659 /*-----------------------------------------------------------------*/
10660 /* genMixedOperation - gen code for operators between mixed types */
10661 /*-----------------------------------------------------------------*/
10663 TSD - Written for the PIC port - but this unfortunately is buggy.
10664 This routine is good in that it is able to efficiently promote
10665 types to different (larger) sizes. Unfortunately, the temporary
10666 variables that are optimized out by this routine are sometimes
10667 used in other places. So until I know how to really parse the
10668 iCode tree, I'm going to not be using this routine :(.
10670 static int genMixedOperation (iCode *ic)
10673 operand *result = IC_RESULT(ic);
10674 sym_link *ctype = operandType(IC_LEFT(ic));
10675 operand *right = IC_RIGHT(ic);
10681 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10683 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10689 nextright = IC_RIGHT(nextic);
10690 nextleft = IC_LEFT(nextic);
10691 nextresult = IC_RESULT(nextic);
10693 pic16_aopOp(right,ic,FALSE);
10694 pic16_aopOp(result,ic,FALSE);
10695 pic16_aopOp(nextright, nextic, FALSE);
10696 pic16_aopOp(nextleft, nextic, FALSE);
10697 pic16_aopOp(nextresult, nextic, FALSE);
10699 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10701 operand *t = right;
10705 pic16_emitcode(";remove right +","");
10707 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10709 operand *t = right;
10713 pic16_emitcode(";remove left +","");
10717 big = AOP_SIZE(nextleft);
10718 small = AOP_SIZE(nextright);
10720 switch(nextic->op) {
10723 pic16_emitcode(";optimize a +","");
10724 /* if unsigned or not an integral type */
10725 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10726 pic16_emitcode(";add a bit to something","");
10729 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10731 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10732 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10733 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10735 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10743 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10744 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10745 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10748 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10750 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10751 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10752 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10753 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10754 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10757 pic16_emitcode("rlf","known_zero,w");
10764 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10765 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10766 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10768 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10778 pic16_freeAsmop(right,NULL,ic,TRUE);
10779 pic16_freeAsmop(result,NULL,ic,TRUE);
10780 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10781 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10783 nextic->generated = 1;
10790 /*-----------------------------------------------------------------*/
10791 /* genCast - gen code for casting */
10792 /*-----------------------------------------------------------------*/
10793 static void genCast (iCode *ic)
10795 operand *result = IC_RESULT(ic);
10796 sym_link *ctype = operandType(IC_LEFT(ic));
10797 sym_link *rtype = operandType(IC_RIGHT(ic));
10798 operand *right = IC_RIGHT(ic);
10801 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10802 /* if they are equivalent then do nothing */
10803 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10806 pic16_aopOp(right,ic,FALSE) ;
10807 pic16_aopOp(result,ic,FALSE);
10809 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10811 /* if the result is a bit */
10812 if (AOP_TYPE(result) == AOP_CRY) {
10814 /* if the right size is a literal then
10815 * we know what the value is */
10816 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10818 if (AOP_TYPE(right) == AOP_LIT) {
10819 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10820 pic16_popGet(AOP(result),0));
10822 if (((int) operandLitValue(right)))
10823 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10824 AOP(result)->aopu.aop_dir,
10825 AOP(result)->aopu.aop_dir);
10827 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10828 AOP(result)->aopu.aop_dir,
10829 AOP(result)->aopu.aop_dir);
10833 /* the right is also a bit variable */
10834 if (AOP_TYPE(right) == AOP_CRY) {
10836 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10838 pic16_emitcode("clrc","");
10839 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10840 AOP(right)->aopu.aop_dir,
10841 AOP(right)->aopu.aop_dir);
10842 pic16_aopPut(AOP(result),"c",0);
10846 /* we need to or */
10847 if (AOP_TYPE(right) == AOP_REG) {
10848 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10849 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10850 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10852 pic16_toBoolean(right);
10853 pic16_aopPut(AOP(result),"a",0);
10857 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10860 size = AOP_SIZE(result);
10862 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10864 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10865 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10866 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10869 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10874 /* if they are the same size : or less */
10875 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10877 /* if they are in the same place */
10878 if (pic16_sameRegs(AOP(right),AOP(result)))
10881 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10883 if (IS_PTR_CONST(rtype))
10885 if (IS_CODEPTR(rtype))
10887 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10890 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10892 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10894 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10897 if(AOP_TYPE(right) == AOP_IMMD) {
10898 pCodeOp *pcop0, *pcop1, *pcop2;
10899 symbol *sym = OP_SYMBOL( right );
10901 size = AOP_SIZE(result);
10903 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10905 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10907 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10910 pic16_emitpcode(POC_MOVLW, pcop0);
10911 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10912 pic16_emitpcode(POC_MOVLW, pcop1);
10913 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10914 pic16_emitpcode(POC_MOVLW, pcop2);
10915 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10918 pic16_emitpcode(POC_MOVLW, pcop0);
10919 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10920 pic16_emitpcode(POC_MOVLW, pcop1);
10921 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10923 pic16_emitpcode(POC_MOVLW, pcop0);
10924 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10928 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10929 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10930 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10931 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10932 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10933 if(AOP_SIZE(result) <2)
10934 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10936 /* if they in different places then copy */
10937 size = AOP_SIZE(result);
10940 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10941 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10948 /* if the result is of type pointer */
10949 if (IS_PTR(ctype)) {
10951 sym_link *type = operandType(right);
10952 sym_link *etype = getSpec(type);
10954 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10956 /* pointer to generic pointer */
10957 if (IS_GENPTR(ctype)) {
10961 p_type = DCL_TYPE(type);
10963 /* we have to go by the storage class */
10964 p_type = PTR_TYPE(SPEC_OCLS(etype));
10966 /* if (SPEC_OCLS(etype)->codesp ) */
10967 /* p_type = CPOINTER ; */
10969 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10970 /* p_type = FPOINTER ; */
10972 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10973 /* p_type = PPOINTER; */
10975 /* if (SPEC_OCLS(etype) == idata ) */
10976 /* p_type = IPOINTER ; */
10978 /* p_type = POINTER ; */
10981 /* the first two bytes are known */
10982 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10983 size = GPTRSIZE - 1;
10986 if(offset < AOP_SIZE(right)) {
10987 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10988 if ((AOP_TYPE(right) == AOP_PCODE) &&
10989 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10990 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10991 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10993 pic16_aopPut(AOP(result),
10994 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10998 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
11001 /* the last byte depending on type */
11005 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
11008 pic16_emitcode(";BUG!? ","%d",__LINE__);
11012 pic16_emitcode(";BUG!? ","%d",__LINE__);
11016 pic16_emitcode(";BUG!? ","%d",__LINE__);
11021 /* this should never happen */
11022 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11023 "got unknown pointer type");
11026 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
11030 /* just copy the pointers */
11031 size = AOP_SIZE(result);
11034 pic16_aopPut(AOP(result),
11035 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
11044 /* so we now know that the size of destination is greater
11045 than the size of the source.
11046 Now, if the next iCode is an operator then we might be
11047 able to optimize the operation without performing a cast.
11049 if(genMixedOperation(ic))
11052 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11054 /* we move to result for the size of source */
11055 size = AOP_SIZE(right);
11058 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11059 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11063 /* now depending on the sign of the destination */
11064 size = AOP_SIZE(result) - AOP_SIZE(right);
11065 /* if unsigned or not an integral type */
11066 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
11068 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
11070 /* we need to extend the sign :( */
11073 /* Save one instruction of casting char to int */
11074 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11075 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
11076 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
11078 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
11081 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
11083 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
11085 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
11088 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
11093 pic16_freeAsmop(right,NULL,ic,TRUE);
11094 pic16_freeAsmop(result,NULL,ic,TRUE);
11098 /*-----------------------------------------------------------------*/
11099 /* genDjnz - generate decrement & jump if not zero instrucion */
11100 /*-----------------------------------------------------------------*/
11101 static int genDjnz (iCode *ic, iCode *ifx)
11103 symbol *lbl, *lbl1;
11104 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11109 /* if the if condition has a false label
11110 then we cannot save */
11114 /* if the minus is not of the form
11116 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
11117 !IS_OP_LITERAL(IC_RIGHT(ic)))
11120 if (operandLitValue(IC_RIGHT(ic)) != 1)
11123 /* if the size of this greater than one then no
11125 if (getSize(operandType(IC_RESULT(ic))) > 1)
11128 /* otherwise we can save BIG */
11129 lbl = newiTempLabel(NULL);
11130 lbl1= newiTempLabel(NULL);
11132 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11134 if (IS_AOP_PREG(IC_RESULT(ic))) {
11135 pic16_emitcode("dec","%s",
11136 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11137 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11138 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
11142 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
11143 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
11145 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11146 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
11149 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
11150 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
11151 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
11152 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
11155 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11156 ifx->generated = 1;
11160 /*-----------------------------------------------------------------*/
11161 /* genReceive - generate code for a receive iCode */
11162 /*-----------------------------------------------------------------*/
11163 static void genReceive (iCode *ic)
11165 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11167 if (isOperandInFarSpace(IC_RESULT(ic)) &&
11168 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
11169 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
11171 int size = getSize(operandType(IC_RESULT(ic)));
11172 int offset = pic16_fReturnSizePic - size;
11175 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
11176 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
11180 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
11182 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11183 size = AOP_SIZE(IC_RESULT(ic));
11186 pic16_emitcode ("pop","acc");
11187 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
11190 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
11193 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11195 assignResultValue(IC_RESULT(ic), 0);
11198 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11201 /*-----------------------------------------------------------------*/
11202 /* genDummyRead - generate code for dummy read of volatiles */
11203 /*-----------------------------------------------------------------*/
11205 genDummyRead (iCode * ic)
11207 pic16_emitcode ("; genDummyRead","");
11208 pic16_emitcode ("; not implemented","");
11213 /*-----------------------------------------------------------------*/
11214 /* genpic16Code - generate code for pic16 based controllers */
11215 /*-----------------------------------------------------------------*/
11217 * At this point, ralloc.c has gone through the iCode and attempted
11218 * to optimize in a way suitable for a PIC. Now we've got to generate
11219 * PIC instructions that correspond to the iCode.
11221 * Once the instructions are generated, we'll pass through both the
11222 * peep hole optimizer and the pCode optimizer.
11223 *-----------------------------------------------------------------*/
11225 void genpic16Code (iCode *lic)
11230 lineHead = lineCurr = NULL;
11232 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
11233 pic16_addpBlock(pb);
11236 /* if debug information required */
11237 if (options.debug && currFunc) {
11239 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
11241 if (IS_STATIC(currFunc->etype)) {
11242 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
11243 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
11245 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
11246 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
11253 for (ic = lic ; ic ; ic = ic->next ) {
11255 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
11256 if ( cln != ic->lineno ) {
11257 if ( options.debug ) {
11259 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
11260 FileBaseName(ic->filename),ic->lineno,
11261 ic->level,ic->block);
11265 if(!options.noCcodeInAsm) {
11266 pic16_addpCode2pBlock(pb,
11267 pic16_newpCodeCSource(ic->lineno, ic->filename,
11268 printCLine(ic->filename, ic->lineno)));
11274 if(options.iCodeInAsm) {
11276 /* insert here code to print iCode as comment */
11277 l = Safe_strdup(printILine(ic));
11278 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
11281 /* if the result is marked as
11282 spilt and rematerializable or code for
11283 this has already been generated then
11285 if (resultRemat(ic) || ic->generated )
11288 /* depending on the operation */
11307 /* IPOP happens only when trying to restore a
11308 spilt live range, if there is an ifx statement
11309 following this pop then the if statement might
11310 be using some of the registers being popped which
11311 would destroy the contents of the register so
11312 we need to check for this condition and handle it */
11314 ic->next->op == IFX &&
11315 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
11316 genIfx (ic->next,ic);
11334 genEndFunction (ic);
11350 pic16_genPlus (ic) ;
11354 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
11355 pic16_genMinus (ic);
11371 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
11375 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
11382 /* note these two are xlated by algebraic equivalence
11383 during parsing SDCC.y */
11384 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11385 "got '>=' or '<=' shouldn't have come here");
11389 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
11401 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
11405 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
11409 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
11433 genRightShift (ic);
11436 case GET_VALUE_AT_ADDRESS:
11441 if (POINTER_SET(ic))
11468 addSet(&_G.sendSet,ic);
11471 case DUMMY_READ_VOLATILE:
11481 /* now we are ready to call the
11482 peep hole optimizer */
11483 if (!options.nopeep) {
11484 peepHole (&lineHead);
11486 /* now do the actual printing */
11487 printLine (lineHead,codeOutFile);
11490 DFPRINTF((stderr,"printing pBlock\n\n"));
11491 pic16_printpBlock(stdout,pb);