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));
333 /*-----------------------------------------------------------------*/
334 /* pic16_emitDebuggerSymbol - associate the current code location */
335 /* with a debugger symbol */
336 /*-----------------------------------------------------------------*/
338 pic16_emitDebuggerSymbol (char * debugSym)
341 pic16_emitcode (";", "%s ==.", debugSym);
345 /*-----------------------------------------------------------------*/
346 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
347 /*-----------------------------------------------------------------*/
348 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
350 bool r0iu = FALSE , r1iu = FALSE;
351 bool r0ou = FALSE , r1ou = FALSE;
353 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
355 /* the logic: if r0 & r1 used in the instruction
356 then we are in trouble otherwise */
358 /* first check if r0 & r1 are used by this
359 instruction, in which case we are in trouble */
360 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
361 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
366 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
367 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
369 /* if no usage of r0 then return it */
370 if (!r0iu && !r0ou) {
371 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
372 (*aopp)->type = AOP_R0;
374 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
377 /* if no usage of r1 then return it */
378 if (!r1iu && !r1ou) {
379 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
380 (*aopp)->type = AOP_R1;
382 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
385 /* now we know they both have usage */
386 /* if r0 not used in this instruction */
388 /* push it if not already pushed */
390 //pic16_emitcode ("push","%s",
391 // pic16_regWithIdx(R0_IDX)->dname);
395 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
396 (*aopp)->type = AOP_R0;
398 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
401 /* if r1 not used then */
404 /* push it if not already pushed */
406 //pic16_emitcode ("push","%s",
407 // pic16_regWithIdx(R1_IDX)->dname);
411 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
412 (*aopp)->type = AOP_R1;
413 return pic16_regWithIdx(R1_IDX);
417 /* I said end of world but not quite end of world yet */
418 /* if this is a result then we can push it on the stack*/
420 (*aopp)->type = AOP_STK;
424 /* other wise this is true end of the world */
425 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
426 "getFreePtr should never reach here");
430 /*-----------------------------------------------------------------*/
431 /* newAsmop - creates a new asmOp */
432 /*-----------------------------------------------------------------*/
433 static asmop *newAsmop (short type)
437 aop = Safe_calloc(1,sizeof(asmop));
442 static void genSetDPTR(int n)
446 pic16_emitcode(";", "Select standard DPTR");
447 pic16_emitcode("mov", "dps, #0x00");
451 pic16_emitcode(";", "Select alternate DPTR");
452 pic16_emitcode("mov", "dps, #0x01");
456 /*-----------------------------------------------------------------*/
457 /* resolveIfx - converts an iCode ifx into a form more useful for */
458 /* generating code */
459 /*-----------------------------------------------------------------*/
460 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
463 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
469 resIfx->condition = 1; /* assume that the ifx is true */
470 resIfx->generated = 0; /* indicate that the ifx has not been used */
473 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
476 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
477 __FUNCTION__,__LINE__,resIfx->lbl->key);
482 resIfx->lbl = IC_TRUE(ifx);
484 resIfx->lbl = IC_FALSE(ifx);
485 resIfx->condition = 0;
489 DEBUGpic16_emitcode("; ***","ifx true is non-null");
491 DEBUGpic16_emitcode("; ***","ifx false is non-null");
495 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
499 /*-----------------------------------------------------------------*/
500 /* pointerCode - returns the code for a pointer type */
501 /*-----------------------------------------------------------------*/
502 static int pointerCode (sym_link *etype)
505 return PTR_TYPE(SPEC_OCLS(etype));
509 /*-----------------------------------------------------------------*/
510 /* aopForSym - for a true symbol */
511 /*-----------------------------------------------------------------*/
512 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
515 memmap *space= SPEC_OCLS(sym->etype);
517 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
518 /* if already has one */
520 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
524 /* if symbol was initially placed onStack then we must re-place it
525 * to direct memory, since pic16 does not have a specific stack */
528 SPEC_OCLS( sym->etype ) = data;
534 /* assign depending on the storage class */
535 /* if it is on the stack or indirectly addressable */
536 /* space we need to assign either r0 or r1 to it */
537 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
539 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
540 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
542 sym->aop = aop = newAsmop(0);
543 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
544 aop->size = getSize(sym->type);
546 /* now assign the address of the variable to
547 the pointer register */
548 if (aop->type != AOP_STK) {
552 pic16_emitcode("push","acc");
554 pic16_emitcode("mov","a,_bp");
555 pic16_emitcode("add","a,#0x%02x",
557 ((char)(sym->stack - _G.nRegsSaved )) :
558 ((char)sym->stack)) & 0xff);
559 pic16_emitcode("mov","%s,a",
560 aop->aopu.aop_ptr->name);
563 pic16_emitcode("pop","acc");
565 pic16_emitcode("mov","%s,#%s",
566 aop->aopu.aop_ptr->name,
568 aop->paged = space->paged;
570 aop->aopu.aop_stk = sym->stack;
575 if (sym->onStack && options.stack10bit)
577 /* It's on the 10 bit stack, which is located in
581 //DEBUGpic16_emitcode(";","%d",__LINE__);
584 pic16_emitcode("push","acc");
586 pic16_emitcode("mov","a,_bp");
587 pic16_emitcode("add","a,#0x%02x",
589 ((char)(sym->stack - _G.nRegsSaved )) :
590 ((char)sym->stack)) & 0xff);
593 pic16_emitcode ("mov","dpx1,#0x40");
594 pic16_emitcode ("mov","dph1,#0x00");
595 pic16_emitcode ("mov","dpl1, a");
599 pic16_emitcode("pop","acc");
601 sym->aop = aop = newAsmop(AOP_DPTR2);
602 aop->size = getSize(sym->type);
606 //DEBUGpic16_emitcode(";","%d",__LINE__);
607 /* if in bit space */
608 if (IN_BITSPACE(space)) {
609 sym->aop = aop = newAsmop (AOP_CRY);
610 aop->aopu.aop_dir = sym->rname ;
611 aop->size = getSize(sym->type);
612 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
615 /* if it is in direct space */
616 if (IN_DIRSPACE(space)) {
617 sym->aop = aop = newAsmop (AOP_DIR);
618 aop->aopu.aop_dir = sym->rname ;
619 aop->size = getSize(sym->type);
620 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
621 pic16_allocDirReg( IC_LEFT(ic) );
626 /* special case for a function */
627 if (IS_FUNC(sym->type)) {
628 sym->aop = aop = newAsmop(AOP_IMMD);
629 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
630 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
631 strcpy(aop->aopu.aop_immd,sym->rname);
632 aop->size = FPTRSIZE;
633 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
639 /* only remaining is far space */
640 /* in which case DPTR gets the address */
641 sym->aop = aop = newAsmop(AOP_PCODE);
643 /* change the next if to 1 to revert to good old immediate code */
644 if(IN_CODESPACE(space)) {
645 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
646 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
647 PCOI(aop->aopu.pcop)->index = 0;
649 /* try to allocate via direct register */
650 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset); // Patch 8
651 // aop->size = getSize( sym->type );
654 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
655 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
658 if(!pic16_allocDirReg (IC_LEFT(ic)))
662 if(IN_DIRSPACE( space ))
664 else if(IN_CODESPACE( space ))
665 aop->size = FPTRSIZE;
666 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
667 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
672 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
674 /* if it is in code space */
675 if (IN_CODESPACE(space))
681 /*-----------------------------------------------------------------*/
682 /* aopForRemat - rematerialzes an object */
683 /*-----------------------------------------------------------------*/
684 static asmop *aopForRemat (operand *op) // x symbol *sym)
686 symbol *sym = OP_SYMBOL(op);
687 iCode *ic = NULL, *oldic;
688 asmop *aop = newAsmop(AOP_PCODE);
694 ic = sym->rematiCode;
696 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
698 if(IS_OP_POINTER(op)) {
699 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
705 // pic16_emitpcomment("ic: %s\n", printILine(ic));
708 val += (int) operandLitValue(IC_RIGHT(ic));
709 } else if (ic->op == '-') {
710 val -= (int) operandLitValue(IC_RIGHT(ic));
714 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
717 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
719 if(!op->isaddr)viaimmd++; else viaimmd=0;
721 /* set the following if to 1 to revert to good old immediate code */
722 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
725 pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__);
727 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
730 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
732 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
735 PCOI(aop->aopu.pcop)->index = val;
737 pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__);
739 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
740 // aop->size = AOP_SIZE( IC_LEFT(ic) );
744 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
745 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
747 val, IS_PTR_CONST(operandType(op)));
749 val, IS_CODEPTR(operandType(op)));
752 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
754 pic16_allocDirReg (IC_LEFT(ic));
756 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
762 static int aopIdx (asmop *aop, int offset)
767 if(aop->type != AOP_REG)
770 return aop->aopu.aop_reg[offset]->rIdx;
773 /*-----------------------------------------------------------------*/
774 /* regsInCommon - two operands have some registers in common */
775 /*-----------------------------------------------------------------*/
776 static bool regsInCommon (operand *op1, operand *op2)
781 /* if they have registers in common */
782 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
785 sym1 = OP_SYMBOL(op1);
786 sym2 = OP_SYMBOL(op2);
788 if (sym1->nRegs == 0 || sym2->nRegs == 0)
791 for (i = 0 ; i < sym1->nRegs ; i++) {
796 for (j = 0 ; j < sym2->nRegs ;j++ ) {
800 if (sym2->regs[j] == sym1->regs[i])
808 /*-----------------------------------------------------------------*/
809 /* operandsEqu - equivalent */
810 /*-----------------------------------------------------------------*/
811 static bool operandsEqu ( operand *op1, operand *op2)
815 /* if they not symbols */
816 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
819 sym1 = OP_SYMBOL(op1);
820 sym2 = OP_SYMBOL(op2);
822 /* if both are itemps & one is spilt
823 and the other is not then false */
824 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
825 sym1->isspilt != sym2->isspilt )
828 /* if they are the same */
832 if (strcmp(sym1->rname,sym2->rname) == 0)
836 /* if left is a tmp & right is not */
840 (sym1->usl.spillLoc == sym2))
847 (sym2->usl.spillLoc == sym1))
853 /*-----------------------------------------------------------------*/
854 /* pic16_sameRegs - two asmops have the same registers */
855 /*-----------------------------------------------------------------*/
856 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
863 if (aop1->type != AOP_REG ||
864 aop2->type != AOP_REG )
867 if (aop1->size != aop2->size )
870 for (i = 0 ; i < aop1->size ; i++ )
871 if (aop1->aopu.aop_reg[i] !=
872 aop2->aopu.aop_reg[i] )
878 /*-----------------------------------------------------------------*/
879 /* pic16_aopOp - allocates an asmop for an operand : */
880 /*-----------------------------------------------------------------*/
881 void pic16_aopOp (operand *op, iCode *ic, bool result)
890 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
892 /* if this a literal */
893 if (IS_OP_LITERAL(op)) {
894 op->aop = aop = newAsmop(AOP_LIT);
895 aop->aopu.aop_lit = op->operand.valOperand;
896 aop->size = getSize(operandType(op));
901 sym_link *type = operandType(op);
903 if(IS_PTR_CONST(type))
907 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
910 /* if already has a asmop then continue */
914 /* if the underlying symbol has a aop */
915 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
916 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
917 op->aop = OP_SYMBOL(op)->aop;
921 /* if this is a true symbol */
922 if (IS_TRUE_SYMOP(op)) {
923 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
924 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
928 /* this is a temporary : this has
934 e) can be a return use only */
938 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
939 /* if the type is a conditional */
940 if (sym->regType == REG_CND) {
941 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
946 /* if it is spilt then two situations
948 b) has a spill location */
949 if (sym->isspilt || sym->nRegs == 0) {
951 DEBUGpic16_emitcode(";","%d",__LINE__);
952 /* rematerialize it NOW */
955 sym->aop = op->aop = aop =
957 aop->size = getSize(sym->type);
958 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
965 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
966 aop->size = getSize(sym->type);
967 for ( i = 0 ; i < 1 ; i++ ) {
968 aop->aopu.aop_str[i] = accUse[i];
969 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
971 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
972 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
980 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
981 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
982 //pic16_allocDirReg (IC_LEFT(ic));
983 aop->size = getSize(sym->type);
988 aop = op->aop = sym->aop = newAsmop(AOP_STR);
989 aop->size = getSize(sym->type);
990 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
991 aop->aopu.aop_str[i] = fReturn[i];
993 DEBUGpic16_emitcode(";","%d",__LINE__);
997 /* else spill location */
998 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
999 /* force a new aop if sizes differ */
1000 sym->usl.spillLoc->aop = NULL;
1002 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
1003 __FUNCTION__,__LINE__,
1004 sym->usl.spillLoc->rname,
1005 sym->rname, sym->usl.spillLoc->offset);
1007 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
1008 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
1009 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1011 sym->usl.spillLoc->offset);
1012 aop->size = getSize(sym->type);
1018 sym_link *type = operandType(op);
1020 if(IS_PTR_CONST(type))
1022 if(IS_CODEPTR(type))
1024 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1027 /* must be in a register */
1028 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1029 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1030 aop->size = sym->nRegs;
1031 for ( i = 0 ; i < sym->nRegs ;i++)
1032 aop->aopu.aop_reg[i] = sym->regs[i];
1035 /*-----------------------------------------------------------------*/
1036 /* pic16_freeAsmop - free up the asmop given to an operand */
1037 /*----------------------------------------------------------------*/
1038 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1055 /* depending on the asmop type only three cases need work AOP_RO
1056 , AOP_R1 && AOP_STK */
1058 switch (aop->type) {
1062 pic16_emitcode ("pop","ar0");
1066 bitVectUnSetBit(ic->rUsed,R0_IDX);
1072 pic16_emitcode ("pop","ar1");
1076 bitVectUnSetBit(ic->rUsed,R1_IDX);
1082 int stk = aop->aopu.aop_stk + aop->size;
1083 bitVectUnSetBit(ic->rUsed,R0_IDX);
1084 bitVectUnSetBit(ic->rUsed,R1_IDX);
1086 getFreePtr(ic,&aop,FALSE);
1088 if (options.stack10bit)
1090 /* I'm not sure what to do here yet... */
1093 "*** Warning: probably generating bad code for "
1094 "10 bit stack mode.\n");
1098 pic16_emitcode ("mov","a,_bp");
1099 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1100 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1102 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1106 pic16_emitcode("pop","acc");
1107 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1109 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1112 pic16_freeAsmop(op,NULL,ic,TRUE);
1114 pic16_emitcode("pop","ar0");
1119 pic16_emitcode("pop","ar1");
1127 /* all other cases just dealloc */
1131 OP_SYMBOL(op)->aop = NULL;
1132 /* if the symbol has a spill */
1134 SPIL_LOC(op)->aop = NULL;
1139 /*-----------------------------------------------------------------*/
1140 /* pic16_aopGet - for fetching value of the aop */
1141 /*-----------------------------------------------------------------*/
1142 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1147 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1149 /* offset is greater than size then zero */
1150 if (offset > (aop->size - 1) &&
1151 aop->type != AOP_LIT)
1154 /* depending on type */
1155 switch (aop->type) {
1159 DEBUGpic16_emitcode(";","%d",__LINE__);
1160 /* if we need to increment it */
1161 while (offset > aop->coff) {
1162 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1166 while (offset < aop->coff) {
1167 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1171 aop->coff = offset ;
1173 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1174 return (dname ? "acc" : "a");
1176 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1177 rs = Safe_calloc(1,strlen(s)+1);
1183 DEBUGpic16_emitcode(";","%d",__LINE__);
1184 if (aop->type == AOP_DPTR2)
1189 while (offset > aop->coff) {
1190 pic16_emitcode ("inc","dptr");
1194 while (offset < aop->coff) {
1195 pic16_emitcode("lcall","__decdptr");
1201 pic16_emitcode("clr","a");
1202 pic16_emitcode("movc","a,@a+dptr");
1205 pic16_emitcode("movx","a,@dptr");
1208 if (aop->type == AOP_DPTR2)
1213 return (dname ? "acc" : "a");
1218 sprintf (s,"%s",aop->aopu.aop_immd);
1221 sprintf(s,"(%s >> %d)",
1226 aop->aopu.aop_immd);
1227 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1228 rs = Safe_calloc(1,strlen(s)+1);
1234 sprintf(s,"(%s + %d)",
1237 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1239 sprintf(s,"%s",aop->aopu.aop_dir);
1240 rs = Safe_calloc(1,strlen(s)+1);
1246 // return aop->aopu.aop_reg[offset]->dname;
1248 return aop->aopu.aop_reg[offset]->name;
1251 //pic16_emitcode(";","%d",__LINE__);
1252 return aop->aopu.aop_dir;
1255 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1256 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1258 return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1261 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1262 rs = Safe_calloc(1,strlen(s)+1);
1267 aop->coff = offset ;
1268 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1271 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1273 return aop->aopu.aop_str[offset];
1277 pCodeOp *pcop = aop->aopu.pcop;
1278 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1280 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1281 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1282 sprintf(s,"%s", pcop->name);
1284 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1287 rs = Safe_calloc(1,strlen(s)+1);
1293 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1294 "aopget got unsupported aop->type");
1299 /*-----------------------------------------------------------------*/
1300 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1301 /*-----------------------------------------------------------------*/
1302 pCodeOp *pic16_popGetTempReg(void)
1307 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1312 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1313 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1314 PCOR(pcop)->r->wasUsed=1;
1315 PCOR(pcop)->r->isFree=0;
1317 /* push value on stack */
1318 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1326 /*-----------------------------------------------------------------*/
1327 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1328 /*-----------------------------------------------------------------*/
1329 void pic16_popReleaseTempReg(pCodeOp *pcop)
1331 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1333 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1334 PCOR(pcop)->r->isFree = 1;
1336 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1339 /*-----------------------------------------------------------------*/
1340 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1341 /*-----------------------------------------------------------------*/
1342 pCodeOp *pic16_popGetLabel(unsigned int key)
1345 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1350 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1353 /*-----------------------------------------------------------------*/
1354 /* pic16_popCopyReg - copy a pcode operator */
1355 /*-----------------------------------------------------------------*/
1356 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1360 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1361 pcor->pcop.type = pc->pcop.type;
1363 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1364 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1366 pcor->pcop.name = NULL;
1369 pcor->rIdx = pc->rIdx;
1372 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1377 /*-----------------------------------------------------------------*/
1378 /* pic16_popGetLit - asm operator to pcode operator conversion */
1379 /*-----------------------------------------------------------------*/
1380 pCodeOp *pic16_popGetLit(unsigned int lit)
1382 return pic16_newpCodeOpLit(lit);
1385 /*-----------------------------------------------------------------*/
1386 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1387 /*-----------------------------------------------------------------*/
1388 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1390 return pic16_newpCodeOpLit2(lit, arg2);
1394 /*-----------------------------------------------------------------*/
1395 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1396 /*-----------------------------------------------------------------*/
1397 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1399 return pic16_newpCodeOpImmd(name, offset,index, 0);
1403 /*-----------------------------------------------------------------*/
1404 /* pic16_popGet - asm operator to pcode operator conversion */
1405 /*-----------------------------------------------------------------*/
1406 pCodeOp *pic16_popGetWithString(char *str)
1412 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1416 pcop = pic16_newpCodeOp(str,PO_STR);
1421 /*-----------------------------------------------------------------*/
1422 /* pic16_popRegFromString - */
1423 /*-----------------------------------------------------------------*/
1424 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1427 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1428 pcop->type = PO_DIR;
1430 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1431 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1436 pcop->name = Safe_calloc(1,strlen(str)+1);
1437 strcpy(pcop->name,str);
1439 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1441 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1442 if(PCOR(pcop)->r == NULL) {
1443 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1444 // __FUNCTION__, __LINE__, str, size, offset);
1445 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1447 //fprintf(stderr, "allocating new register -> %s\n", str);
1449 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1451 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1453 PCOR(pcop)->instance = offset;
1458 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1462 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1464 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1465 PCOR(pcop)->rIdx = rIdx;
1466 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1467 PCOR(pcop)->r->isFree = 0;
1468 PCOR(pcop)->r->wasUsed = 1;
1470 pcop->type = PCOR(pcop)->r->pc_type;
1475 /*---------------------------------------------------------------------------------*/
1476 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1478 /*---------------------------------------------------------------------------------*/
1479 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1484 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1486 /* comment the following check, so errors to throw up */
1487 // if(!pcop2)return NULL;
1489 temp = pic16_popGet(aop_dst, offset);
1490 pcop2->pcop2 = temp;
1497 /*--------------------------------------------------------------------------------.-*/
1498 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1499 /* VR 030601 , adapted by Hans Dorn */
1500 /*--------------------------------------------------------------------------------.-*/
1501 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1505 pcop2 = (pCodeOpReg2 *)src;
1513 /*---------------------------------------------------------------------------------*/
1514 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1515 /* movff instruction */
1516 /*---------------------------------------------------------------------------------*/
1517 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1522 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1523 pcop2->pcop2 = pic16_popCopyReg(dst);
1525 /* the pCodeOp may be already allocated */
1526 pcop2 = (pCodeOpReg2 *)(src);
1527 pcop2->pcop2 = (pCodeOp *)(dst);
1534 /*-----------------------------------------------------------------*/
1535 /* pic16_popGet - asm operator to pcode operator conversion */
1536 /*-----------------------------------------------------------------*/
1537 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1539 //char *s = buffer ;
1543 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1544 /* offset is greater than
1547 // if (offset > (aop->size - 1) &&
1548 // aop->type != AOP_LIT)
1549 // return NULL; //zero;
1551 /* depending on type */
1552 switch (aop->type) {
1558 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1559 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1566 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1567 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1571 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1573 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1575 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1577 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1578 PCOR(pcop)->rIdx = rIdx;
1579 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1580 PCOR(pcop)->r->wasUsed=1;
1581 PCOR(pcop)->r->isFree=0;
1583 PCOR(pcop)->instance = offset;
1584 pcop->type = PCOR(pcop)->r->pc_type;
1585 // rs = aop->aopu.aop_reg[offset]->name;
1586 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1590 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1591 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1597 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1598 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1602 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1604 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1606 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1607 PCOR(pcop)->rIdx = rIdx;
1608 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1609 PCOR(pcop)->r->wasUsed=1;
1610 PCOR(pcop)->r->isFree=0;
1612 PCOR(pcop)->instance = offset;
1613 pcop->type = PCOR(pcop)->r->pc_type;
1614 rs = aop->aopu.aop_reg[offset]->name;
1615 DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1620 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1622 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1623 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1624 //if(PCOR(pcop)->r == NULL)
1625 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1629 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1630 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1633 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1634 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1637 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1638 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1639 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1640 pcop->type = PCOR(pcop)->r->pc_type;
1641 pcop->name = PCOR(pcop)->r->name;
1647 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1649 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1650 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1652 switch( aop->aopu.pcop->type ) {
1653 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1654 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1656 assert( 0 ); /* should never reach here */;
1659 PCOI(pcop)->offset = offset;
1664 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1665 "pic16_popGet got unsupported aop->type");
1668 /*-----------------------------------------------------------------*/
1669 /* pic16_aopPut - puts a string for a aop */
1670 /*-----------------------------------------------------------------*/
1671 void pic16_aopPut (asmop *aop, char *s, int offset)
1676 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1678 if (aop->size && offset > ( aop->size - 1)) {
1679 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1680 "pic16_aopPut got offset > aop->size");
1684 /* will assign value to value */
1685 /* depending on where it is ofcourse */
1686 switch (aop->type) {
1689 sprintf(d,"(%s + %d)",
1690 aop->aopu.aop_dir,offset);
1691 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1694 sprintf(d,"%s",aop->aopu.aop_dir);
1697 DEBUGpic16_emitcode(";","%d",__LINE__);
1699 pic16_emitcode("movf","%s,w",s);
1700 pic16_emitcode("movwf","%s",d);
1703 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1704 if(offset >= aop->size) {
1705 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1708 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1711 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1718 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1719 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1722 strcmp(s,"r0") == 0 ||
1723 strcmp(s,"r1") == 0 ||
1724 strcmp(s,"r2") == 0 ||
1725 strcmp(s,"r3") == 0 ||
1726 strcmp(s,"r4") == 0 ||
1727 strcmp(s,"r5") == 0 ||
1728 strcmp(s,"r6") == 0 ||
1729 strcmp(s,"r7") == 0 )
1730 pic16_emitcode("mov","%s,%s ; %d",
1731 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1735 if(strcmp(s,"W")==0 )
1736 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1738 pic16_emitcode("movwf","%s",
1739 aop->aopu.aop_reg[offset]->name);
1741 if(strcmp(s,zero)==0) {
1742 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1744 } else if(strcmp(s,"W")==0) {
1745 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1746 pcop->type = PO_GPR_REGISTER;
1748 PCOR(pcop)->rIdx = -1;
1749 PCOR(pcop)->r = NULL;
1751 DEBUGpic16_emitcode(";","%d",__LINE__);
1752 pcop->name = Safe_strdup(s);
1753 pic16_emitpcode(POC_MOVFW,pcop);
1754 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1755 } else if(strcmp(s,one)==0) {
1756 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1757 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1759 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1767 if (aop->type == AOP_DPTR2)
1773 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1774 "pic16_aopPut writting to code space");
1778 while (offset > aop->coff) {
1780 pic16_emitcode ("inc","dptr");
1783 while (offset < aop->coff) {
1785 pic16_emitcode("lcall","__decdptr");
1790 /* if not in accumulater */
1793 pic16_emitcode ("movx","@dptr,a");
1795 if (aop->type == AOP_DPTR2)
1803 while (offset > aop->coff) {
1805 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1807 while (offset < aop->coff) {
1809 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1815 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1820 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1822 if (strcmp(s,"r0") == 0 ||
1823 strcmp(s,"r1") == 0 ||
1824 strcmp(s,"r2") == 0 ||
1825 strcmp(s,"r3") == 0 ||
1826 strcmp(s,"r4") == 0 ||
1827 strcmp(s,"r5") == 0 ||
1828 strcmp(s,"r6") == 0 ||
1829 strcmp(s,"r7") == 0 ) {
1831 sprintf(buffer,"a%s",s);
1832 pic16_emitcode("mov","@%s,%s",
1833 aop->aopu.aop_ptr->name,buffer);
1835 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1840 if (strcmp(s,"a") == 0)
1841 pic16_emitcode("push","acc");
1843 pic16_emitcode("push","%s",s);
1848 /* if bit variable */
1849 if (!aop->aopu.aop_dir) {
1850 pic16_emitcode("clr","a");
1851 pic16_emitcode("rlc","a");
1854 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1857 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1860 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1862 lbl = newiTempLabel(NULL);
1864 if (strcmp(s,"a")) {
1867 pic16_emitcode("clr","c");
1868 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1869 pic16_emitcode("cpl","c");
1870 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1871 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1878 if (strcmp(aop->aopu.aop_str[offset],s))
1879 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1884 if (!offset && (strcmp(s,"acc") == 0))
1887 if (strcmp(aop->aopu.aop_str[offset],s))
1888 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1892 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1893 "pic16_aopPut got unsupported aop->type");
1899 /*-----------------------------------------------------------------*/
1900 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1901 /*-----------------------------------------------------------------*/
1902 static void mov2w (asmop *aop, int offset)
1908 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1910 if ( aop->type == AOP_PCODE ||
1911 aop->type == AOP_LIT )
1912 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1914 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1919 /* push pcop into stack */
1920 void pic16_pushpCodeOp(pCodeOp *pcop)
1922 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1923 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1926 /* pop pcop from stack */
1927 void pic16_poppCodeOp(pCodeOp *pcop)
1929 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1933 /*-----------------------------------------------------------------*/
1934 /* pushw - pushes wreg to stack */
1935 /*-----------------------------------------------------------------*/
1938 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1939 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1943 /*-----------------------------------------------------------------*/
1944 /* pushaop - pushes aop to stack */
1945 /*-----------------------------------------------------------------*/
1946 void pushaop(asmop *aop, int offset)
1948 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1949 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1952 /*-----------------------------------------------------------------*/
1953 /* popaop - pops aop from stack */
1954 /*-----------------------------------------------------------------*/
1955 void popaop(asmop *aop, int offset)
1957 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1958 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1961 void popaopidx(asmop *aop, int offset, int index)
1965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1967 if(STACK_MODEL_LARGE)ofs++;
1969 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1970 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1973 /*-----------------------------------------------------------------*/
1974 /* reAdjustPreg - points a register back to where it should */
1975 /*-----------------------------------------------------------------*/
1976 static void reAdjustPreg (asmop *aop)
1980 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1982 if ((size = aop->size) <= 1)
1985 switch (aop->type) {
1989 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1993 if (aop->type == AOP_DPTR2)
1999 pic16_emitcode("lcall","__decdptr");
2002 if (aop->type == AOP_DPTR2)
2014 /*-----------------------------------------------------------------*/
2015 /* opIsGptr: returns non-zero if the passed operand is */
2016 /* a generic pointer type. */
2017 /*-----------------------------------------------------------------*/
2018 static int opIsGptr(operand *op)
2020 sym_link *type = operandType(op);
2022 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2023 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2031 /*-----------------------------------------------------------------*/
2032 /* pic16_getDataSize - get the operand data size */
2033 /*-----------------------------------------------------------------*/
2034 int pic16_getDataSize(operand *op)
2036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2039 return AOP_SIZE(op);
2041 // tsd- in the pic port, the genptr size is 1, so this code here
2042 // fails. ( in the 8051 port, the size was 4).
2045 size = AOP_SIZE(op);
2046 if (size == GPTRSIZE)
2048 sym_link *type = operandType(op);
2049 if (IS_GENPTR(type))
2051 /* generic pointer; arithmetic operations
2052 * should ignore the high byte (pointer type).
2055 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2062 /*-----------------------------------------------------------------*/
2063 /* pic16_outAcc - output Acc */
2064 /*-----------------------------------------------------------------*/
2065 void pic16_outAcc(operand *result)
2068 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2069 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2072 size = pic16_getDataSize(result);
2074 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2077 /* unsigned or positive */
2079 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2084 /*-----------------------------------------------------------------*/
2085 /* pic16_outBitC - output a bit C */
2086 /*-----------------------------------------------------------------*/
2087 void pic16_outBitC(operand *result)
2090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2091 /* if the result is bit */
2092 if (AOP_TYPE(result) == AOP_CRY)
2093 pic16_aopPut(AOP(result),"c",0);
2095 pic16_emitcode("clr","a ; %d", __LINE__);
2096 pic16_emitcode("rlc","a");
2097 pic16_outAcc(result);
2101 /*-----------------------------------------------------------------*/
2102 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2103 /*-----------------------------------------------------------------*/
2104 void pic16_toBoolean(operand *oper)
2106 int size = AOP_SIZE(oper) - 1;
2109 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2111 if ( AOP_TYPE(oper) != AOP_ACC) {
2112 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2115 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2120 #if !defined(GEN_Not)
2121 /*-----------------------------------------------------------------*/
2122 /* genNot - generate code for ! operation */
2123 /*-----------------------------------------------------------------*/
2124 static void pic16_genNot (iCode *ic)
2129 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2130 /* assign asmOps to operand & result */
2131 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2132 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2134 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2135 /* if in bit space then a special case */
2136 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2137 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2138 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2139 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2141 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2142 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2143 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2148 size = AOP_SIZE(IC_LEFT(ic));
2150 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2151 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2152 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2155 pic16_toBoolean(IC_LEFT(ic));
2157 tlbl = newiTempLabel(NULL);
2158 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2159 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2160 pic16_outBitC(IC_RESULT(ic));
2163 /* release the aops */
2164 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2165 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2170 #if !defined(GEN_Cpl)
2171 /*-----------------------------------------------------------------*/
2172 /* genCpl - generate code for complement */
2173 /*-----------------------------------------------------------------*/
2174 static void pic16_genCpl (iCode *ic)
2180 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2181 /* assign asmOps to operand & result */
2182 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2183 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2185 /* if both are in bit space then
2187 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2188 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2190 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2191 pic16_emitcode("cpl","c");
2192 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2196 size = AOP_SIZE(IC_RESULT(ic));
2199 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2201 pic16_emitcode("cpl","a");
2202 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2204 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2205 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2207 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2208 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2216 /* release the aops */
2217 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2218 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2222 /*-----------------------------------------------------------------*/
2223 /* genUminusFloat - unary minus for floating points */
2224 /*-----------------------------------------------------------------*/
2225 static void genUminusFloat(operand *op,operand *result)
2227 int size ,offset =0 ;
2230 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2231 /* for this we just need to flip the
2232 first it then copy the rest in place */
2233 size = AOP_SIZE(op) - 1;
2234 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2238 pic16_emitcode("cpl","acc.7");
2239 pic16_aopPut(AOP(result),"a",3);
2242 pic16_aopPut(AOP(result),
2243 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2249 /*-----------------------------------------------------------------*/
2250 /* genUminus - unary minus code generation */
2251 /*-----------------------------------------------------------------*/
2252 static void genUminus (iCode *ic)
2255 sym_link *optype, *rtype;
2258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2260 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2261 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2263 /* if both in bit space then special
2265 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2266 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2268 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2269 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2270 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2275 optype = operandType(IC_LEFT(ic));
2276 rtype = operandType(IC_RESULT(ic));
2278 /* if float then do float stuff */
2279 if (IS_FLOAT(optype)) {
2280 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2284 /* otherwise subtract from zero by taking the 2's complement */
2285 size = AOP_SIZE(IC_LEFT(ic));
2287 for(i=0; i<size; i++) {
2288 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2289 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2291 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2292 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2296 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2297 for(i=1; i<size; i++) {
2299 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2303 /* release the aops */
2304 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2305 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2308 /*-----------------------------------------------------------------*/
2309 /* saveRegisters - will look for a call and save the registers */
2310 /*-----------------------------------------------------------------*/
2311 static void saveRegisters(iCode *lic)
2318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2320 for (ic = lic ; ic ; ic = ic->next)
2321 if (ic->op == CALL || ic->op == PCALL)
2325 fprintf(stderr,"found parameter push with no function call\n");
2329 /* if the registers have been saved already then
2331 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2334 /* find the registers in use at this time
2335 and push them away to safety */
2336 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2340 if (options.useXstack) {
2341 if (bitVectBitValue(rsave,R0_IDX))
2342 pic16_emitcode("mov","b,r0");
2343 pic16_emitcode("mov","r0,%s",spname);
2344 for (i = 0 ; i < pic16_nRegs ; i++) {
2345 if (bitVectBitValue(rsave,i)) {
2347 pic16_emitcode("mov","a,b");
2349 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2350 pic16_emitcode("movx","@r0,a");
2351 pic16_emitcode("inc","r0");
2354 pic16_emitcode("mov","%s,r0",spname);
2355 if (bitVectBitValue(rsave,R0_IDX))
2356 pic16_emitcode("mov","r0,b");
2358 //for (i = 0 ; i < pic16_nRegs ; i++) {
2359 // if (bitVectBitValue(rsave,i))
2360 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2363 dtype = operandType(IC_LEFT(ic));
2364 if (currFunc && dtype &&
2365 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2366 IFFUNC_ISISR(currFunc->type) &&
2369 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2372 /*-----------------------------------------------------------------*/
2373 /* unsaveRegisters - pop the pushed registers */
2374 /*-----------------------------------------------------------------*/
2375 static void unsaveRegisters (iCode *ic)
2380 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2381 /* find the registers in use at this time
2382 and push them away to safety */
2383 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2386 if (options.useXstack) {
2387 pic16_emitcode("mov","r0,%s",spname);
2388 for (i = pic16_nRegs ; i >= 0 ; i--) {
2389 if (bitVectBitValue(rsave,i)) {
2390 pic16_emitcode("dec","r0");
2391 pic16_emitcode("movx","a,@r0");
2393 pic16_emitcode("mov","b,a");
2395 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2399 pic16_emitcode("mov","%s,r0",spname);
2400 if (bitVectBitValue(rsave,R0_IDX))
2401 pic16_emitcode("mov","r0,b");
2403 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2404 // if (bitVectBitValue(rsave,i))
2405 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2411 /*-----------------------------------------------------------------*/
2413 /*-----------------------------------------------------------------*/
2414 static void pushSide(operand * oper, int size)
2417 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2419 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2420 if (AOP_TYPE(oper) != AOP_REG &&
2421 AOP_TYPE(oper) != AOP_DIR &&
2423 pic16_emitcode("mov","a,%s",l);
2424 pic16_emitcode("push","acc");
2426 pic16_emitcode("push","%s",l);
2431 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2433 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2435 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2436 pic16_emitpcode(POC_MOVFW, src);
2437 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2439 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2440 src, pic16_popGet(AOP(op), offset)));
2445 /*-----------------------------------------------------------------*/
2446 /* assignResultValue - assign results to oper, rescall==1 is */
2447 /* called from genCall() or genPCall() */
2448 /*-----------------------------------------------------------------*/
2449 static void assignResultValue(operand * oper, int rescall)
2451 int size = AOP_SIZE(oper);
2453 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2454 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2457 /* assign result from a call/pcall function() */
2459 /* function results are stored in a special order,
2460 * see top of file with Function return policy, or manual */
2463 /* 8-bits, result in WREG */
2464 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2467 /* 16-bits, result in PRODL:WREG */
2468 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2472 /* 24-bits, result in PRODH:PRODL:WREG */
2473 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2477 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2478 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2481 /* >32-bits, result on stack, and FSR0 points to beginning.
2482 * Fix stack when done */
2485 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2486 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2488 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2493 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2494 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2495 if(STACK_MODEL_LARGE) {
2497 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2501 if(!GpsuedoStkPtr) {
2502 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2503 /* The last byte in the assignment is in W */
2505 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2510 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2511 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2513 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2519 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2521 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2531 /*-----------------------------------------------------------------*/
2532 /* genIpush - genrate code for pushing this gets a little complex */
2533 /*-----------------------------------------------------------------*/
2534 static void genIpush (iCode *ic)
2537 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2539 int size, offset = 0 ;
2543 /* if this is not a parm push : ie. it is spill push
2544 and spill push is always done on the local stack */
2545 if (!ic->parmPush) {
2547 /* and the item is spilt then do nothing */
2548 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2551 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2552 size = AOP_SIZE(IC_LEFT(ic));
2553 /* push it on the stack */
2555 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2560 pic16_emitcode("push","%s",l);
2565 /* this is a paramter push: in this case we call
2566 the routine to find the call and save those
2567 registers that need to be saved */
2570 /* then do the push */
2571 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2574 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2575 size = AOP_SIZE(IC_LEFT(ic));
2578 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2579 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2580 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2582 pic16_emitcode("mov","a,%s",l);
2583 pic16_emitcode("push","acc");
2585 pic16_emitcode("push","%s",l);
2588 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2592 /*-----------------------------------------------------------------*/
2593 /* genIpop - recover the registers: can happen only for spilling */
2594 /*-----------------------------------------------------------------*/
2595 static void genIpop (iCode *ic)
2597 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2602 /* if the temp was not pushed then */
2603 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2606 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2607 size = AOP_SIZE(IC_LEFT(ic));
2610 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2613 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2617 /*-----------------------------------------------------------------*/
2618 /* unsaverbank - restores the resgister bank from stack */
2619 /*-----------------------------------------------------------------*/
2620 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2622 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2628 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2630 if (options.useXstack) {
2632 r = getFreePtr(ic,&aop,FALSE);
2635 pic16_emitcode("mov","%s,_spx",r->name);
2636 pic16_emitcode("movx","a,@%s",r->name);
2637 pic16_emitcode("mov","psw,a");
2638 pic16_emitcode("dec","%s",r->name);
2641 pic16_emitcode ("pop","psw");
2644 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2645 if (options.useXstack) {
2646 pic16_emitcode("movx","a,@%s",r->name);
2647 //pic16_emitcode("mov","(%s+%d),a",
2648 // regspic16[i].base,8*bank+regspic16[i].offset);
2649 pic16_emitcode("dec","%s",r->name);
2652 pic16_emitcode("pop",""); //"(%s+%d)",
2653 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2656 if (options.useXstack) {
2658 pic16_emitcode("mov","_spx,%s",r->name);
2659 pic16_freeAsmop(NULL,aop,ic,TRUE);
2665 /*-----------------------------------------------------------------*/
2666 /* saverbank - saves an entire register bank on the stack */
2667 /*-----------------------------------------------------------------*/
2668 static void saverbank (int bank, iCode *ic, bool pushPsw)
2670 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2676 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2677 if (options.useXstack) {
2680 r = getFreePtr(ic,&aop,FALSE);
2681 pic16_emitcode("mov","%s,_spx",r->name);
2685 for (i = 0 ; i < pic16_nRegs ;i++) {
2686 if (options.useXstack) {
2687 pic16_emitcode("inc","%s",r->name);
2688 //pic16_emitcode("mov","a,(%s+%d)",
2689 // regspic16[i].base,8*bank+regspic16[i].offset);
2690 pic16_emitcode("movx","@%s,a",r->name);
2692 pic16_emitcode("push","");// "(%s+%d)",
2693 //regspic16[i].base,8*bank+regspic16[i].offset);
2697 if (options.useXstack) {
2698 pic16_emitcode("mov","a,psw");
2699 pic16_emitcode("movx","@%s,a",r->name);
2700 pic16_emitcode("inc","%s",r->name);
2701 pic16_emitcode("mov","_spx,%s",r->name);
2702 pic16_freeAsmop (NULL,aop,ic,TRUE);
2705 pic16_emitcode("push","psw");
2707 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2715 /*-----------------------------------------------------------------*/
2716 /* genCall - generates a call statement */
2717 /*-----------------------------------------------------------------*/
2718 static void genCall (iCode *ic)
2723 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2725 /* if caller saves & we have not saved then */
2729 /* if we are calling a function that is not using
2730 * the same register bank then we need to save the
2731 * destination registers on the stack */
2732 dtype = operandType(IC_LEFT(ic));
2733 if (currFunc && dtype &&
2734 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2735 IFFUNC_ISISR(currFunc->type) &&
2738 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2740 /* if send set is not empty the assign */
2744 /* For the Pic port, there is no data stack.
2745 * So parameters passed to functions are stored
2746 * in registers. (The pCode optimizer will get
2747 * rid of most of these :). */
2749 int psuedoStkPtr=-1;
2750 int firstTimeThruLoop = 1;
2752 _G.sendSet = reverseSet(_G.sendSet);
2754 /* First figure how many parameters are getting passed */
2755 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2756 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2757 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2758 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2761 stackParms = psuedoStkPtr;
2763 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2764 int size, offset = 0;
2766 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2767 size = AOP_SIZE(IC_LEFT(sic));
2770 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2771 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2772 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2774 if(!firstTimeThruLoop) {
2775 /* If this is not the first time we've been through the loop
2776 * then we need to save the parameter in a temporary
2777 * register. The last byte of the last parameter is
2781 --psuedoStkPtr; // sanity check
2784 firstTimeThruLoop=0;
2786 mov2w (AOP(IC_LEFT(sic)), offset);
2789 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2795 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2796 OP_SYMBOL(IC_LEFT(ic))->rname :
2797 OP_SYMBOL(IC_LEFT(ic))->name));
2800 /* if we need assign a result value */
2801 if ((IS_ITEMP(IC_RESULT(ic)) &&
2802 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2803 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2804 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2807 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2810 assignResultValue(IC_RESULT(ic), 1);
2812 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2813 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2815 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2819 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2820 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2821 if(STACK_MODEL_LARGE) {
2823 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2827 /* adjust the stack for parameters if required */
2828 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2830 if (ic->parmBytes) {
2833 if (ic->parmBytes > 3) {
2834 pic16_emitcode("mov","a,%s",spname);
2835 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2836 pic16_emitcode("mov","%s,a",spname);
2838 for ( i = 0 ; i < ic->parmBytes ;i++)
2839 pic16_emitcode("dec","%s",spname);
2843 /* if register bank was saved then pop them */
2845 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2847 /* if we hade saved some registers then unsave them */
2848 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2849 unsaveRegisters (ic);
2855 /*-----------------------------------------------------------------*/ // patch 14
2856 /* genPcall - generates a call by pointer statement */
2857 /*-----------------------------------------------------------------*/
2859 // new version, created from genCall
2861 static void genPcall (iCode *ic)
2865 symbol *retlbl = newiTempLabel(NULL);
2866 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
2868 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2870 /* if caller saves & we have not saved then */
2874 /* if we are calling a function that is not using
2875 * the same register bank then we need to save the
2876 * destination registers on the stack */
2877 dtype = operandType(IC_LEFT(ic));
2878 if (currFunc && dtype &&
2879 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2880 IFFUNC_ISISR(currFunc->type) &&
2883 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2885 /* if send set is not empty the assign */
2889 /* For the Pic port, there is no data stack.
2890 * So parameters passed to functions are stored
2891 * in registers. (The pCode optimizer will get
2892 * rid of most of these :). */
2894 int psuedoStkPtr=-1;
2895 int firstTimeThruLoop = 1;
2897 _G.sendSet = reverseSet(_G.sendSet);
2899 /* First figure how many parameters are getting passed */
2900 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2901 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2902 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2903 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2906 stackParms = psuedoStkPtr;
2908 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2909 int size, offset = 0;
2911 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2912 size = AOP_SIZE(IC_LEFT(sic));
2915 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2916 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2917 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2919 if(!firstTimeThruLoop) {
2920 /* If this is not the first time we've been through the loop
2921 * then we need to save the parameter in a temporary
2922 * register. The last byte of the last parameter is
2926 --psuedoStkPtr; // sanity check
2929 firstTimeThruLoop=0;
2931 mov2w (AOP(IC_LEFT(sic)), offset);
2934 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2939 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2941 // push return address
2942 // push $ on return stack, then replace with retlbl
2944 // Note: retlbl is supplied as dummy operand to PUSH
2945 // This has the nice side effect of keeping the label from being optimized out :o)
2946 pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key));
2948 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
2949 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
2950 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
2951 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
2952 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
2953 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
2955 /* make the call by writing the pointer into pc */
2956 // FIXME Disabled writes to PCLATU because of gpsim problems
2958 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
2961 "WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
2962 Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
2965 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
2966 // note: MOVFF to PCL not allowed
2967 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
2968 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
2970 /* return address is here: (X) */
2971 pic16_emitpLabel(retlbl->key);
2973 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2976 /* if we need assign a result value */
2977 if ((IS_ITEMP(IC_RESULT(ic)) &&
2978 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2979 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2980 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2983 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2986 assignResultValue(IC_RESULT(ic), 1);
2988 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2989 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2991 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2995 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2996 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2997 if(STACK_MODEL_LARGE) {
2999 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
3003 /* adjust the stack for parameters if required */
3004 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
3006 if (ic->parmBytes) {
3009 if (ic->parmBytes > 3) {
3010 pic16_emitcode("mov","a,%s",spname);
3011 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3012 pic16_emitcode("mov","%s,a",spname);
3014 for ( i = 0 ; i < ic->parmBytes ;i++)
3015 pic16_emitcode("dec","%s",spname);
3018 /* if register bank was saved then pop them */
3020 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3022 /* if we hade saved some registers then unsave them */
3023 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3024 unsaveRegisters (ic);
3029 // old version, kept for reference
3031 /*-----------------------------------------------------------------*/
3032 /* genPcall - generates a call by pointer statement */
3033 /*-----------------------------------------------------------------*/
3034 static void genPcall (iCode *ic)
3037 symbol *rlbl = newiTempLabel(NULL);
3040 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3041 /* if caller saves & we have not saved then */
3045 /* if we are calling a function that is not using
3046 the same register bank then we need to save the
3047 destination registers on the stack */
3048 dtype = operandType(IC_LEFT(ic));
3049 if (currFunc && dtype &&
3050 IFFUNC_ISISR(currFunc->type) &&
3051 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3052 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3055 /* push the return address on to the stack */
3056 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
3057 pic16_emitcode("push","acc");
3058 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
3059 pic16_emitcode("push","acc");
3061 if (options.model == MODEL_FLAT24)
3063 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
3064 pic16_emitcode("push","acc");
3067 /* now push the calling address */
3068 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3070 pushSide(IC_LEFT(ic), FPTRSIZE);
3072 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3074 /* if send set is not empty the assign */
3078 for (sic = setFirstItem(_G.sendSet) ; sic ;
3079 sic = setNextItem(_G.sendSet)) {
3080 int size, offset = 0;
3081 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3082 size = AOP_SIZE(IC_LEFT(sic));
3084 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
3086 if (strcmp(l,fReturn[offset]))
3087 pic16_emitcode("mov","%s,%s",
3092 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3097 pic16_emitcode("ret","");
3098 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
3101 /* if we need assign a result value */
3102 if ((IS_ITEMP(IC_RESULT(ic)) &&
3103 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3104 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
3105 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3108 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3111 assignResultValue(IC_RESULT(ic), 1);
3113 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3116 /* adjust the stack for parameters if
3118 if (ic->parmBytes) {
3120 if (ic->parmBytes > 3) {
3121 pic16_emitcode("mov","a,%s",spname);
3122 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3123 pic16_emitcode("mov","%s,a",spname);
3125 for ( i = 0 ; i < ic->parmBytes ;i++)
3126 pic16_emitcode("dec","%s",spname);
3130 /* if register bank was saved then unsave them */
3131 if (currFunc && dtype &&
3132 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3133 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3135 /* if we hade saved some registers then
3138 unsaveRegisters (ic);
3144 /*-----------------------------------------------------------------*/
3145 /* resultRemat - result is rematerializable */
3146 /*-----------------------------------------------------------------*/
3147 static int resultRemat (iCode *ic)
3149 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3150 if (SKIP_IC(ic) || ic->op == IFX)
3153 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3154 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3155 if (sym->remat && !POINTER_SET(ic))
3162 #if defined(__BORLANDC__) || defined(_MSC_VER)
3163 #define STRCASECMP stricmp
3165 #define STRCASECMP strcasecmp
3169 /*-----------------------------------------------------------------*/
3170 /* inExcludeList - return 1 if the string is in exclude Reg list */
3171 /*-----------------------------------------------------------------*/
3172 static bool inExcludeList(char *s)
3174 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3177 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3178 if (options.excludeRegs[i] &&
3179 STRCASECMP(options.excludeRegs[i],"none") == 0)
3182 for ( i = 0 ; options.excludeRegs[i]; i++) {
3183 if (options.excludeRegs[i] &&
3184 STRCASECMP(s,options.excludeRegs[i]) == 0)
3191 /*-----------------------------------------------------------------*/
3192 /* genFunction - generated code for function entry */
3193 /*-----------------------------------------------------------------*/
3194 static void genFunction (iCode *ic)
3199 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
3201 labelOffset += (max_key+4);
3206 ftype = operandType(IC_LEFT(ic));
3207 sym = OP_SYMBOL(IC_LEFT(ic));
3209 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3210 /* create an absolute section at the interrupt vector:
3211 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3219 sym = OP_SYMBOL( IC_LEFT(ic));
3221 if(interrupts[i]->name
3222 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3229 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3230 __FILE__, __LINE__, sym->name);
3233 _G.interruptvector = found;
3236 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3237 asym = newSymbol(asymname, 0);
3239 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3240 pic16_addpBlock( apb );
3242 pic16_addpCode2pBlock(apb,
3243 pic16_newpCodeCharP(";-----------------------------------------"));
3246 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3248 pic16_addpCode2pBlock(apb,
3249 pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3251 /* mark the end of this tiny function */
3252 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3257 abSym = Safe_calloc(1, sizeof(absSym));
3258 abSym->name = Safe_strdup( asymname );
3260 switch( _G.interruptvector ) {
3261 case 0: abSym->address = 0x000000; break;
3262 case 1: abSym->address = 0x000008; break;
3263 case 2: abSym->address = 0x000018; break;
3266 addSet(&absSymSet, abSym);
3271 /* create the function header */
3272 pic16_emitcode(";","-----------------------------------------");
3273 pic16_emitcode(";"," function %s",sym->name);
3274 pic16_emitcode(";","-----------------------------------------");
3276 pic16_emitcode("","%s:",sym->rname);
3277 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3283 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3284 if(!strcmp(ab->name, sym->name)) {
3285 pic16_pBlockConvert2Absolute(pb);
3292 if(IFFUNC_ISNAKED(ftype)) {
3293 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3297 /* if critical function then turn interrupts off */
3298 if (IFFUNC_ISCRITICAL(ftype))
3299 pic16_emitcode("clr","ea");
3301 /* if this is an interrupt service routine then
3302 * save acc, b, dpl, dph */
3303 if (IFFUNC_ISISR(sym->type)) {
3305 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3306 if(!(_G.interruptvector == 1)) {
3308 /* do not save WREG,STATUS,BSR for high priority interrupts
3309 * because they are stored in the hardware shadow registers already */
3311 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3312 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3313 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3316 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3317 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3318 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3319 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3321 // pic16_pBlockConvert2ISR(pb);
3323 /* if any registers used */
3324 if (sym->regsUsed) {
3325 /* save the registers used */
3326 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3327 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3328 if (bitVectBitValue(sym->regsUsed,i)) {
3329 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3330 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3331 // pic16_regWithIdx(i)->name);
3333 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3339 /* emit code to setup stack frame if user enabled,
3340 * and function is not main() */
3342 // fprintf(stderr, "function name: %s\n", sym->name);
3343 if(strcmp(sym->name, "main")) {
3344 if(/*!options.ommitFramePtr || */sym->regsUsed) {
3345 /* setup the stack frame */
3346 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3347 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3348 if(STACK_MODEL_LARGE)
3349 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3353 /* if callee-save to be used for this function
3354 * then save the registers being used in this function */
3355 // if (IFFUNC_CALLEESAVES(sym->type))
3359 // fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
3361 // pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3363 /* if any registers used */
3364 if (sym->regsUsed) {
3365 /* save the registers used */
3366 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3367 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3368 if (bitVectBitValue(sym->regsUsed,i)) {
3370 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3371 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3372 // pic16_regWithIdx(i)->name);
3374 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3376 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3377 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3378 // &pic16_pc_postdec1, 0));
3390 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3392 if (options.useXstack) {
3393 pic16_emitcode("mov","r0,%s",spname);
3394 pic16_emitcode("mov","a,_bp");
3395 pic16_emitcode("movx","@r0,a");
3396 pic16_emitcode("inc","%s",spname);
3398 /* set up the stack */
3399 pic16_emitcode ("push","_bp"); /* save the callers stack */
3401 pic16_emitcode ("mov","_bp,%s",spname);
3404 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3406 /* adjust the stack for the function */
3411 werror(W_STACK_OVERFLOW,sym->name);
3413 if (i > 3 && sym->recvSize < 4) {
3414 pic16_emitcode ("mov","a,sp");
3415 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3416 pic16_emitcode ("mov","sp,a");
3419 pic16_emitcode("inc","sp");
3423 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3425 pic16_emitcode ("mov","a,_spx");
3426 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3427 pic16_emitcode ("mov","_spx,a");
3432 /*-----------------------------------------------------------------*/
3433 /* genEndFunction - generates epilogue for functions */
3434 /*-----------------------------------------------------------------*/
3435 static void genEndFunction (iCode *ic)
3437 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3439 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3441 if(IFFUNC_ISNAKED(sym->type)) {
3442 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3447 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3449 pic16_emitcode ("mov","%s,_bp",spname);
3453 /* if use external stack but some variables were
3454 added to the local stack then decrement the
3456 if (options.useXstack && sym->stack) {
3457 pic16_emitcode("mov","a,sp");
3458 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3459 pic16_emitcode("mov","sp,a");
3464 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3465 if (options.useXstack) {
3466 pic16_emitcode("mov","r0,%s",spname);
3467 pic16_emitcode("movx","a,@r0");
3468 pic16_emitcode("mov","_bp,a");
3469 pic16_emitcode("dec","%s",spname);
3473 pic16_emitcode ("pop","_bp");
3478 if (IFFUNC_ISISR(sym->type)) {
3479 /* now we need to restore the registers */
3480 /* if any registers used */
3481 if (sym->regsUsed) {
3484 /* restore registers used */
3485 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3486 for ( i = sym->regsUsed->size; i >= 0; i--) {
3487 if (bitVectBitValue(sym->regsUsed,i)) {
3489 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3490 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3491 // pic16_regWithIdx(i)->name);
3493 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3495 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3496 // &pic16_pc_preinc1,
3497 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3503 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3504 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3505 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3506 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3508 if(!(_G.interruptvector == 1)) {
3509 /* do not restore interrupt vector for WREG,STATUS,BSR
3510 * for high priority interrupt, see genFunction */
3512 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3513 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3514 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3517 _G.interruptvector = 0; /* sanity check */
3519 // pic16_pBlockConvert2ISR(pb);
3522 /* if debug then send end of function */
3523 /* if (options.debug && currFunc) */
3525 debugFile->writeEndFunction (currFunc, ic, 1);
3528 pic16_emitpcodeNULLop(POC_RETFIE);
3530 if (IFFUNC_ISCRITICAL(sym->type))
3531 pic16_emitcode("setb","ea");
3534 // pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3536 /* if any registers used */
3537 if (sym->regsUsed) {
3539 /* save the registers used */
3540 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3541 for ( i = sym->regsUsed->size; i >= 0; i--) {
3542 if (bitVectBitValue(sym->regsUsed,i)) {
3544 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3545 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3546 // pic16_regWithIdx(i)->name);
3548 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3550 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3551 // &pic16_pc_preinc1,
3552 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3559 pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
3560 /* if debug then send end of function */
3562 debugFile->writeEndFunction (currFunc, ic, 1);
3565 /* insert code to restore stack frame, if user enabled it
3566 * and function is not main() */
3569 if(strcmp(sym->name, "main")) {
3570 if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
3571 /* restore stack frame */
3572 if(STACK_MODEL_LARGE)
3573 pic16_emitpcode(POC_MOVFF,
3574 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3575 pic16_emitpcode(POC_MOVFF,
3576 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3580 pic16_emitcode ("return","");
3581 pic16_emitpcodeNULLop(POC_RETURN);
3583 /* Mark the end of a function */
3584 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3590 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3592 // (AOP(left)->aopu.pcop->type == PO_DIR)?
3594 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3595 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
3596 pic16_emitpcode(POC_MOVWF, dest);
3598 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3599 pic16_popGet(AOP(op), offset), dest));
3603 /*-----------------------------------------------------------------*/
3604 /* genRet - generate code for return statement */
3605 /*-----------------------------------------------------------------*/
3606 static void genRet (iCode *ic)
3611 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3612 /* if we have no return value then
3613 * just generate the "ret" */
3618 /* we have something to return then
3619 * move the return value into place */
3620 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3621 size = AOP_SIZE(IC_LEFT(ic));
3625 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3626 // pic16_emitpcode(POC_MOVFF,
3627 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3630 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3631 // pic16_emitpcode(POC_MOVFF,
3632 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3635 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3636 // pic16_emitpcode(POC_MOVFF,
3637 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3640 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3642 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3643 // pic16_emitpcode(POC_MOVFF,
3644 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3647 /* >32-bits, setup stack and FSR0 */
3649 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3650 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3652 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3654 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3659 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3660 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3662 if(STACK_MODEL_LARGE) {
3663 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3664 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3666 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3671 /* old code, left here for reference -- VR */
3675 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3677 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3678 pic16_emitpcomment("push %s",l);
3681 DEBUGpic16_emitcode(";", "%d", __LINE__);
3682 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3683 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3685 if (strcmp(fReturn[offset],l)) {
3686 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3687 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3688 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3690 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3694 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3704 if (strcmp(fReturn[pushed],"a"))
3705 pic16_emitcode("pop",fReturn[pushed]);
3707 pic16_emitcode("pop","acc");
3713 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3716 /* generate a jump to the return label
3717 * if the next is not the return statement */
3718 if (!(ic->next && ic->next->op == LABEL
3719 && IC_LABEL(ic->next) == returnLabel)) {
3721 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3722 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3726 /*-----------------------------------------------------------------*/
3727 /* genLabel - generates a label */
3728 /*-----------------------------------------------------------------*/
3729 static void genLabel (iCode *ic)
3733 /* special case never generate */
3734 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3735 if (IC_LABEL(ic) == entryLabel)
3738 pic16_emitpLabel(IC_LABEL(ic)->key);
3739 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3742 /*-----------------------------------------------------------------*/
3743 /* genGoto - generates a goto */
3744 /*-----------------------------------------------------------------*/
3746 static void genGoto (iCode *ic)
3748 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3749 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3753 /*-----------------------------------------------------------------*/
3754 /* genMultbits :- multiplication of bits */
3755 /*-----------------------------------------------------------------*/
3756 static void genMultbits (operand *left,
3760 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3762 if(!pic16_sameRegs(AOP(result),AOP(right)))
3763 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3765 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3766 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3767 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3772 /*-----------------------------------------------------------------*/
3773 /* genMultOneByte : 8 bit multiplication & division */
3774 /*-----------------------------------------------------------------*/
3775 static void genMultOneByte (operand *left,
3780 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3781 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3782 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3784 /* (if two literals, the value is computed before) */
3785 /* if one literal, literal on the right */
3786 if (AOP_TYPE(left) == AOP_LIT){
3792 /* size is already checked in genMult == 1 */
3793 // size = AOP_SIZE(result);
3795 if (AOP_TYPE(right) == AOP_LIT){
3796 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3797 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3798 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3799 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3801 pic16_emitpcomment("multiply variable :%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));
3807 pic16_genMult8X8_8 (left, right,result);
3811 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3812 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3813 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3814 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3816 if (SPEC_USIGN(opetype)){
3817 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3818 pic16_genUMult8X8_16 (left, right, result, NULL);
3821 /* for filling the MSBs */
3822 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3823 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3827 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3829 pic16_emitcode("mov","a,b");
3831 /* adjust the MSB if left or right neg */
3833 /* if one literal */
3834 if (AOP_TYPE(right) == AOP_LIT){
3835 pic16_emitcode("multiply ","right is a lit");
3836 /* AND literal negative */
3837 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3838 /* adjust MSB (c==0 after mul) */
3839 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3843 pic16_genSMult8X8_16 (left, right, result, NULL);
3847 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3849 pic16_emitcode("rlc","a");
3850 pic16_emitcode("subb","a,acc");
3858 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3859 //pic16_aopPut(AOP(result),"a",offset++);
3866 /*-----------------------------------------------------------------*/
3867 /* genMultOneWord : 16 bit multiplication */
3868 /*-----------------------------------------------------------------*/
3869 static void genMultOneWord (operand *left,
3874 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3875 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3876 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3878 /* (if two literals, the value is computed before)
3879 * if one literal, literal on the right */
3880 if (AOP_TYPE(left) == AOP_LIT){
3886 /* size is checked already == 2 */
3887 // size = AOP_SIZE(result);
3889 if (AOP_TYPE(right) == AOP_LIT) {
3890 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3891 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3892 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3893 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3895 pic16_emitpcomment("multiply variable :%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));
3901 pic16_genMult16X16_16(left, right,result);
3904 /*-----------------------------------------------------------------*/
3905 /* genMultOneLong : 32 bit multiplication */
3906 /*-----------------------------------------------------------------*/
3907 static void genMultOneLong (operand *left,
3912 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3913 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3914 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3916 /* (if two literals, the value is computed before)
3917 * if one literal, literal on the right */
3918 if (AOP_TYPE(left) == AOP_LIT){
3924 /* size is checked already == 4 */
3925 // size = AOP_SIZE(result);
3927 if (AOP_TYPE(right) == AOP_LIT) {
3928 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3929 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3930 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3931 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3933 pic16_emitpcomment("multiply variable :%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));
3939 pic16_genMult32X32_32(left, right,result);
3944 /*-----------------------------------------------------------------*/
3945 /* genMult - generates code for multiplication */
3946 /*-----------------------------------------------------------------*/
3947 static void genMult (iCode *ic)
3949 operand *left = IC_LEFT(ic);
3950 operand *right = IC_RIGHT(ic);
3951 operand *result= IC_RESULT(ic);
3953 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3954 /* assign the amsops */
3955 pic16_aopOp (left,ic,FALSE);
3956 pic16_aopOp (right,ic,FALSE);
3957 pic16_aopOp (result,ic,TRUE);
3959 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3961 /* special cases first *
3963 if (AOP_TYPE(left) == AOP_CRY
3964 && AOP_TYPE(right)== AOP_CRY) {
3965 genMultbits(left,right,result);
3969 /* if both are of size == 1 */
3970 if(AOP_SIZE(left) == 1
3971 && AOP_SIZE(right) == 1) {
3972 genMultOneByte(left,right,result);
3976 /* if both are of size == 2 */
3977 if(AOP_SIZE(left) == 2
3978 && AOP_SIZE(right) == 2) {
3979 genMultOneWord(left, right, result);
3983 /* if both are of size == 4 */
3984 if(AOP_SIZE(left) == 4
3985 && AOP_SIZE(right) == 4) {
3986 genMultOneLong(left, right, result);
3990 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
3993 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
3994 /* should have been converted to function call */
3998 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3999 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4000 pic16_freeAsmop(result,NULL,ic,TRUE);
4003 /*-----------------------------------------------------------------*/
4004 /* genDivbits :- division of bits */
4005 /*-----------------------------------------------------------------*/
4006 static void genDivbits (operand *left,
4013 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4014 /* the result must be bit */
4015 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4016 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4020 pic16_emitcode("div","ab");
4021 pic16_emitcode("rrc","a");
4022 pic16_aopPut(AOP(result),"c",0);
4025 /*-----------------------------------------------------------------*/
4026 /* genDivOneByte : 8 bit division */
4027 /*-----------------------------------------------------------------*/
4028 static void genDivOneByte (operand *left,
4032 sym_link *opetype = operandType(result);
4037 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4038 size = AOP_SIZE(result) - 1;
4040 /* signed or unsigned */
4041 if (SPEC_USIGN(opetype)) {
4042 /* unsigned is easy */
4043 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4044 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4046 pic16_emitcode("div","ab");
4047 pic16_aopPut(AOP(result),"a",0);
4049 pic16_aopPut(AOP(result),zero,offset++);
4053 /* signed is a little bit more difficult */
4055 /* save the signs of the operands */
4056 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4058 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4059 pic16_emitcode("push","acc"); /* save it on the stack */
4061 /* now sign adjust for both left & right */
4062 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4064 lbl = newiTempLabel(NULL);
4065 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4066 pic16_emitcode("cpl","a");
4067 pic16_emitcode("inc","a");
4068 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4069 pic16_emitcode("mov","b,a");
4071 /* sign adjust left side */
4072 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4075 lbl = newiTempLabel(NULL);
4076 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4077 pic16_emitcode("cpl","a");
4078 pic16_emitcode("inc","a");
4079 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4081 /* now the division */
4082 pic16_emitcode("div","ab");
4083 /* we are interested in the lower order
4085 pic16_emitcode("mov","b,a");
4086 lbl = newiTempLabel(NULL);
4087 pic16_emitcode("pop","acc");
4088 /* if there was an over flow we don't
4089 adjust the sign of the result */
4090 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4091 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4093 pic16_emitcode("clr","a");
4094 pic16_emitcode("subb","a,b");
4095 pic16_emitcode("mov","b,a");
4096 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4098 /* now we are done */
4099 pic16_aopPut(AOP(result),"b",0);
4101 pic16_emitcode("mov","c,b.7");
4102 pic16_emitcode("subb","a,acc");
4105 pic16_aopPut(AOP(result),"a",offset++);
4109 /*-----------------------------------------------------------------*/
4110 /* genDiv - generates code for division */
4111 /*-----------------------------------------------------------------*/
4112 static void genDiv (iCode *ic)
4114 operand *left = IC_LEFT(ic);
4115 operand *right = IC_RIGHT(ic);
4116 operand *result= IC_RESULT(ic);
4118 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4119 /* assign the amsops */
4120 pic16_aopOp (left,ic,FALSE);
4121 pic16_aopOp (right,ic,FALSE);
4122 pic16_aopOp (result,ic,TRUE);
4124 /* special cases first */
4126 if (AOP_TYPE(left) == AOP_CRY &&
4127 AOP_TYPE(right)== AOP_CRY) {
4128 genDivbits(left,right,result);
4132 /* if both are of size == 1 */
4133 if (AOP_SIZE(left) == 1 &&
4134 AOP_SIZE(right) == 1 ) {
4135 genDivOneByte(left,right,result);
4139 /* should have been converted to function call */
4142 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4143 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4144 pic16_freeAsmop(result,NULL,ic,TRUE);
4147 /*-----------------------------------------------------------------*/
4148 /* genModbits :- modulus of bits */
4149 /*-----------------------------------------------------------------*/
4150 static void genModbits (operand *left,
4157 /* the result must be bit */
4158 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4159 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4163 pic16_emitcode("div","ab");
4164 pic16_emitcode("mov","a,b");
4165 pic16_emitcode("rrc","a");
4166 pic16_aopPut(AOP(result),"c",0);
4169 /*-----------------------------------------------------------------*/
4170 /* genModOneByte : 8 bit modulus */
4171 /*-----------------------------------------------------------------*/
4172 static void genModOneByte (operand *left,
4176 sym_link *opetype = operandType(result);
4180 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4181 /* signed or unsigned */
4182 if (SPEC_USIGN(opetype)) {
4183 /* unsigned is easy */
4184 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4185 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4187 pic16_emitcode("div","ab");
4188 pic16_aopPut(AOP(result),"b",0);
4192 /* signed is a little bit more difficult */
4194 /* save the signs of the operands */
4195 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4198 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4199 pic16_emitcode("push","acc"); /* save it on the stack */
4201 /* now sign adjust for both left & right */
4202 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4205 lbl = newiTempLabel(NULL);
4206 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4207 pic16_emitcode("cpl","a");
4208 pic16_emitcode("inc","a");
4209 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4210 pic16_emitcode("mov","b,a");
4212 /* sign adjust left side */
4213 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4216 lbl = newiTempLabel(NULL);
4217 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4218 pic16_emitcode("cpl","a");
4219 pic16_emitcode("inc","a");
4220 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4222 /* now the multiplication */
4223 pic16_emitcode("div","ab");
4224 /* we are interested in the lower order
4226 lbl = newiTempLabel(NULL);
4227 pic16_emitcode("pop","acc");
4228 /* if there was an over flow we don't
4229 adjust the sign of the result */
4230 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4231 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4233 pic16_emitcode("clr","a");
4234 pic16_emitcode("subb","a,b");
4235 pic16_emitcode("mov","b,a");
4236 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4238 /* now we are done */
4239 pic16_aopPut(AOP(result),"b",0);
4243 /*-----------------------------------------------------------------*/
4244 /* genMod - generates code for division */
4245 /*-----------------------------------------------------------------*/
4246 static void genMod (iCode *ic)
4248 operand *left = IC_LEFT(ic);
4249 operand *right = IC_RIGHT(ic);
4250 operand *result= IC_RESULT(ic);
4252 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4253 /* assign the amsops */
4254 pic16_aopOp (left,ic,FALSE);
4255 pic16_aopOp (right,ic,FALSE);
4256 pic16_aopOp (result,ic,TRUE);
4258 /* special cases first */
4260 if (AOP_TYPE(left) == AOP_CRY &&
4261 AOP_TYPE(right)== AOP_CRY) {
4262 genModbits(left,right,result);
4266 /* if both are of size == 1 */
4267 if (AOP_SIZE(left) == 1 &&
4268 AOP_SIZE(right) == 1 ) {
4269 genModOneByte(left,right,result);
4273 /* should have been converted to function call */
4277 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4278 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4279 pic16_freeAsmop(result,NULL,ic,TRUE);
4282 /*-----------------------------------------------------------------*/
4283 /* genIfxJump :- will create a jump depending on the ifx */
4284 /*-----------------------------------------------------------------*/
4286 note: May need to add parameter to indicate when a variable is in bit space.
4288 static void genIfxJump (iCode *ic, char *jval)
4291 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4292 /* if true label then we jump if condition
4294 if ( IC_TRUE(ic) ) {
4296 if(strcmp(jval,"a") == 0)
4298 else if (strcmp(jval,"c") == 0)
4301 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4302 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
4305 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4306 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
4310 /* false label is present */
4311 if(strcmp(jval,"a") == 0)
4313 else if (strcmp(jval,"c") == 0)
4316 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4317 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
4320 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4321 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
4326 /* mark the icode as generated */
4333 /*-----------------------------------------------------------------*/
4335 /*-----------------------------------------------------------------*/
4336 static void genSkip(iCode *ifx,int status_bit)
4338 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4342 if ( IC_TRUE(ifx) ) {
4343 switch(status_bit) {
4358 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4359 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4363 switch(status_bit) {
4377 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4378 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4385 /*-----------------------------------------------------------------*/
4387 /*-----------------------------------------------------------------*/
4388 static void genSkipc(resolvedIfx *rifx)
4390 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4400 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4401 rifx->generated = 1;
4404 /*-----------------------------------------------------------------*/
4406 /*-----------------------------------------------------------------*/
4407 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4409 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4414 if( (rifx->condition ^ invert_condition) & 1)
4419 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4420 rifx->generated = 1;
4424 /*-----------------------------------------------------------------*/
4426 /*-----------------------------------------------------------------*/
4427 static void genSkipz(iCode *ifx, int condition)
4438 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4440 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4443 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4445 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4450 /*-----------------------------------------------------------------*/
4452 /*-----------------------------------------------------------------*/
4453 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4459 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4461 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4464 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4465 rifx->generated = 1;
4469 /*-----------------------------------------------------------------*/
4470 /* genChkZeroes :- greater or less than comparison */
4471 /* For each byte in a literal that is zero, inclusive or the */
4472 /* the corresponding byte in the operand with W */
4473 /* returns true if any of the bytes are zero */
4474 /*-----------------------------------------------------------------*/
4475 static int genChkZeroes(operand *op, int lit, int size)
4482 i = (lit >> (size*8)) & 0xff;
4486 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4488 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4497 /*-----------------------------------------------------------------*/
4498 /* genCmp :- greater or less than comparison */
4499 /*-----------------------------------------------------------------*/
4500 static void genCmp (operand *left,operand *right,
4501 operand *result, iCode *ifx, int sign)
4503 int size; //, offset = 0 ;
4504 unsigned long lit = 0L,i = 0;
4505 resolvedIfx rFalseIfx;
4506 // resolvedIfx rTrueIfx;
4508 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4511 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4512 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4516 resolveIfx(&rFalseIfx,ifx);
4517 truelbl = newiTempLabel(NULL);
4518 size = max(AOP_SIZE(left),AOP_SIZE(right));
4520 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4524 /* if literal is on the right then swap with left */
4525 if ((AOP_TYPE(right) == AOP_LIT)) {
4526 operand *tmp = right ;
4527 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4528 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4531 lit = (lit - 1) & mask;
4534 rFalseIfx.condition ^= 1;
4537 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4538 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4542 //if(IC_TRUE(ifx) == NULL)
4543 /* if left & right are bit variables */
4544 if (AOP_TYPE(left) == AOP_CRY &&
4545 AOP_TYPE(right) == AOP_CRY ) {
4546 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4547 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4549 /* subtract right from left if at the
4550 end the carry flag is set then we know that
4551 left is greater than right */
4553 symbol *lbl = newiTempLabel(NULL);
4556 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4557 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
4561 if(AOP_TYPE(right) == AOP_LIT) {
4563 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4565 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4572 genSkipCond(&rFalseIfx,left,size-1,7);
4574 /* no need to compare to 0...*/
4575 /* NOTE: this is a de-generate compare that most certainly
4576 * creates some dead code. */
4577 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4579 if(ifx) ifx->generated = 1;
4586 //i = (lit >> (size*8)) & 0xff;
4587 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4589 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4591 i = ((0-lit) & 0xff);
4594 /* lit is 0x7f, all signed chars are less than
4595 * this except for 0x7f itself */
4596 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4597 genSkipz2(&rFalseIfx,0);
4599 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4600 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4601 genSkipc(&rFalseIfx);
4606 genSkipz2(&rFalseIfx,1);
4608 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4609 genSkipc(&rFalseIfx);
4613 if(ifx) ifx->generated = 1;
4617 /* chars are out of the way. now do ints and longs */
4620 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4627 genSkipCond(&rFalseIfx,left,size,7);
4628 if(ifx) ifx->generated = 1;
4633 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4635 //rFalseIfx.condition ^= 1;
4636 //genSkipCond(&rFalseIfx,left,size,7);
4637 //rFalseIfx.condition ^= 1;
4639 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4640 if(rFalseIfx.condition)
4641 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4643 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4645 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4646 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4647 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4650 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4652 if(rFalseIfx.condition) {
4654 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4660 genSkipc(&rFalseIfx);
4661 pic16_emitpLabel(truelbl->key);
4662 if(ifx) ifx->generated = 1;
4669 if( (lit & 0xff) == 0) {
4670 /* lower byte is zero */
4671 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4672 i = ((lit >> 8) & 0xff) ^0x80;
4673 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4674 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4675 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4676 genSkipc(&rFalseIfx);
4679 if(ifx) ifx->generated = 1;
4684 /* Special cases for signed longs */
4685 if( (lit & 0xffffff) == 0) {
4686 /* lower byte is zero */
4687 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4688 i = ((lit >> 8*3) & 0xff) ^0x80;
4689 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4690 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4691 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4692 genSkipc(&rFalseIfx);
4695 if(ifx) ifx->generated = 1;
4703 if(lit & (0x80 << (size*8))) {
4704 /* lit is negative */
4705 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4707 //genSkipCond(&rFalseIfx,left,size,7);
4709 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4711 if(rFalseIfx.condition)
4712 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4714 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4718 /* lit is positive */
4719 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4720 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4721 if(rFalseIfx.condition)
4722 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4724 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4729 This works, but is only good for ints.
4730 It also requires a "known zero" register.
4731 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4732 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4733 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4734 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4735 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4736 genSkipc(&rFalseIfx);
4738 pic16_emitpLabel(truelbl->key);
4739 if(ifx) ifx->generated = 1;
4743 /* There are no more special cases, so perform a general compare */
4745 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4746 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4750 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4752 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4754 //rFalseIfx.condition ^= 1;
4755 genSkipc(&rFalseIfx);
4757 pic16_emitpLabel(truelbl->key);
4759 if(ifx) ifx->generated = 1;
4766 /* sign is out of the way. So now do an unsigned compare */
4767 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4770 /* General case - compare to an unsigned literal on the right.*/
4772 i = (lit >> (size*8)) & 0xff;
4773 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4774 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4776 i = (lit >> (size*8)) & 0xff;
4779 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4781 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4783 /* this byte of the lit is zero,
4784 *if it's not the last then OR in the variable */
4786 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4791 pic16_emitpLabel(lbl->key);
4792 // pic16_emitpLabel(truelbl->key);
4793 //if(emitFinalCheck)
4794 genSkipc(&rFalseIfx);
4796 pic16_emitpLabel(truelbl->key);
4798 if(ifx) ifx->generated = 1;
4805 if(AOP_TYPE(left) == AOP_LIT) {
4806 //symbol *lbl = newiTempLabel(NULL);
4808 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4811 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4814 if((lit == 0) && (sign == 0)){
4817 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4819 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4821 genSkipz2(&rFalseIfx,0);
4822 if(ifx) ifx->generated = 1;
4829 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4830 /* degenerate compare can never be true */
4831 if(rFalseIfx.condition == 0)
4832 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4834 if(ifx) ifx->generated = 1;
4839 /* signed comparisons to a literal byte */
4841 int lp1 = (lit+1) & 0xff;
4843 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4846 rFalseIfx.condition ^= 1;
4847 genSkipCond(&rFalseIfx,right,0,7);
4850 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4851 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4852 genSkipz2(&rFalseIfx,1);
4855 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4856 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4857 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4858 rFalseIfx.condition ^= 1;
4859 genSkipc(&rFalseIfx);
4863 /* unsigned comparisons to a literal byte */
4865 switch(lit & 0xff ) {
4867 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4868 genSkipz2(&rFalseIfx,0);
4871 rFalseIfx.condition ^= 1;
4872 genSkipCond(&rFalseIfx,right,0,7);
4876 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4877 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4878 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4879 rFalseIfx.condition ^= 1;
4880 if (AOP_TYPE(result) == AOP_CRY)
4881 genSkipc(&rFalseIfx);
4883 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4884 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4890 if(ifx) ifx->generated = 1;
4896 /* Size is greater than 1 */
4904 /* this means lit = 0xffffffff, or -1 */
4907 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4908 rFalseIfx.condition ^= 1;
4909 genSkipCond(&rFalseIfx,right,size,7);
4910 if(ifx) ifx->generated = 1;
4917 if(rFalseIfx.condition) {
4918 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4919 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4922 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4924 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4928 if(rFalseIfx.condition) {
4929 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4930 pic16_emitpLabel(truelbl->key);
4932 rFalseIfx.condition ^= 1;
4933 genSkipCond(&rFalseIfx,right,s,7);
4936 if(ifx) ifx->generated = 1;
4940 if((size == 1) && (0 == (lp1&0xff))) {
4941 /* lower byte of signed word is zero */
4942 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4943 i = ((lp1 >> 8) & 0xff) ^0x80;
4944 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4945 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4946 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4947 rFalseIfx.condition ^= 1;
4948 genSkipc(&rFalseIfx);
4951 if(ifx) ifx->generated = 1;
4955 if(lit & (0x80 << (size*8))) {
4956 /* Lit is less than zero */
4957 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4958 //rFalseIfx.condition ^= 1;
4959 //genSkipCond(&rFalseIfx,left,size,7);
4960 //rFalseIfx.condition ^= 1;
4961 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4962 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4964 if(rFalseIfx.condition)
4965 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4967 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4971 /* Lit is greater than or equal to zero */
4972 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4973 //rFalseIfx.condition ^= 1;
4974 //genSkipCond(&rFalseIfx,right,size,7);
4975 //rFalseIfx.condition ^= 1;
4977 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4978 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4980 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4981 if(rFalseIfx.condition)
4982 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4984 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4989 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4990 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4994 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4996 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4998 rFalseIfx.condition ^= 1;
4999 //rFalseIfx.condition = 1;
5000 genSkipc(&rFalseIfx);
5002 pic16_emitpLabel(truelbl->key);
5004 if(ifx) ifx->generated = 1;
5009 /* compare word or long to an unsigned literal on the right.*/
5014 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5017 break; /* handled above */
5020 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5022 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5023 genSkipz2(&rFalseIfx,0);
5027 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5029 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5032 if(rFalseIfx.condition)
5033 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5035 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5038 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5039 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5041 rFalseIfx.condition ^= 1;
5042 genSkipc(&rFalseIfx);
5045 pic16_emitpLabel(truelbl->key);
5047 if(ifx) ifx->generated = 1;
5053 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5054 i = (lit >> (size*8)) & 0xff;
5056 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5057 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5060 i = (lit >> (size*8)) & 0xff;
5063 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5065 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5067 /* this byte of the lit is zero,
5068 * if it's not the last then OR in the variable */
5070 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5075 pic16_emitpLabel(lbl->key);
5077 rFalseIfx.condition ^= 1;
5079 genSkipc(&rFalseIfx);
5083 pic16_emitpLabel(truelbl->key);
5084 if(ifx) ifx->generated = 1;
5088 /* Compare two variables */
5090 DEBUGpic16_emitcode(";sign","%d",sign);
5094 /* Sigh. thus sucks... */
5096 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5097 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5098 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5099 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5100 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5101 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5103 /* Signed char comparison */
5104 /* Special thanks to Nikolai Golovchenko for this snippet */
5105 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5106 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5107 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5108 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5109 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5110 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5112 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5113 genSkipc(&rFalseIfx);
5115 if(ifx) ifx->generated = 1;
5121 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5122 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5126 /* The rest of the bytes of a multi-byte compare */
5130 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5133 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5134 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5139 pic16_emitpLabel(lbl->key);
5141 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5142 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5143 (AOP_TYPE(result) == AOP_REG)) {
5144 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5145 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5147 genSkipc(&rFalseIfx);
5149 //genSkipc(&rFalseIfx);
5150 if(ifx) ifx->generated = 1;
5157 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5158 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5159 pic16_outBitC(result);
5161 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5162 /* if the result is used in the next
5163 ifx conditional branch then generate
5164 code a little differently */
5166 genIfxJump (ifx,"c");
5168 pic16_outBitC(result);
5169 /* leave the result in acc */
5174 /*-----------------------------------------------------------------*/
5175 /* genCmpGt :- greater than comparison */
5176 /*-----------------------------------------------------------------*/
5177 static void genCmpGt (iCode *ic, iCode *ifx)
5179 operand *left, *right, *result;
5180 sym_link *letype , *retype;
5183 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5185 right= IC_RIGHT(ic);
5186 result = IC_RESULT(ic);
5188 letype = getSpec(operandType(left));
5189 retype =getSpec(operandType(right));
5190 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5191 /* assign the amsops */
5192 pic16_aopOp (left,ic,FALSE);
5193 pic16_aopOp (right,ic,FALSE);
5194 pic16_aopOp (result,ic,TRUE);
5196 genCmp(right, left, result, ifx, sign);
5198 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5199 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5200 pic16_freeAsmop(result,NULL,ic,TRUE);
5203 /*-----------------------------------------------------------------*/
5204 /* genCmpLt - less than comparisons */
5205 /*-----------------------------------------------------------------*/
5206 static void genCmpLt (iCode *ic, iCode *ifx)
5208 operand *left, *right, *result;
5209 sym_link *letype , *retype;
5212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5214 right= IC_RIGHT(ic);
5215 result = IC_RESULT(ic);
5217 letype = getSpec(operandType(left));
5218 retype =getSpec(operandType(right));
5219 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5221 /* assign the amsops */
5222 pic16_aopOp (left,ic,FALSE);
5223 pic16_aopOp (right,ic,FALSE);
5224 pic16_aopOp (result,ic,TRUE);
5226 genCmp(left, right, result, ifx, sign);
5228 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5229 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5230 pic16_freeAsmop(result,NULL,ic,TRUE);
5235 // FIXME reenable literal optimisation when the pic16 port is stable
5237 /*-----------------------------------------------------------------*/
5238 /* genc16bit2lit - compare a 16 bit value to a literal */
5239 /*-----------------------------------------------------------------*/
5240 static void genc16bit2lit(operand *op, int lit, int offset)
5244 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5245 if( (lit&0xff) == 0)
5250 switch( BYTEofLONG(lit,i)) {
5252 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5255 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5258 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5261 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5262 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5267 switch( BYTEofLONG(lit,i)) {
5269 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5273 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5277 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5280 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5282 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5291 /*-----------------------------------------------------------------*/
5292 /* gencjneshort - compare and jump if not equal */
5293 /*-----------------------------------------------------------------*/
5294 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5296 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5298 int res_offset = 0; /* the result may be a different size then left or right */
5299 int res_size = AOP_SIZE(result);
5301 symbol *lbl, *lbl_done;
5303 unsigned long lit = 0L;
5304 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5306 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5307 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5309 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5310 resolveIfx(&rIfx,ifx);
5311 lbl = newiTempLabel(NULL);
5312 lbl_done = newiTempLabel(NULL);
5315 /* if the left side is a literal or
5316 if the right is in a pointer register and left
5318 if ((AOP_TYPE(left) == AOP_LIT) ||
5319 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5324 if(AOP_TYPE(right) == AOP_LIT)
5325 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5327 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5328 preserve_result = 1;
5330 if(result && !preserve_result)
5333 for(i = 0; i < AOP_SIZE(result); i++)
5334 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5338 /* if the right side is a literal then anything goes */
5339 if (AOP_TYPE(right) == AOP_LIT &&
5340 AOP_TYPE(left) != AOP_DIR ) {
5343 genc16bit2lit(left, lit, 0);
5345 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5348 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5351 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5352 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5354 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5358 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5360 if(res_offset < res_size-1)
5368 /* if the right side is in a register or in direct space or
5369 if the left is a pointer register & right is not */
5370 else if (AOP_TYPE(right) == AOP_REG ||
5371 AOP_TYPE(right) == AOP_DIR ||
5372 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5373 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5374 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5375 int lbl_key = lbl->key;
5378 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5379 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5381 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5382 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5383 __FUNCTION__,__LINE__);
5387 /* switch(size) { */
5389 /* genc16bit2lit(left, lit, 0); */
5391 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5396 if((AOP_TYPE(left) == AOP_DIR) &&
5397 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5399 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5400 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5402 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5404 switch (lit & 0xff) {
5406 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5409 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5410 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5411 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5415 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5416 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5417 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5418 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5422 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5423 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5428 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5431 if(AOP_TYPE(result) == AOP_CRY) {
5432 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5437 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5439 /* fix me. probably need to check result size too */
5440 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5445 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5446 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5453 if(res_offset < res_size-1)
5458 } else if(AOP_TYPE(right) == AOP_REG &&
5459 AOP_TYPE(left) != AOP_DIR){
5462 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5463 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5464 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5469 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5471 if(res_offset < res_size-1)
5476 /* right is a pointer reg need both a & b */
5478 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5480 pic16_emitcode("mov","b,%s",l);
5481 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5482 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5487 if(result && preserve_result)
5490 for(i = 0; i < AOP_SIZE(result); i++)
5491 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5494 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
5496 if(result && preserve_result)
5497 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
5500 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5502 pic16_emitpLabel(lbl->key);
5504 if(result && preserve_result)
5507 for(i = 0; i < AOP_SIZE(result); i++)
5508 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5510 pic16_emitpLabel(lbl_done->key);
5513 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5521 /*-----------------------------------------------------------------*/
5522 /* gencjne - compare and jump if not equal */
5523 /*-----------------------------------------------------------------*/
5524 static void gencjne(operand *left, operand *right, iCode *ifx)
5526 symbol *tlbl = newiTempLabel(NULL);
5528 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5529 gencjneshort(left, right, lbl);
5531 pic16_emitcode("mov","a,%s",one);
5532 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5533 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5534 pic16_emitcode("clr","a");
5535 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5537 pic16_emitpLabel(lbl->key);
5538 pic16_emitpLabel(tlbl->key);
5544 /*-----------------------------------------------------------------*/
5545 /* is_LitOp - check if operand has to be treated as literal */
5546 /*-----------------------------------------------------------------*/
5547 static bool is_LitOp(operand *op)
5549 return (AOP_TYPE(op) == AOP_LIT)
5550 || ( (AOP_TYPE(op) == AOP_PCODE)
5551 && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
5552 || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) ));
5556 /*-----------------------------------------------------------------*/
5557 /* genCmpEq - generates code for equal to */
5558 /*-----------------------------------------------------------------*/
5559 static void genCmpEq (iCode *ic, iCode *ifx)
5561 operand *left, *right, *result;
5562 symbol *falselbl = newiTempLabel(NULL);
5563 symbol *donelbl = newiTempLabel(NULL);
5565 int preserve_result = 0;
5566 int generate_result = 0;
5569 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5570 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5571 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5573 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5574 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5576 if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
5578 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5579 fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
5583 if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
5585 operand *tmp = right ;
5590 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5591 preserve_result = 1;
5593 if(result && AOP_SIZE(result))
5594 generate_result = 1;
5596 if(generate_result && !preserve_result)
5598 for(i = 0; i < AOP_SIZE(result); i++)
5599 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5602 for(i=0; i < AOP_SIZE(left); i++)
5604 if(AOP_TYPE(left) != AOP_ACC)
5607 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
5609 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
5612 pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
5614 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
5616 pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
5621 if(generate_result && preserve_result)
5623 for(i = 0; i < AOP_SIZE(result); i++)
5624 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5628 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
5630 if(generate_result && preserve_result)
5631 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5633 if(ifx && IC_TRUE(ifx))
5634 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5636 if(ifx && IC_FALSE(ifx))
5637 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
5639 pic16_emitpLabel(falselbl->key);
5643 if(ifx && IC_FALSE(ifx))
5644 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5646 if(generate_result && preserve_result)
5648 for(i = 0; i < AOP_SIZE(result); i++)
5649 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5652 pic16_emitpLabel(donelbl->key);
5658 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5659 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5660 pic16_freeAsmop(result,NULL,ic,TRUE);
5666 // old version kept for reference
5668 /*-----------------------------------------------------------------*/
5669 /* genCmpEq - generates code for equal to */
5670 /*-----------------------------------------------------------------*/
5671 static void genCmpEq (iCode *ic, iCode *ifx)
5673 operand *left, *right, *result;
5674 unsigned long lit = 0L;
5676 symbol *falselbl = newiTempLabel(NULL);
5679 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5682 DEBUGpic16_emitcode ("; ifx is non-null","");
5684 DEBUGpic16_emitcode ("; ifx is null","");
5686 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5687 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5688 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5690 size = max(AOP_SIZE(left),AOP_SIZE(right));
5692 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5694 /* if literal, literal on the right or
5695 if the right is in a pointer register and left
5697 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5698 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5699 operand *tmp = right ;
5705 if(ifx && !AOP_SIZE(result)){
5707 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5708 /* if they are both bit variables */
5709 if (AOP_TYPE(left) == AOP_CRY &&
5710 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5711 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5712 if(AOP_TYPE(right) == AOP_LIT){
5713 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5715 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5716 pic16_emitcode("cpl","c");
5717 } else if(lit == 1L) {
5718 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5720 pic16_emitcode("clr","c");
5722 /* AOP_TYPE(right) == AOP_CRY */
5724 symbol *lbl = newiTempLabel(NULL);
5725 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5726 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5727 pic16_emitcode("cpl","c");
5728 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5730 /* if true label then we jump if condition
5732 tlbl = newiTempLabel(NULL);
5733 if ( IC_TRUE(ifx) ) {
5734 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5735 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5737 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5738 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5740 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5743 /* left and right are both bit variables, result is carry */
5746 resolveIfx(&rIfx,ifx);
5748 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5749 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5750 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5751 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5756 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5758 /* They're not both bit variables. Is the right a literal? */
5759 if(AOP_TYPE(right) == AOP_LIT) {
5760 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5765 switch(lit & 0xff) {
5767 if ( IC_TRUE(ifx) ) {
5768 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5770 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5772 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5773 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5777 if ( IC_TRUE(ifx) ) {
5778 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5780 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5782 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5783 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5787 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5789 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5794 /* end of size == 1 */
5798 genc16bit2lit(left,lit,offset);
5801 /* end of size == 2 */
5806 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5807 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5808 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5809 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5812 /* search for patterns that can be optimized */
5814 genc16bit2lit(left,lit,0);
5818 emitSKPZ; // if hi word unequal
5820 emitSKPNZ; // if hi word equal
5822 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5823 genc16bit2lit(left,lit,2);
5826 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5827 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5831 pic16_emitpLabel(falselbl->key);
5840 } else if(AOP_TYPE(right) == AOP_CRY ) {
5841 /* we know the left is not a bit, but that the right is */
5842 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5843 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5844 pic16_popGet(AOP(right),offset));
5845 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5847 /* if the two are equal, then W will be 0 and the Z bit is set
5848 * we could test Z now, or go ahead and check the high order bytes if
5849 * the variable we're comparing is larger than a byte. */
5852 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5854 if ( IC_TRUE(ifx) ) {
5856 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5857 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5860 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5861 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5865 /* They're both variables that are larger than bits */
5868 tlbl = newiTempLabel(NULL);
5871 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5872 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5874 if ( IC_TRUE(ifx) ) {
5878 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5880 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5881 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5885 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5888 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5889 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5894 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5896 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5897 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5901 if(s>1 && IC_TRUE(ifx)) {
5902 pic16_emitpLabel(tlbl->key);
5903 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5907 /* mark the icode as generated */
5912 /* if they are both bit variables */
5913 if (AOP_TYPE(left) == AOP_CRY &&
5914 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5915 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5916 if(AOP_TYPE(right) == AOP_LIT){
5917 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5919 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5920 pic16_emitcode("cpl","c");
5921 } else if(lit == 1L) {
5922 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5924 pic16_emitcode("clr","c");
5926 /* AOP_TYPE(right) == AOP_CRY */
5928 symbol *lbl = newiTempLabel(NULL);
5929 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5930 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5931 pic16_emitcode("cpl","c");
5932 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5935 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5936 pic16_outBitC(result);
5940 genIfxJump (ifx,"c");
5943 /* if the result is used in an arithmetic operation
5944 then put the result in place */
5945 pic16_outBitC(result);
5948 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5949 gencjne(left,right,result,ifx);
5952 gencjne(left,right,newiTempLabel(NULL));
5954 if(IC_TRUE(ifx)->key)
5955 gencjne(left,right,IC_TRUE(ifx)->key);
5957 gencjne(left,right,IC_FALSE(ifx)->key);
5961 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5962 pic16_aopPut(AOP(result),"a",0);
5967 genIfxJump (ifx,"a");
5971 /* if the result is used in an arithmetic operation
5972 then put the result in place */
5974 if (AOP_TYPE(result) != AOP_CRY)
5975 pic16_outAcc(result);
5977 /* leave the result in acc */
5981 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5982 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5983 pic16_freeAsmop(result,NULL,ic,TRUE);
5987 /*-----------------------------------------------------------------*/
5988 /* ifxForOp - returns the icode containing the ifx for operand */
5989 /*-----------------------------------------------------------------*/
5990 static iCode *ifxForOp ( operand *op, iCode *ic )
5992 /* if true symbol then needs to be assigned */
5993 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5994 if (IS_TRUE_SYMOP(op))
5997 /* if this has register type condition and
5998 the next instruction is ifx with the same operand
5999 and live to of the operand is upto the ifx only then */
6001 ic->next->op == IFX &&
6002 IC_COND(ic->next)->key == op->key &&
6003 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6007 ic->next->op == IFX &&
6008 IC_COND(ic->next)->key == op->key) {
6009 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6013 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
6015 ic->next->op == IFX)
6016 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
6019 ic->next->op == IFX &&
6020 IC_COND(ic->next)->key == op->key) {
6021 DEBUGpic16_emitcode ("; "," key is okay");
6022 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
6023 OP_SYMBOL(op)->liveTo,
6028 /* the code below is completely untested
6029 * it just allows ulong2fs.c compile -- VR */
6032 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
6033 __FILE__, __FUNCTION__, __LINE__);
6035 /* if this has register type condition and
6036 the next instruction is ifx with the same operand
6037 and live to of the operand is upto the ifx only then */
6039 ic->next->op == IFX &&
6040 IC_COND(ic->next)->key == op->key &&
6041 OP_SYMBOL(op)->liveTo <= ic->next->seq )
6045 ic->next->op == IFX &&
6046 IC_COND(ic->next)->key == op->key) {
6047 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
6051 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
6052 __FILE__, __FUNCTION__, __LINE__);
6054 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
6058 /*-----------------------------------------------------------------*/
6059 /* genAndOp - for && operation */
6060 /*-----------------------------------------------------------------*/
6061 static void genAndOp (iCode *ic)
6063 operand *left,*right, *result;
6066 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6067 /* note here that && operations that are in an
6068 if statement are taken away by backPatchLabels
6069 only those used in arthmetic operations remain */
6070 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6071 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6072 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6074 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6076 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
6077 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
6078 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
6080 /* if both are bit variables */
6081 /* if (AOP_TYPE(left) == AOP_CRY && */
6082 /* AOP_TYPE(right) == AOP_CRY ) { */
6083 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
6084 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
6085 /* pic16_outBitC(result); */
6087 /* tlbl = newiTempLabel(NULL); */
6088 /* pic16_toBoolean(left); */
6089 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
6090 /* pic16_toBoolean(right); */
6091 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
6092 /* pic16_outBitAcc(result); */
6095 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6096 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6097 pic16_freeAsmop(result,NULL,ic,TRUE);
6101 /*-----------------------------------------------------------------*/
6102 /* genOrOp - for || operation */
6103 /*-----------------------------------------------------------------*/
6106 modified this code, but it doesn't appear to ever get called
6109 static void genOrOp (iCode *ic)
6111 operand *left,*right, *result;
6114 /* note here that || operations that are in an
6115 if statement are taken away by backPatchLabels
6116 only those used in arthmetic operations remain */
6117 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6118 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
6119 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
6120 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
6122 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6124 /* if both are bit variables */
6125 if (AOP_TYPE(left) == AOP_CRY &&
6126 AOP_TYPE(right) == AOP_CRY ) {
6127 pic16_emitcode("clrc","");
6128 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6129 AOP(left)->aopu.aop_dir,
6130 AOP(left)->aopu.aop_dir);
6131 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6132 AOP(right)->aopu.aop_dir,
6133 AOP(right)->aopu.aop_dir);
6134 pic16_emitcode("setc","");
6137 tlbl = newiTempLabel(NULL);
6138 pic16_toBoolean(left);
6140 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
6141 pic16_toBoolean(right);
6142 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
6144 pic16_outBitAcc(result);
6147 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6148 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6149 pic16_freeAsmop(result,NULL,ic,TRUE);
6152 /*-----------------------------------------------------------------*/
6153 /* isLiteralBit - test if lit == 2^n */
6154 /*-----------------------------------------------------------------*/
6155 static int isLiteralBit(unsigned long lit)
6157 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6158 0x100L,0x200L,0x400L,0x800L,
6159 0x1000L,0x2000L,0x4000L,0x8000L,
6160 0x10000L,0x20000L,0x40000L,0x80000L,
6161 0x100000L,0x200000L,0x400000L,0x800000L,
6162 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6163 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6167 for(idx = 0; idx < 32; idx++)
6173 /*-----------------------------------------------------------------*/
6174 /* continueIfTrue - */
6175 /*-----------------------------------------------------------------*/
6176 static void continueIfTrue (iCode *ic)
6178 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6180 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6184 /*-----------------------------------------------------------------*/
6186 /*-----------------------------------------------------------------*/
6187 static void jumpIfTrue (iCode *ic)
6189 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6191 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6195 /*-----------------------------------------------------------------*/
6196 /* jmpTrueOrFalse - */
6197 /*-----------------------------------------------------------------*/
6198 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6200 // ugly but optimized by peephole
6201 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6203 symbol *nlbl = newiTempLabel(NULL);
6204 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6205 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6206 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6207 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6210 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6211 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6216 /*-----------------------------------------------------------------*/
6217 /* genAnd - code for and */
6218 /*-----------------------------------------------------------------*/
6219 static void genAnd (iCode *ic, iCode *ifx)
6221 operand *left, *right, *result;
6223 unsigned long lit = 0L;
6228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6229 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6230 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6231 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6233 resolveIfx(&rIfx,ifx);
6235 /* if left is a literal & right is not then exchange them */
6236 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6237 AOP_NEEDSACC(left)) {
6238 operand *tmp = right ;
6243 /* if result = right then exchange them */
6244 if(pic16_sameRegs(AOP(result),AOP(right))){
6245 operand *tmp = right ;
6250 /* if right is bit then exchange them */
6251 if (AOP_TYPE(right) == AOP_CRY &&
6252 AOP_TYPE(left) != AOP_CRY){
6253 operand *tmp = right ;
6257 if(AOP_TYPE(right) == AOP_LIT)
6258 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6260 size = AOP_SIZE(result);
6262 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6265 // result = bit & yy;
6266 if (AOP_TYPE(left) == AOP_CRY){
6267 // c = bit & literal;
6268 if(AOP_TYPE(right) == AOP_LIT){
6270 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6273 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6276 if(size && (AOP_TYPE(result) == AOP_CRY)){
6277 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6280 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6284 pic16_emitcode("clr","c");
6287 if (AOP_TYPE(right) == AOP_CRY){
6289 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6290 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6293 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6295 pic16_emitcode("rrc","a");
6296 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6302 pic16_outBitC(result);
6304 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6305 genIfxJump(ifx, "c");
6309 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6310 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6311 if((AOP_TYPE(right) == AOP_LIT) &&
6312 (AOP_TYPE(result) == AOP_CRY) &&
6313 (AOP_TYPE(left) != AOP_CRY)){
6314 int posbit = isLiteralBit(lit);
6318 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6321 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6327 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6328 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6330 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6331 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6334 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6335 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6336 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6343 symbol *tlbl = newiTempLabel(NULL);
6344 int sizel = AOP_SIZE(left);
6346 pic16_emitcode("setb","c");
6348 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
6349 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6351 if((posbit = isLiteralBit(bytelit)) != 0)
6352 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
6354 if(bytelit != 0x0FFL)
6355 pic16_emitcode("anl","a,%s",
6356 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
6357 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6362 // bit = left & literal
6364 pic16_emitcode("clr","c");
6365 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6367 // if(left & literal)
6370 jmpTrueOrFalse(ifx, tlbl);
6374 pic16_outBitC(result);
6378 /* if left is same as result */
6379 if(pic16_sameRegs(AOP(result),AOP(left))){
6381 for(;size--; offset++,lit>>=8) {
6382 if(AOP_TYPE(right) == AOP_LIT){
6383 switch(lit & 0xff) {
6385 /* and'ing with 0 has clears the result */
6386 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6387 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6390 /* and'ing with 0xff is a nop when the result and left are the same */
6395 int p = my_powof2( (~lit) & 0xff );
6397 /* only one bit is set in the literal, so use a bcf instruction */
6398 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
6399 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6402 pic16_emitcode("movlw","0x%x", (lit & 0xff));
6403 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6404 if(know_W != (lit&0xff))
6405 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6407 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6412 if (AOP_TYPE(left) == AOP_ACC) {
6413 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6415 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6416 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6423 // left & result in different registers
6424 if(AOP_TYPE(result) == AOP_CRY){
6426 // if(size), result in bit
6427 // if(!size && ifx), conditional oper: if(left & right)
6428 symbol *tlbl = newiTempLabel(NULL);
6429 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
6431 pic16_emitcode("setb","c");
6433 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6434 pic16_emitcode("anl","a,%s",
6435 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6436 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6441 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6442 pic16_outBitC(result);
6444 jmpTrueOrFalse(ifx, tlbl);
6446 for(;(size--);offset++) {
6448 // result = left & right
6449 if(AOP_TYPE(right) == AOP_LIT){
6450 int t = (lit >> (offset*8)) & 0x0FFL;
6453 pic16_emitcode("clrf","%s",
6454 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6455 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6458 pic16_emitcode("movf","%s,w",
6459 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6460 pic16_emitcode("movwf","%s",
6461 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6462 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6463 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6466 pic16_emitcode("movlw","0x%x",t);
6467 pic16_emitcode("andwf","%s,w",
6468 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6469 pic16_emitcode("movwf","%s",
6470 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6472 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6473 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6474 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6479 if (AOP_TYPE(left) == AOP_ACC) {
6480 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6481 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6483 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6484 pic16_emitcode("andwf","%s,w",
6485 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6486 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6487 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6489 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6490 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6496 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6497 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6498 pic16_freeAsmop(result,NULL,ic,TRUE);
6501 /*-----------------------------------------------------------------*/
6502 /* genOr - code for or */
6503 /*-----------------------------------------------------------------*/
6504 static void genOr (iCode *ic, iCode *ifx)
6506 operand *left, *right, *result;
6508 unsigned long lit = 0L;
6510 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6512 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6513 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6514 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6516 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6518 /* if left is a literal & right is not then exchange them */
6519 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6520 AOP_NEEDSACC(left)) {
6521 operand *tmp = right ;
6526 /* if result = right then exchange them */
6527 if(pic16_sameRegs(AOP(result),AOP(right))){
6528 operand *tmp = right ;
6533 /* if right is bit then exchange them */
6534 if (AOP_TYPE(right) == AOP_CRY &&
6535 AOP_TYPE(left) != AOP_CRY){
6536 operand *tmp = right ;
6541 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6543 if(AOP_TYPE(right) == AOP_LIT)
6544 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6546 size = AOP_SIZE(result);
6550 if (AOP_TYPE(left) == AOP_CRY){
6551 if(AOP_TYPE(right) == AOP_LIT){
6552 // c = bit & literal;
6554 // lit != 0 => result = 1
6555 if(AOP_TYPE(result) == AOP_CRY){
6557 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6558 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6559 // AOP(result)->aopu.aop_dir,
6560 // AOP(result)->aopu.aop_dir);
6562 continueIfTrue(ifx);
6566 // lit == 0 => result = left
6567 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6569 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6572 if (AOP_TYPE(right) == AOP_CRY){
6573 if(pic16_sameRegs(AOP(result),AOP(left))){
6575 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6576 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6577 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6579 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6580 AOP(result)->aopu.aop_dir,
6581 AOP(result)->aopu.aop_dir);
6582 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6583 AOP(right)->aopu.aop_dir,
6584 AOP(right)->aopu.aop_dir);
6585 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6586 AOP(result)->aopu.aop_dir,
6587 AOP(result)->aopu.aop_dir);
6589 if( AOP_TYPE(result) == AOP_ACC) {
6590 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6591 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6592 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6593 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6597 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6598 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6599 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6600 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6602 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6603 AOP(result)->aopu.aop_dir,
6604 AOP(result)->aopu.aop_dir);
6605 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6606 AOP(right)->aopu.aop_dir,
6607 AOP(right)->aopu.aop_dir);
6608 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6609 AOP(left)->aopu.aop_dir,
6610 AOP(left)->aopu.aop_dir);
6611 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6612 AOP(result)->aopu.aop_dir,
6613 AOP(result)->aopu.aop_dir);
6618 symbol *tlbl = newiTempLabel(NULL);
6619 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6622 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6623 if( AOP_TYPE(right) == AOP_ACC) {
6624 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6626 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6627 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6632 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6633 pic16_emitcode(";XXX setb","c");
6634 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6635 AOP(left)->aopu.aop_dir,tlbl->key+100);
6636 pic16_toBoolean(right);
6637 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6638 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6639 jmpTrueOrFalse(ifx, tlbl);
6643 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6650 pic16_outBitC(result);
6652 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6653 genIfxJump(ifx, "c");
6657 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6658 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6659 if((AOP_TYPE(right) == AOP_LIT) &&
6660 (AOP_TYPE(result) == AOP_CRY) &&
6661 (AOP_TYPE(left) != AOP_CRY)){
6663 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6666 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6668 continueIfTrue(ifx);
6671 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6672 // lit = 0, result = boolean(left)
6674 pic16_emitcode(";XXX setb","c");
6675 pic16_toBoolean(right);
6677 symbol *tlbl = newiTempLabel(NULL);
6678 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6680 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6682 genIfxJump (ifx,"a");
6686 pic16_outBitC(result);
6690 /* if left is same as result */
6691 if(pic16_sameRegs(AOP(result),AOP(left))){
6693 for(;size--; offset++,lit>>=8) {
6694 if(AOP_TYPE(right) == AOP_LIT){
6695 if((lit & 0xff) == 0)
6696 /* or'ing with 0 has no effect */
6699 int p = my_powof2(lit & 0xff);
6701 /* only one bit is set in the literal, so use a bsf instruction */
6702 pic16_emitpcode(POC_BSF,
6703 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6705 if(know_W != (lit & 0xff))
6706 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6707 know_W = lit & 0xff;
6708 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6713 if (AOP_TYPE(left) == AOP_ACC) {
6714 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6715 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6717 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6718 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6720 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6721 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6727 // left & result in different registers
6728 if(AOP_TYPE(result) == AOP_CRY){
6730 // if(size), result in bit
6731 // if(!size && ifx), conditional oper: if(left | right)
6732 symbol *tlbl = newiTempLabel(NULL);
6733 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6734 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6738 pic16_emitcode(";XXX setb","c");
6740 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6741 pic16_emitcode(";XXX orl","a,%s",
6742 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6743 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6748 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6749 pic16_outBitC(result);
6751 jmpTrueOrFalse(ifx, tlbl);
6752 } else for(;(size--);offset++){
6754 // result = left & right
6755 if(AOP_TYPE(right) == AOP_LIT){
6756 int t = (lit >> (offset*8)) & 0x0FFL;
6759 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6760 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6762 pic16_emitcode("movf","%s,w",
6763 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6764 pic16_emitcode("movwf","%s",
6765 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6768 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6769 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6770 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6772 pic16_emitcode("movlw","0x%x",t);
6773 pic16_emitcode("iorwf","%s,w",
6774 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6775 pic16_emitcode("movwf","%s",
6776 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6782 // faster than result <- left, anl result,right
6783 // and better if result is SFR
6784 if (AOP_TYPE(left) == AOP_ACC) {
6785 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6786 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6788 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6789 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6791 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6792 pic16_emitcode("iorwf","%s,w",
6793 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6795 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6796 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6801 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6802 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6803 pic16_freeAsmop(result,NULL,ic,TRUE);
6806 /*-----------------------------------------------------------------*/
6807 /* genXor - code for xclusive or */
6808 /*-----------------------------------------------------------------*/
6809 static void genXor (iCode *ic, iCode *ifx)
6811 operand *left, *right, *result;
6813 unsigned long lit = 0L;
6815 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6817 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6818 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6819 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6821 /* if left is a literal & right is not ||
6822 if left needs acc & right does not */
6823 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6824 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6825 operand *tmp = right ;
6830 /* if result = right then exchange them */
6831 if(pic16_sameRegs(AOP(result),AOP(right))){
6832 operand *tmp = right ;
6837 /* if right is bit then exchange them */
6838 if (AOP_TYPE(right) == AOP_CRY &&
6839 AOP_TYPE(left) != AOP_CRY){
6840 operand *tmp = right ;
6844 if(AOP_TYPE(right) == AOP_LIT)
6845 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6847 size = AOP_SIZE(result);
6851 if (AOP_TYPE(left) == AOP_CRY){
6852 if(AOP_TYPE(right) == AOP_LIT){
6853 // c = bit & literal;
6855 // lit>>1 != 0 => result = 1
6856 if(AOP_TYPE(result) == AOP_CRY){
6858 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6859 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6861 continueIfTrue(ifx);
6864 pic16_emitcode("setb","c");
6868 // lit == 0, result = left
6869 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6871 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6873 // lit == 1, result = not(left)
6874 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6875 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6876 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6877 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6880 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6881 pic16_emitcode("cpl","c");
6888 symbol *tlbl = newiTempLabel(NULL);
6889 if (AOP_TYPE(right) == AOP_CRY){
6891 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6894 int sizer = AOP_SIZE(right);
6896 // if val>>1 != 0, result = 1
6897 pic16_emitcode("setb","c");
6899 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6901 // test the msb of the lsb
6902 pic16_emitcode("anl","a,#0xfe");
6903 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6907 pic16_emitcode("rrc","a");
6909 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6910 pic16_emitcode("cpl","c");
6911 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6916 pic16_outBitC(result);
6918 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6919 genIfxJump(ifx, "c");
6923 if(pic16_sameRegs(AOP(result),AOP(left))){
6924 /* if left is same as result */
6925 for(;size--; offset++) {
6926 if(AOP_TYPE(right) == AOP_LIT){
6927 int t = (lit >> (offset*8)) & 0x0FFL;
6931 if (IS_AOP_PREG(left)) {
6932 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6933 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6934 pic16_aopPut(AOP(result),"a",offset);
6936 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6937 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6938 pic16_emitcode("xrl","%s,%s",
6939 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6940 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6943 if (AOP_TYPE(left) == AOP_ACC)
6944 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6946 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6947 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6949 if (IS_AOP_PREG(left)) {
6950 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6951 pic16_aopPut(AOP(result),"a",offset);
6953 pic16_emitcode("xrl","%s,a",
6954 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6960 // left & result in different registers
6961 if(AOP_TYPE(result) == AOP_CRY){
6963 // if(size), result in bit
6964 // if(!size && ifx), conditional oper: if(left ^ right)
6965 symbol *tlbl = newiTempLabel(NULL);
6966 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6968 pic16_emitcode("setb","c");
6970 if((AOP_TYPE(right) == AOP_LIT) &&
6971 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6972 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6974 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6975 pic16_emitcode("xrl","a,%s",
6976 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6978 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6983 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6984 pic16_outBitC(result);
6986 jmpTrueOrFalse(ifx, tlbl);
6987 } else for(;(size--);offset++){
6989 // result = left & right
6990 if(AOP_TYPE(right) == AOP_LIT){
6991 int t = (lit >> (offset*8)) & 0x0FFL;
6994 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6995 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6996 pic16_emitcode("movf","%s,w",
6997 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6998 pic16_emitcode("movwf","%s",
6999 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7002 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
7003 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7004 pic16_emitcode("comf","%s,w",
7005 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7006 pic16_emitcode("movwf","%s",
7007 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7010 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
7011 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7012 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7013 pic16_emitcode("movlw","0x%x",t);
7014 pic16_emitcode("xorwf","%s,w",
7015 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7016 pic16_emitcode("movwf","%s",
7017 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7023 // faster than result <- left, anl result,right
7024 // and better if result is SFR
7025 if (AOP_TYPE(left) == AOP_ACC) {
7026 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
7027 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7029 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
7030 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
7031 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
7032 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7034 if ( AOP_TYPE(result) != AOP_ACC){
7035 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
7036 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
7042 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7043 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
7044 pic16_freeAsmop(result,NULL,ic,TRUE);
7047 /*-----------------------------------------------------------------*/
7048 /* genInline - write the inline code out */
7049 /*-----------------------------------------------------------------*/
7050 static void genInline (iCode *ic)
7052 char *buffer, *bp, *bp1;
7054 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7056 _G.inLine += (!options.asmpeep);
7058 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
7059 strcpy(buffer,IC_INLINE(ic));
7061 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
7063 /* emit each line as a code */
7069 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7077 /* print label, use this special format with NULL directive
7078 * to denote that the argument should not be indented with tab */
7079 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
7086 if ((bp1 != bp) && *bp1)
7087 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
7092 _G.inLine -= (!options.asmpeep);
7095 /*-----------------------------------------------------------------*/
7096 /* genRRC - rotate right with carry */
7097 /*-----------------------------------------------------------------*/
7098 static void genRRC (iCode *ic)
7100 operand *left , *result ;
7101 int size, offset = 0, same;
7103 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7105 /* rotate right with carry */
7107 result=IC_RESULT(ic);
7108 pic16_aopOp (left,ic,FALSE);
7109 pic16_aopOp (result,ic,FALSE);
7111 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7113 same = pic16_sameRegs(AOP(result),AOP(left));
7115 size = AOP_SIZE(result);
7117 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
7119 /* get the lsb and put it into the carry */
7120 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
7127 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
7129 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
7130 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7136 pic16_freeAsmop(left,NULL,ic,TRUE);
7137 pic16_freeAsmop(result,NULL,ic,TRUE);
7140 /*-----------------------------------------------------------------*/
7141 /* genRLC - generate code for rotate left with carry */
7142 /*-----------------------------------------------------------------*/
7143 static void genRLC (iCode *ic)
7145 operand *left , *result ;
7146 int size, offset = 0;
7149 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7150 /* rotate right with carry */
7152 result=IC_RESULT(ic);
7153 pic16_aopOp (left,ic,FALSE);
7154 pic16_aopOp (result,ic,FALSE);
7156 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7158 same = pic16_sameRegs(AOP(result),AOP(left));
7160 /* move it to the result */
7161 size = AOP_SIZE(result);
7163 /* get the msb and put it into the carry */
7164 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7171 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7173 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7174 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7181 pic16_freeAsmop(left,NULL,ic,TRUE);
7182 pic16_freeAsmop(result,NULL,ic,TRUE);
7186 /* gpasm can get the highest order bit with HIGH/UPPER
7187 * so the following probably is not needed -- VR */
7189 /*-----------------------------------------------------------------*/
7190 /* genGetHbit - generates code get highest order bit */
7191 /*-----------------------------------------------------------------*/
7192 static void genGetHbit (iCode *ic)
7194 operand *left, *result;
7196 result=IC_RESULT(ic);
7197 pic16_aopOp (left,ic,FALSE);
7198 pic16_aopOp (result,ic,FALSE);
7200 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7201 /* get the highest order byte into a */
7202 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7203 if(AOP_TYPE(result) == AOP_CRY){
7204 pic16_emitcode("rlc","a");
7205 pic16_outBitC(result);
7208 pic16_emitcode("rl","a");
7209 pic16_emitcode("anl","a,#0x01");
7210 pic16_outAcc(result);
7214 pic16_freeAsmop(left,NULL,ic,TRUE);
7215 pic16_freeAsmop(result,NULL,ic,TRUE);
7219 /*-----------------------------------------------------------------*/
7220 /* AccRol - rotate left accumulator by known count */
7221 /*-----------------------------------------------------------------*/
7222 static void AccRol (int shCount)
7224 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7225 shCount &= 0x0007; // shCount : 0..7
7230 pic16_emitcode("rl","a");
7233 pic16_emitcode("rl","a");
7234 pic16_emitcode("rl","a");
7237 pic16_emitcode("swap","a");
7238 pic16_emitcode("rr","a");
7241 pic16_emitcode("swap","a");
7244 pic16_emitcode("swap","a");
7245 pic16_emitcode("rl","a");
7248 pic16_emitcode("rr","a");
7249 pic16_emitcode("rr","a");
7252 pic16_emitcode("rr","a");
7258 /*-----------------------------------------------------------------*/
7259 /* AccLsh - left shift accumulator by known count */
7260 /*-----------------------------------------------------------------*/
7261 static void AccLsh (int shCount)
7263 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7269 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7272 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7273 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7276 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7277 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7280 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7283 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7284 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7287 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7288 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7291 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7295 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7298 /*-----------------------------------------------------------------*/
7299 /* AccRsh - right shift accumulator by known count */
7300 /*-----------------------------------------------------------------*/
7301 static void AccRsh (int shCount, int andmask)
7303 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7308 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7309 // andmask = 0; /* no need */
7312 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7313 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7314 // andmask = 0; /* no need */
7317 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7318 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7321 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7324 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7325 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7328 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7329 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7332 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7337 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
7339 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
7343 /*-----------------------------------------------------------------*/
7344 /* AccSRsh - signed right shift accumulator by known count */
7345 /*-----------------------------------------------------------------*/
7346 static void AccSRsh (int shCount)
7349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7352 pic16_emitcode("mov","c,acc.7");
7353 pic16_emitcode("rrc","a");
7354 } else if(shCount == 2){
7355 pic16_emitcode("mov","c,acc.7");
7356 pic16_emitcode("rrc","a");
7357 pic16_emitcode("mov","c,acc.7");
7358 pic16_emitcode("rrc","a");
7360 tlbl = newiTempLabel(NULL);
7361 /* rotate right accumulator */
7362 AccRol(8 - shCount);
7363 /* and kill the higher order bits */
7364 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
7365 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
7366 pic16_emitcode("orl","a,#0x%02x",
7367 (unsigned char)~SRMask[shCount]);
7368 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7373 /*-----------------------------------------------------------------*/
7374 /* shiftR1Left2Result - shift right one byte from left to result */
7375 /*-----------------------------------------------------------------*/
7376 static void shiftR1Left2ResultSigned (operand *left, int offl,
7377 operand *result, int offr,
7382 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7384 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7388 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7390 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7392 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7393 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7399 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7401 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7403 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7404 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7406 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7407 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7413 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7415 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7416 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7419 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7420 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7421 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7423 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7424 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
7426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7430 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7431 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7432 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7433 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
7434 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7438 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7440 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7441 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7443 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7444 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
7445 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7446 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
7447 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7452 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7453 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7454 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
7455 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7456 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
7457 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7459 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7460 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7461 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7462 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7463 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
7469 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7470 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7471 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7472 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7474 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7475 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7476 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7484 /*-----------------------------------------------------------------*/
7485 /* shiftR1Left2Result - shift right one byte from left to result */
7486 /*-----------------------------------------------------------------*/
7487 static void shiftR1Left2Result (operand *left, int offl,
7488 operand *result, int offr,
7489 int shCount, int sign)
7493 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7495 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7497 /* Copy the msb into the carry if signed. */
7499 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
7509 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7511 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7512 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7518 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7520 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7521 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7524 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7529 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7531 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7532 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7535 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7536 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7537 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7538 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7542 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7543 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7544 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7548 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7549 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7550 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7552 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7557 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7558 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7559 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7560 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7561 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7566 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7567 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7568 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7577 /*-----------------------------------------------------------------*/
7578 /* shiftL1Left2Result - shift left one byte from left to result */
7579 /*-----------------------------------------------------------------*/
7580 static void shiftL1Left2Result (operand *left, int offl,
7581 operand *result, int offr, int shCount)
7586 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7588 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7589 DEBUGpic16_emitcode ("; ***","same = %d",same);
7590 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7592 /* shift left accumulator */
7593 //AccLsh(shCount); // don't comment out just yet...
7594 // pic16_aopPut(AOP(result),"a",offr);
7598 /* Shift left 1 bit position */
7599 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7601 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7603 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7604 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7608 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7609 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7610 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7611 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7614 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7615 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7616 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7617 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7618 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7621 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7622 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7623 pic16_emitpcode(POC_MOVWF,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));
7629 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7632 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7633 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7634 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7635 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7636 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7639 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7640 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7641 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7645 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7650 /*-----------------------------------------------------------------*/
7651 /* movLeft2Result - move byte from left to result */
7652 /*-----------------------------------------------------------------*/
7653 static void movLeft2Result (operand *left, int offl,
7654 operand *result, int offr)
7657 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7658 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7659 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7661 if (*l == '@' && (IS_AOP_PREG(result))) {
7662 pic16_emitcode("mov","a,%s",l);
7663 pic16_aopPut(AOP(result),"a",offr);
7665 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7666 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7671 /*-----------------------------------------------------------------*/
7672 /* shiftL2Left2Result - shift left two bytes from left to result */
7673 /*-----------------------------------------------------------------*/
7674 static void shiftL2Left2Result (operand *left, int offl,
7675 operand *result, int offr, int shCount)
7677 int same = pic16_sameRegs(AOP(result), AOP(left));
7680 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7682 if (same && (offl != offr)) { // shift bytes
7685 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7686 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7688 } else { // just treat as different later on
7701 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7702 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7703 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7707 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7708 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7714 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7715 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7716 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7717 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7718 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7719 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7720 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7722 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7723 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7727 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7728 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7729 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7730 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7731 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7732 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7733 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7734 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7735 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7736 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7739 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7740 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7741 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7742 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7743 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7753 /* note, use a mov/add for the shift since the mov has a
7754 chance of getting optimized out */
7755 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7756 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7757 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7758 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7759 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7763 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7764 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7770 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7771 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7772 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7773 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7774 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7775 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7776 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7777 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7781 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7782 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7786 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7787 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7788 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7789 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7791 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7792 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7793 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7794 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7795 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7796 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7797 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7798 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7801 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7802 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7803 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7804 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7805 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7810 /*-----------------------------------------------------------------*/
7811 /* shiftR2Left2Result - shift right two bytes from left to result */
7812 /*-----------------------------------------------------------------*/
7813 static void shiftR2Left2Result (operand *left, int offl,
7814 operand *result, int offr,
7815 int shCount, int sign)
7817 int same = pic16_sameRegs(AOP(result), AOP(left));
7819 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7821 if (same && (offl != offr)) { // shift right bytes
7824 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7825 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7827 } else { // just treat as different later on
7839 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7844 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7845 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7847 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7848 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7849 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7850 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7855 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7858 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7859 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7866 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7867 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7868 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7870 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7871 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7872 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7873 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7875 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7876 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7877 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7879 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7880 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7881 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7882 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7883 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7887 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7888 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7892 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7893 pic16_emitpcode(POC_BTFSC,
7894 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7895 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7903 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7904 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7906 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7907 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7908 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7909 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7911 pic16_emitpcode(POC_BTFSC,
7912 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7913 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7915 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7916 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7917 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7918 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7920 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7921 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7922 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7923 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7924 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7925 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7926 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7927 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7929 pic16_emitpcode(POC_BTFSC,
7930 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7931 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7933 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7934 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7941 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7942 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7943 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7944 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7947 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7949 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7954 /*-----------------------------------------------------------------*/
7955 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7956 /*-----------------------------------------------------------------*/
7957 static void shiftLLeftOrResult (operand *left, int offl,
7958 operand *result, int offr, int shCount)
7960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7962 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7963 /* shift left accumulator */
7965 /* or with result */
7966 /* back to result */
7967 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7970 /*-----------------------------------------------------------------*/
7971 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7972 /*-----------------------------------------------------------------*/
7973 static void shiftRLeftOrResult (operand *left, int offl,
7974 operand *result, int offr, int shCount)
7976 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7978 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7979 /* shift right accumulator */
7981 /* or with result */
7982 /* back to result */
7983 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7986 /*-----------------------------------------------------------------*/
7987 /* genlshOne - left shift a one byte quantity by known count */
7988 /*-----------------------------------------------------------------*/
7989 static void genlshOne (operand *result, operand *left, int shCount)
7991 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7992 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7995 /*-----------------------------------------------------------------*/
7996 /* genlshTwo - left shift two bytes by known amount != 0 */
7997 /*-----------------------------------------------------------------*/
7998 static void genlshTwo (operand *result,operand *left, int shCount)
8002 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8003 size = pic16_getDataSize(result);
8005 /* if shCount >= 8 */
8011 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8013 movLeft2Result(left, LSB, result, MSB16);
8015 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8018 /* 1 <= shCount <= 7 */
8021 shiftL1Left2Result(left, LSB, result, LSB, shCount);
8023 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8027 /*-----------------------------------------------------------------*/
8028 /* shiftLLong - shift left one long from left to result */
8029 /* offr = LSB or MSB16 */
8030 /*-----------------------------------------------------------------*/
8031 static void shiftLLong (operand *left, operand *result, int offr )
8033 int size = AOP_SIZE(result);
8034 int same = pic16_sameRegs(AOP(left),AOP(result));
8037 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
8039 if (same && (offr == MSB16)) { //shift one byte
8040 for(i=size-1;i>=MSB16;i--) {
8041 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
8042 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
8045 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
8048 if (size >= LSB+offr ){
8050 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
8052 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
8053 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
8057 if(size >= MSB16+offr){
8059 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
8061 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
8062 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
8066 if(size >= MSB24+offr){
8068 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
8070 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
8071 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
8075 if(size > MSB32+offr){
8077 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
8079 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
8080 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
8084 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8088 /*-----------------------------------------------------------------*/
8089 /* genlshFour - shift four byte by a known amount != 0 */
8090 /*-----------------------------------------------------------------*/
8091 static void genlshFour (operand *result, operand *left, int shCount)
8095 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8096 size = AOP_SIZE(result);
8098 /* if shifting more that 3 bytes */
8099 if (shCount >= 24 ) {
8102 /* lowest order of left goes to the highest
8103 order of the destination */
8104 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
8106 movLeft2Result(left, LSB, result, MSB32);
8108 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8109 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8110 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
8115 /* more than two bytes */
8116 else if ( shCount >= 16 ) {
8117 /* lower order two bytes goes to higher order two bytes */
8119 /* if some more remaining */
8121 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
8123 movLeft2Result(left, MSB16, result, MSB32);
8124 movLeft2Result(left, LSB, result, MSB24);
8126 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8127 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8131 /* if more than 1 byte */
8132 else if ( shCount >= 8 ) {
8133 /* lower order three bytes goes to higher order three bytes */
8137 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8139 movLeft2Result(left, LSB, result, MSB16);
8141 else{ /* size = 4 */
8143 movLeft2Result(left, MSB24, result, MSB32);
8144 movLeft2Result(left, MSB16, result, MSB24);
8145 movLeft2Result(left, LSB, result, MSB16);
8146 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8148 else if(shCount == 1)
8149 shiftLLong(left, result, MSB16);
8151 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8152 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8153 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8154 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8159 /* 1 <= shCount <= 7 */
8160 else if(shCount <= 3)
8162 shiftLLong(left, result, LSB);
8163 while(--shCount >= 1)
8164 shiftLLong(result, result, LSB);
8166 /* 3 <= shCount <= 7, optimize */
8168 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8169 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8170 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8174 /*-----------------------------------------------------------------*/
8175 /* genLeftShiftLiteral - left shifting by known count */
8176 /*-----------------------------------------------------------------*/
8177 static void genLeftShiftLiteral (operand *left,
8182 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8185 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8186 pic16_freeAsmop(right,NULL,ic,TRUE);
8188 pic16_aopOp(left,ic,FALSE);
8189 pic16_aopOp(result,ic,FALSE);
8191 size = getSize(operandType(result));
8194 pic16_emitcode("; shift left ","result %d, left %d",size,
8198 /* I suppose that the left size >= result size */
8201 movLeft2Result(left, size, result, size);
8205 else if(shCount >= (size * 8))
8207 pic16_aopPut(AOP(result),zero,size);
8211 genlshOne (result,left,shCount);
8216 genlshTwo (result,left,shCount);
8220 genlshFour (result,left,shCount);
8224 pic16_freeAsmop(left,NULL,ic,TRUE);
8225 pic16_freeAsmop(result,NULL,ic,TRUE);
8228 /*-----------------------------------------------------------------*
8229 * genMultiAsm - repeat assembly instruction for size of register.
8230 * if endian == 1, then the high byte (i.e base address + size of
8231 * register) is used first else the low byte is used first;
8232 *-----------------------------------------------------------------*/
8233 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8238 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8251 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8256 /*-----------------------------------------------------------------*/
8257 /* genLeftShift - generates code for left shifting */
8258 /*-----------------------------------------------------------------*/
8259 static void genLeftShift (iCode *ic)
8261 operand *left,*right, *result;
8264 symbol *tlbl , *tlbl1;
8267 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8269 right = IC_RIGHT(ic);
8271 result = IC_RESULT(ic);
8273 pic16_aopOp(right,ic,FALSE);
8275 /* if the shift count is known then do it
8276 as efficiently as possible */
8277 if (AOP_TYPE(right) == AOP_LIT) {
8278 genLeftShiftLiteral (left,right,result,ic);
8282 /* shift count is unknown then we have to form
8283 a loop get the loop count in B : Note: we take
8284 only the lower order byte since shifting
8285 more that 32 bits make no sense anyway, ( the
8286 largest size of an object can be only 32 bits ) */
8289 pic16_aopOp(left,ic,FALSE);
8290 pic16_aopOp(result,ic,FALSE);
8292 /* now move the left to the result if they are not the
8294 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8295 AOP_SIZE(result) > 1) {
8297 size = AOP_SIZE(result);
8300 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8301 if (*l == '@' && (IS_AOP_PREG(result))) {
8303 pic16_emitcode("mov","a,%s",l);
8304 pic16_aopPut(AOP(result),"a",offset);
8306 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8307 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8308 //pic16_aopPut(AOP(result),l,offset);
8314 size = AOP_SIZE(result);
8316 /* if it is only one byte then */
8318 if(optimized_for_speed) {
8319 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8320 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8321 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
8322 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8323 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8324 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
8325 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8326 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8327 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8328 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8329 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
8330 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8333 tlbl = newiTempLabel(NULL);
8334 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8335 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8336 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8339 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8340 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8341 pic16_emitpLabel(tlbl->key);
8342 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8343 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8345 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8350 if (pic16_sameRegs(AOP(left),AOP(result))) {
8352 tlbl = newiTempLabel(NULL);
8353 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8354 genMultiAsm(POC_RRCF, result, size,1);
8355 pic16_emitpLabel(tlbl->key);
8356 genMultiAsm(POC_RLCF, result, size,0);
8357 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8359 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8363 //tlbl = newiTempLabel(NULL);
8365 //tlbl1 = newiTempLabel(NULL);
8367 //reAdjustPreg(AOP(result));
8369 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8370 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8371 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8373 //pic16_emitcode("add","a,acc");
8374 //pic16_aopPut(AOP(result),"a",offset++);
8376 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8378 // pic16_emitcode("rlc","a");
8379 // pic16_aopPut(AOP(result),"a",offset++);
8381 //reAdjustPreg(AOP(result));
8383 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8384 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8387 tlbl = newiTempLabel(NULL);
8388 tlbl1= newiTempLabel(NULL);
8390 size = AOP_SIZE(result);
8393 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8395 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8397 /* offset should be 0, 1 or 3 */
8399 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8401 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8403 pic16_emitpcode(POC_MOVWF, pctemp);
8406 pic16_emitpLabel(tlbl->key);
8409 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8411 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8413 pic16_emitpcode(POC_DECFSZ, pctemp);
8414 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8415 pic16_emitpLabel(tlbl1->key);
8417 pic16_popReleaseTempReg(pctemp);
8421 pic16_freeAsmop (right,NULL,ic,TRUE);
8422 pic16_freeAsmop(left,NULL,ic,TRUE);
8423 pic16_freeAsmop(result,NULL,ic,TRUE);
8426 /*-----------------------------------------------------------------*/
8427 /* genrshOne - right shift a one byte quantity by known count */
8428 /*-----------------------------------------------------------------*/
8429 static void genrshOne (operand *result, operand *left,
8430 int shCount, int sign)
8432 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8433 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
8436 /*-----------------------------------------------------------------*/
8437 /* genrshTwo - right shift two bytes by known amount != 0 */
8438 /*-----------------------------------------------------------------*/
8439 static void genrshTwo (operand *result,operand *left,
8440 int shCount, int sign)
8442 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8443 /* if shCount >= 8 */
8447 shiftR1Left2Result(left, MSB16, result, LSB,
8450 movLeft2Result(left, MSB16, result, LSB);
8452 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8455 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
8456 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
8460 /* 1 <= shCount <= 7 */
8462 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
8465 /*-----------------------------------------------------------------*/
8466 /* shiftRLong - shift right one long from left to result */
8467 /* offl = LSB or MSB16 */
8468 /*-----------------------------------------------------------------*/
8469 static void shiftRLong (operand *left, int offl,
8470 operand *result, int sign)
8472 int size = AOP_SIZE(result);
8473 int same = pic16_sameRegs(AOP(left),AOP(result));
8475 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
8477 if (same && (offl == MSB16)) { //shift one byte right
8478 for(i=MSB16;i<size;i++) {
8479 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
8480 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
8485 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
8491 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
8493 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
8494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
8498 /* add sign of "a" */
8499 pic16_addSign(result, MSB32, sign);
8503 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
8505 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
8506 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
8510 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
8512 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
8513 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
8517 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
8520 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
8521 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
8526 /*-----------------------------------------------------------------*/
8527 /* genrshFour - shift four byte by a known amount != 0 */
8528 /*-----------------------------------------------------------------*/
8529 static void genrshFour (operand *result, operand *left,
8530 int shCount, int sign)
8532 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8533 /* if shifting more that 3 bytes */
8534 if(shCount >= 24 ) {
8537 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8539 movLeft2Result(left, MSB32, result, LSB);
8541 pic16_addSign(result, MSB16, sign);
8543 else if(shCount >= 16){
8546 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8548 movLeft2Result(left, MSB24, result, LSB);
8549 movLeft2Result(left, MSB32, result, MSB16);
8551 pic16_addSign(result, MSB24, sign);
8553 else if(shCount >= 8){
8556 shiftRLong(left, MSB16, result, sign);
8557 else if(shCount == 0){
8558 movLeft2Result(left, MSB16, result, LSB);
8559 movLeft2Result(left, MSB24, result, MSB16);
8560 movLeft2Result(left, MSB32, result, MSB24);
8561 pic16_addSign(result, MSB32, sign);
8563 else{ //shcount >= 2
8564 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8565 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8566 /* the last shift is signed */
8567 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8568 pic16_addSign(result, MSB32, sign);
8571 else{ /* 1 <= shCount <= 7 */
8573 shiftRLong(left, LSB, result, sign);
8575 shiftRLong(result, LSB, result, sign);
8578 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8579 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8580 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8585 /*-----------------------------------------------------------------*/
8586 /* genRightShiftLiteral - right shifting by known count */
8587 /*-----------------------------------------------------------------*/
8588 static void genRightShiftLiteral (operand *left,
8594 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8597 pic16_freeAsmop(right,NULL,ic,TRUE);
8599 pic16_aopOp(left,ic,FALSE);
8600 pic16_aopOp(result,ic,FALSE);
8602 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8605 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8609 lsize = pic16_getDataSize(left);
8610 res_size = pic16_getDataSize(result);
8611 /* test the LEFT size !!! */
8613 /* I suppose that the left size >= result size */
8616 movLeft2Result(left, lsize, result, res_size);
8619 else if(shCount >= (lsize * 8)){
8622 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8624 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8625 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8630 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8631 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8632 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8634 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8639 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8646 genrshOne (result,left,shCount,sign);
8650 genrshTwo (result,left,shCount,sign);
8654 genrshFour (result,left,shCount,sign);
8662 pic16_freeAsmop(left,NULL,ic,TRUE);
8663 pic16_freeAsmop(result,NULL,ic,TRUE);
8666 /*-----------------------------------------------------------------*/
8667 /* genSignedRightShift - right shift of signed number */
8668 /*-----------------------------------------------------------------*/
8669 static void genSignedRightShift (iCode *ic)
8671 operand *right, *left, *result;
8674 symbol *tlbl, *tlbl1 ;
8677 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8679 /* we do it the hard way put the shift count in b
8680 and loop thru preserving the sign */
8681 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8683 right = IC_RIGHT(ic);
8685 result = IC_RESULT(ic);
8687 pic16_aopOp(right,ic,FALSE);
8688 pic16_aopOp(left,ic,FALSE);
8689 pic16_aopOp(result,ic,FALSE);
8692 if ( AOP_TYPE(right) == AOP_LIT) {
8693 genRightShiftLiteral (left,right,result,ic,1);
8696 /* shift count is unknown then we have to form
8697 a loop get the loop count in B : Note: we take
8698 only the lower order byte since shifting
8699 more that 32 bits make no sense anyway, ( the
8700 largest size of an object can be only 32 bits ) */
8702 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8703 //pic16_emitcode("inc","b");
8704 //pic16_freeAsmop (right,NULL,ic,TRUE);
8705 //pic16_aopOp(left,ic,FALSE);
8706 //pic16_aopOp(result,ic,FALSE);
8708 /* now move the left to the result if they are not the
8710 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8711 AOP_SIZE(result) > 1) {
8713 size = AOP_SIZE(result);
8717 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8718 if (*l == '@' && IS_AOP_PREG(result)) {
8720 pic16_emitcode("mov","a,%s",l);
8721 pic16_aopPut(AOP(result),"a",offset);
8723 pic16_aopPut(AOP(result),l,offset);
8725 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8726 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8732 /* mov the highest order bit to OVR */
8733 tlbl = newiTempLabel(NULL);
8734 tlbl1= newiTempLabel(NULL);
8736 size = AOP_SIZE(result);
8739 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8741 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8743 /* offset should be 0, 1 or 3 */
8744 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8746 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8748 pic16_emitpcode(POC_MOVWF, pctemp);
8751 pic16_emitpLabel(tlbl->key);
8753 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8754 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8757 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8760 pic16_emitpcode(POC_DECFSZ, pctemp);
8761 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8762 pic16_emitpLabel(tlbl1->key);
8764 pic16_popReleaseTempReg(pctemp);
8766 size = AOP_SIZE(result);
8768 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8769 pic16_emitcode("rlc","a");
8770 pic16_emitcode("mov","ov,c");
8771 /* if it is only one byte then */
8773 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8775 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8776 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8777 pic16_emitcode("mov","c,ov");
8778 pic16_emitcode("rrc","a");
8779 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8780 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8781 pic16_aopPut(AOP(result),"a",0);
8785 reAdjustPreg(AOP(result));
8786 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8787 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8788 pic16_emitcode("mov","c,ov");
8790 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8792 pic16_emitcode("rrc","a");
8793 pic16_aopPut(AOP(result),"a",offset--);
8795 reAdjustPreg(AOP(result));
8796 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8797 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8802 pic16_freeAsmop(left,NULL,ic,TRUE);
8803 pic16_freeAsmop(result,NULL,ic,TRUE);
8804 pic16_freeAsmop(right,NULL,ic,TRUE);
8807 /*-----------------------------------------------------------------*/
8808 /* genRightShift - generate code for right shifting */
8809 /*-----------------------------------------------------------------*/
8810 static void genRightShift (iCode *ic)
8812 operand *right, *left, *result;
8816 symbol *tlbl, *tlbl1 ;
8818 /* if signed then we do it the hard way preserve the
8819 sign bit moving it inwards */
8820 letype = getSpec(operandType(IC_LEFT(ic)));
8821 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8823 if (!SPEC_USIGN(letype)) {
8824 genSignedRightShift (ic);
8828 /* signed & unsigned types are treated the same : i.e. the
8829 signed is NOT propagated inwards : quoting from the
8830 ANSI - standard : "for E1 >> E2, is equivalent to division
8831 by 2**E2 if unsigned or if it has a non-negative value,
8832 otherwise the result is implementation defined ", MY definition
8833 is that the sign does not get propagated */
8835 right = IC_RIGHT(ic);
8837 result = IC_RESULT(ic);
8839 pic16_aopOp(right,ic,FALSE);
8841 /* if the shift count is known then do it
8842 as efficiently as possible */
8843 if (AOP_TYPE(right) == AOP_LIT) {
8844 genRightShiftLiteral (left,right,result,ic, 0);
8848 /* shift count is unknown then we have to form
8849 a loop get the loop count in B : Note: we take
8850 only the lower order byte since shifting
8851 more that 32 bits make no sense anyway, ( the
8852 largest size of an object can be only 32 bits ) */
8854 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8855 pic16_emitcode("inc","b");
8856 pic16_aopOp(left,ic,FALSE);
8857 pic16_aopOp(result,ic,FALSE);
8859 /* now move the left to the result if they are not the
8861 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8862 AOP_SIZE(result) > 1) {
8864 size = AOP_SIZE(result);
8867 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8868 if (*l == '@' && IS_AOP_PREG(result)) {
8870 pic16_emitcode("mov","a,%s",l);
8871 pic16_aopPut(AOP(result),"a",offset);
8873 pic16_aopPut(AOP(result),l,offset);
8878 tlbl = newiTempLabel(NULL);
8879 tlbl1= newiTempLabel(NULL);
8880 size = AOP_SIZE(result);
8883 /* if it is only one byte then */
8886 tlbl = newiTempLabel(NULL);
8887 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8888 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8889 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8892 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8893 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8894 pic16_emitpLabel(tlbl->key);
8895 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8896 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8898 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8903 reAdjustPreg(AOP(result));
8904 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8905 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8908 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8910 pic16_emitcode("rrc","a");
8911 pic16_aopPut(AOP(result),"a",offset--);
8913 reAdjustPreg(AOP(result));
8915 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8916 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8919 pic16_freeAsmop(left,NULL,ic,TRUE);
8920 pic16_freeAsmop (right,NULL,ic,TRUE);
8921 pic16_freeAsmop(result,NULL,ic,TRUE);
8924 /*-----------------------------------------------------------------*/
8925 /* genUnpackBits - generates code for unpacking bits */
8926 /*-----------------------------------------------------------------*/
8927 static void genUnpackBits (operand *result, char *rname, int ptype)
8934 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8935 etype = getSpec(operandType(result));
8937 /* read the first byte */
8944 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8947 pic16_emitcode("clr","a");
8948 pic16_emitcode("movc","a","@a+dptr");
8953 /* if we have bitdisplacement then it fits */
8954 /* into this byte completely or if length is */
8955 /* less than a byte */
8956 if ((shCnt = SPEC_BSTR(etype)) ||
8957 (SPEC_BLEN(etype) <= 8)) {
8959 /* shift right acc */
8962 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8963 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8965 /* VR -- normally I would use the following, but since we use the hack,
8966 * to avoid the masking from AccRsh, why not mask it right now? */
8969 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8972 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8978 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8979 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8982 /* bit field did not fit in a byte */
8983 rlen = SPEC_BLEN(etype) - 8;
8984 pic16_aopPut(AOP(result),"a",offset++);
8991 pic16_emitcode("inc","%s",rname);
8992 pic16_emitcode("mov","a,@%s",rname);
8996 pic16_emitcode("inc","%s",rname);
8997 pic16_emitcode("movx","a,@%s",rname);
9001 pic16_emitcode("inc","dptr");
9002 pic16_emitcode("movx","a,@dptr");
9006 pic16_emitcode("clr","a");
9007 pic16_emitcode("inc","dptr");
9008 pic16_emitcode("movc","a","@a+dptr");
9012 pic16_emitcode("inc","dptr");
9013 pic16_emitcode("lcall","__gptrget");
9018 /* if we are done */
9022 pic16_aopPut(AOP(result),"a",offset++);
9027 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
9028 pic16_aopPut(AOP(result),"a",offset);
9035 static void genDataPointerGet(operand *left,
9039 int size, offset = 0, leoffset=0 ;
9041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9042 pic16_aopOp(result, ic, FALSE);
9044 size = AOP_SIZE(result);
9045 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9049 /* The following tests may save a redudant movff instruction when
9050 * accessing unions */
9052 /* if they are the same */
9053 if (operandsEqu (left, result)) {
9054 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
9060 /* if they are the same registers */
9061 if (pic16_sameRegs(AOP(left),AOP(result))) {
9062 DEBUGpic16_emitcode("; ***", "left and result registers are same");
9068 if ( AOP_TYPE(left) == AOP_PCODE) {
9069 fprintf(stderr,"genDataPointerGet %s, %d\n",
9070 AOP(left)->aopu.pcop->name,
9071 (AOP(left)->aopu.pcop->type == PO_DIR)?
9072 PCOR(AOP(left)->aopu.pcop)->instance:
9073 PCOI(AOP(left)->aopu.pcop)->offset);
9077 if(AOP(left)->aopu.pcop->type == PO_DIR)
9078 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
9080 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9083 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
9085 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
9086 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
9087 mov2w(AOP(left), offset); // patch 8
9088 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
9090 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
9091 pic16_popGet(AOP(left), offset), //patch 8
9092 pic16_popGet(AOP(result), offset)));
9100 pic16_freeAsmop(result,NULL,ic,TRUE);
9103 void pic16_loadFSR0(operand *op)
9105 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
9109 /*-----------------------------------------------------------------*/
9110 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
9111 /*-----------------------------------------------------------------*/
9112 static void genNearPointerGet (operand *left,
9117 //regs *preg = NULL ;
9118 sym_link *rtype, *retype;
9119 sym_link *ltype = operandType(left);
9121 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9122 rtype = operandType(result);
9123 retype= getSpec(rtype);
9125 pic16_aopOp(left,ic,FALSE);
9127 pic16_DumpOp("(left)",left);
9128 pic16_DumpOp("(result)",result);
9130 /* if left is rematerialisable and
9131 * result is not bit variable type and
9132 * the left is pointer to data space i.e
9133 * lower 128 bytes of space */
9134 if (AOP_TYPE(left) == AOP_PCODE
9135 && !IS_BITFIELD(retype)
9136 && DCL_TYPE(ltype) == POINTER) {
9138 genDataPointerGet (left,result,ic);
9139 pic16_freeAsmop(left, NULL, ic, TRUE);
9143 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9145 /* if the value is already in a pointer register
9146 * then don't need anything more */
9147 if (!AOP_INPREG(AOP(left))) {
9148 /* otherwise get a free pointer register */
9149 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9151 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
9152 if( (AOP_TYPE(left) == AOP_PCODE)
9153 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9154 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
9156 pic16_loadFSR0( left ); // patch 10
9158 // set up FSR0 with address from left
9159 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9160 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9164 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9166 pic16_aopOp (result,ic,FALSE);
9168 /* if bitfield then unpack the bits */
9169 if (IS_BITFIELD(retype))
9170 genUnpackBits (result, NULL, POINTER);
9172 /* we have can just get the values */
9173 int size = AOP_SIZE(result);
9176 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9179 /* fsr0 is loaded already -- VR */
9180 // pic16_loadFSR0( left );
9182 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
9183 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9187 pic16_emitpcode(POC_MOVFF,
9188 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
9189 pic16_popGet(AOP(result), offset++)));
9191 pic16_emitpcode(POC_MOVFF,
9192 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
9193 pic16_popGet(AOP(result), offset++)));
9197 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
9198 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
9200 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9204 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
9206 pic16_emitcode("mov","a,@%s",rname);
9207 pic16_aopPut(AOP(result),"a",offset);
9209 sprintf(buffer,"@%s",rname);
9210 pic16_aopPut(AOP(result),buffer,offset);
9214 pic16_emitcode("inc","%s",rname);
9219 /* now some housekeeping stuff */
9221 /* we had to allocate for this iCode */
9222 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9223 pic16_freeAsmop(NULL,aop,ic,TRUE);
9225 /* we did not allocate which means left
9226 already in a pointer register, then
9227 if size > 0 && this could be used again
9228 we have to point it back to where it
9230 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9231 if (AOP_SIZE(result) > 1 &&
9232 !OP_SYMBOL(left)->remat &&
9233 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9235 // int size = AOP_SIZE(result) - 1;
9237 // pic16_emitcode("dec","%s",rname);
9242 pic16_freeAsmop(left,NULL,ic,TRUE);
9243 pic16_freeAsmop(result,NULL,ic,TRUE);
9247 /*-----------------------------------------------------------------*/
9248 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
9249 /*-----------------------------------------------------------------*/
9250 static void genPagedPointerGet (operand *left,
9257 sym_link *rtype, *retype;
9259 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9261 rtype = operandType(result);
9262 retype= getSpec(rtype);
9264 pic16_aopOp(left,ic,FALSE);
9266 /* if the value is already in a pointer register
9267 then don't need anything more */
9268 if (!AOP_INPREG(AOP(left))) {
9269 /* otherwise get a free pointer register */
9271 preg = getFreePtr(ic,&aop,FALSE);
9272 pic16_emitcode("mov","%s,%s",
9274 pic16_aopGet(AOP(left),0,FALSE,TRUE));
9275 rname = preg->name ;
9277 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9279 pic16_freeAsmop(left,NULL,ic,TRUE);
9280 pic16_aopOp (result,ic,FALSE);
9282 /* if bitfield then unpack the bits */
9283 if (IS_BITFIELD(retype))
9284 genUnpackBits (result,rname,PPOINTER);
9286 /* we have can just get the values */
9287 int size = AOP_SIZE(result);
9292 pic16_emitcode("movx","a,@%s",rname);
9293 pic16_aopPut(AOP(result),"a",offset);
9298 pic16_emitcode("inc","%s",rname);
9302 /* now some housekeeping stuff */
9304 /* we had to allocate for this iCode */
9305 pic16_freeAsmop(NULL,aop,ic,TRUE);
9307 /* we did not allocate which means left
9308 already in a pointer register, then
9309 if size > 0 && this could be used again
9310 we have to point it back to where it
9312 if (AOP_SIZE(result) > 1 &&
9313 !OP_SYMBOL(left)->remat &&
9314 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9316 int size = AOP_SIZE(result) - 1;
9318 pic16_emitcode("dec","%s",rname);
9323 pic16_freeAsmop(result,NULL,ic,TRUE);
9328 /*-----------------------------------------------------------------*/
9329 /* genFarPointerGet - gget value from far space */
9330 /*-----------------------------------------------------------------*/
9331 static void genFarPointerGet (operand *left,
9332 operand *result, iCode *ic)
9335 sym_link *retype = getSpec(operandType(result));
9337 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9339 pic16_aopOp(left,ic,FALSE);
9341 /* if the operand is already in dptr
9342 then we do nothing else we move the value to dptr */
9343 if (AOP_TYPE(left) != AOP_STR) {
9344 /* if this is remateriazable */
9345 if (AOP_TYPE(left) == AOP_IMMD)
9346 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9347 else { /* we need to get it byte by byte */
9348 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9349 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9350 if (options.model == MODEL_FLAT24)
9352 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9356 /* so dptr know contains the address */
9357 pic16_freeAsmop(left,NULL,ic,TRUE);
9358 pic16_aopOp(result,ic,FALSE);
9360 /* if bit then unpack */
9361 if (IS_BITFIELD(retype))
9362 genUnpackBits(result,"dptr",FPOINTER);
9364 size = AOP_SIZE(result);
9368 pic16_emitcode("movx","a,@dptr");
9369 pic16_aopPut(AOP(result),"a",offset++);
9371 pic16_emitcode("inc","dptr");
9375 pic16_freeAsmop(result,NULL,ic,TRUE);
9378 /*-----------------------------------------------------------------*/
9379 /* genCodePointerGet - get value from code space */
9380 /*-----------------------------------------------------------------*/
9381 static void genCodePointerGet (operand *left,
9382 operand *result, iCode *ic)
9385 sym_link *retype = getSpec(operandType(result));
9387 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9389 pic16_aopOp(left,ic,FALSE);
9391 /* if the operand is already in dptr
9392 then we do nothing else we move the value to dptr */
9393 if (AOP_TYPE(left) != AOP_STR) {
9394 /* if this is remateriazable */
9395 if (AOP_TYPE(left) == AOP_IMMD)
9396 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9397 else { /* we need to get it byte by byte */
9398 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9399 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9400 if (options.model == MODEL_FLAT24)
9402 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9406 /* so dptr know contains the address */
9407 pic16_freeAsmop(left,NULL,ic,TRUE);
9408 pic16_aopOp(result,ic,FALSE);
9410 /* if bit then unpack */
9411 if (IS_BITFIELD(retype))
9412 genUnpackBits(result,"dptr",CPOINTER);
9414 size = AOP_SIZE(result);
9418 pic16_emitcode("clr","a");
9419 pic16_emitcode("movc","a,@a+dptr");
9420 pic16_aopPut(AOP(result),"a",offset++);
9422 pic16_emitcode("inc","dptr");
9426 pic16_freeAsmop(result,NULL,ic,TRUE);
9429 /*-----------------------------------------------------------------*/
9430 /* genGenPointerGet - gget value from generic pointer space */
9431 /*-----------------------------------------------------------------*/
9432 static void genGenPointerGet (operand *left,
9433 operand *result, iCode *ic)
9435 int size, offset, lit;
9436 sym_link *retype = getSpec(operandType(result));
9438 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9439 pic16_aopOp(left,ic,FALSE);
9440 pic16_aopOp(result,ic,FALSE);
9441 size = AOP_SIZE(result);
9443 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9445 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
9447 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
9448 // load FSR0 from immediate
9449 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9451 // pic16_loadFSR0( left );
9456 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9458 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9465 else { /* we need to get it byte by byte */
9466 // set up FSR0 with address from left
9467 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9468 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9474 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9476 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9483 /* if bit then unpack */
9484 if (IS_BITFIELD(retype))
9485 genUnpackBits(result,"BAD",GPOINTER);
9488 pic16_freeAsmop(left,NULL,ic,TRUE);
9489 pic16_freeAsmop(result,NULL,ic,TRUE);
9493 /*-----------------------------------------------------------------*/
9494 /* genConstPointerGet - get value from const generic pointer space */
9495 /*-----------------------------------------------------------------*/
9496 static void genConstPointerGet (operand *left,
9497 operand *result, iCode *ic)
9499 //sym_link *retype = getSpec(operandType(result));
9500 // symbol *albl = newiTempLabel(NULL); // patch 15
9501 // symbol *blbl = newiTempLabel(NULL); //
9502 // PIC_OPCODE poc; // patch 15
9506 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9507 pic16_aopOp(left,ic,FALSE);
9508 pic16_aopOp(result,ic,TRUE);
9509 size = AOP_SIZE(result);
9511 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9513 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
9515 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
9516 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
9517 pic16_emitpLabel(albl->key);
9519 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
9521 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
9522 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
9523 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
9524 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
9525 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
9527 pic16_emitpLabel(blbl->key);
9529 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
9533 // set up table pointer
9534 if( (AOP_TYPE(left) == AOP_PCODE)
9535 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9536 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
9538 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
9539 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
9540 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
9541 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
9542 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
9543 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
9547 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
9548 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
9549 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
9555 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
9556 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
9560 pic16_freeAsmop(left,NULL,ic,TRUE);
9561 pic16_freeAsmop(result,NULL,ic,TRUE);
9564 /*-----------------------------------------------------------------*/
9565 /* genPointerGet - generate code for pointer get */
9566 /*-----------------------------------------------------------------*/
9567 static void genPointerGet (iCode *ic)
9569 operand *left, *result ;
9570 sym_link *type, *etype;
9573 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9576 result = IC_RESULT(ic) ;
9578 /* depending on the type of pointer we need to
9579 move it to the correct pointer register */
9580 type = operandType(left);
9581 etype = getSpec(type);
9584 if (IS_PTR_CONST(type))
9586 if (IS_CODEPTR(type))
9588 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9590 /* if left is of type of pointer then it is simple */
9591 if (IS_PTR(type) && !IS_FUNC(type->next))
9592 p_type = DCL_TYPE(type);
9594 /* we have to go by the storage class */
9595 p_type = PTR_TYPE(SPEC_OCLS(etype));
9597 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9599 if (SPEC_OCLS(etype)->codesp ) {
9600 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9601 //p_type = CPOINTER ;
9604 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9605 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9606 /*p_type = FPOINTER ;*/
9608 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9609 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9610 /* p_type = PPOINTER; */
9612 if (SPEC_OCLS(etype) == idata )
9613 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9614 /* p_type = IPOINTER; */
9616 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9617 /* p_type = POINTER ; */
9620 /* now that we have the pointer type we assign
9621 the pointer values */
9626 genNearPointerGet (left,result,ic);
9630 genPagedPointerGet(left,result,ic);
9634 genFarPointerGet (left,result,ic);
9638 genConstPointerGet (left,result,ic);
9639 //pic16_emitcodePointerGet (left,result,ic);
9644 if (IS_PTR_CONST(type))
9645 genConstPointerGet (left,result,ic);
9648 genGenPointerGet (left,result,ic);
9654 /*-----------------------------------------------------------------*/
9655 /* genPackBits - generates code for packed bit storage */
9656 /*-----------------------------------------------------------------*/
9657 static void genPackBits (sym_link *etype ,
9659 char *rname, int p_type)
9667 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9668 blen = SPEC_BLEN(etype);
9669 bstr = SPEC_BSTR(etype);
9671 if(AOP_TYPE(right) == AOP_LIT) {
9672 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9675 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9677 /* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9680 /* if the bit lenth is less than or */
9681 /* it exactly fits a byte then */
9682 if((shCnt=SPEC_BSTR(etype))
9683 || SPEC_BLEN(etype) <= 8 ) {
9685 /* shift left acc */
9688 /* using PRODL as a temporary register here */
9689 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9695 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9696 // pic16_emitcode ("mov","b,a");
9697 // pic16_emitcode("mov","a,@%s",rname);
9701 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9702 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9703 (unsigned char)(0xff >> (8-bstr))) ));
9704 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9705 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9709 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9710 ((unsigned char)(0xFF << (blen+bstr)) |
9711 (unsigned char)(0xFF >> (8-bstr)) ) );
9712 pic16_emitcode ("orl","a,b");
9713 if (p_type == GPOINTER)
9714 pic16_emitcode("pop","b");
9719 pic16_emitcode("mov","@%s,a",rname);
9722 pic16_emitcode("movx","@dptr,a");
9725 DEBUGpic16_emitcode(";lcall","__gptrput");
9734 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9735 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9740 if ( SPEC_BLEN(etype) <= 8 )
9743 pic16_emitcode("inc","%s",rname);
9744 rLen = SPEC_BLEN(etype) ;
9748 /* now generate for lengths greater than one byte */
9751 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9761 pic16_emitcode("mov","@%s,a",rname);
9763 pic16_emitcode("mov","@%s,%s",rname,l);
9768 pic16_emitcode("movx","@dptr,a");
9773 DEBUGpic16_emitcode(";lcall","__gptrput");
9776 pic16_emitcode ("inc","%s",rname);
9781 /* last last was not complete */
9783 /* save the byte & read byte */
9786 pic16_emitcode ("mov","b,a");
9787 pic16_emitcode("mov","a,@%s",rname);
9791 pic16_emitcode ("mov","b,a");
9792 pic16_emitcode("movx","a,@dptr");
9796 pic16_emitcode ("push","b");
9797 pic16_emitcode ("push","acc");
9798 pic16_emitcode ("lcall","__gptrget");
9799 pic16_emitcode ("pop","b");
9803 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9804 pic16_emitcode ("orl","a,b");
9807 if (p_type == GPOINTER)
9808 pic16_emitcode("pop","b");
9813 pic16_emitcode("mov","@%s,a",rname);
9817 pic16_emitcode("movx","@dptr,a");
9821 DEBUGpic16_emitcode(";lcall","__gptrput");
9825 /*-----------------------------------------------------------------*/
9826 /* genDataPointerSet - remat pointer to data space */
9827 /*-----------------------------------------------------------------*/
9828 static void genDataPointerSet(operand *right,
9832 int size, offset = 0, resoffset=0 ;
9834 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9835 pic16_aopOp(right,ic,FALSE);
9837 size = AOP_SIZE(right);
9839 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9842 if ( AOP_TYPE(result) == AOP_PCODE) {
9843 fprintf(stderr,"genDataPointerSet %s, %d\n",
9844 AOP(result)->aopu.pcop->name,
9845 (AOP(result)->aopu.pcop->type == PO_DIR)?
9846 PCOR(AOP(result)->aopu.pcop)->instance:
9847 PCOI(AOP(result)->aopu.pcop)->offset);
9851 if(AOP(result)->aopu.pcop->type == PO_DIR)
9852 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9855 if (AOP_TYPE(right) == AOP_LIT) {
9856 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9858 lit = lit >> (8*offset);
9860 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9861 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
9863 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
9866 mov2w(AOP(right), offset);
9867 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
9873 pic16_freeAsmop(right,NULL,ic,TRUE);
9878 /*-----------------------------------------------------------------*/
9879 /* genNearPointerSet - pic16_emitcode for near pointer put */
9880 /*-----------------------------------------------------------------*/
9881 static void genNearPointerSet (operand *right,
9888 sym_link *ptype = operandType(result);
9891 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9892 retype= getSpec(operandType(right));
9893 resetype = getSpec(operandType(result));
9895 pic16_aopOp(result,ic,FALSE);
9897 /* if the result is rematerializable &
9898 * in data space & not a bit variable */
9900 /* and result is not a bit variable */
9901 if (AOP_TYPE(result) == AOP_PCODE
9902 // && AOP_TYPE(result) == AOP_IMMD
9903 && DCL_TYPE(ptype) == POINTER
9904 && !IS_BITFIELD(retype)
9905 && !IS_BITFIELD(resetype)) {
9907 genDataPointerSet (right,result,ic);
9908 pic16_freeAsmop(result,NULL,ic,TRUE);
9912 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9913 pic16_aopOp(right,ic,FALSE);
9914 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9916 /* if the value is already in a pointer register
9917 * then don't need anything more */
9918 if (!AOP_INPREG(AOP(result))) {
9919 /* otherwise get a free pointer register */
9920 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9922 if( (AOP_TYPE(result) == AOP_PCODE)
9923 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
9924 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
9926 pic16_loadFSR0( result ); // patch 10
9928 // set up FSR0 with address of result
9929 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9930 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9935 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9939 /* if bitfield then unpack the bits */
9940 if (IS_BITFIELD(resetype)) {
9941 genPackBits (resetype, right, NULL, POINTER);
9943 /* we have can just get the values */
9944 int size = AOP_SIZE(right);
9947 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9949 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9952 //pic16_emitcode("mov","@%s,a",rname);
9953 pic16_emitcode("movf","indf0,w ;1");
9956 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
9957 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
9959 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
9961 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
9963 } else { // no literal //
9965 pic16_emitpcode(POC_MOVFF, //
9966 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9967 pic16_popCopyReg(&pic16_pc_postinc0))); //
9969 pic16_emitpcode(POC_MOVFF, //
9970 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9971 pic16_popCopyReg(&pic16_pc_indf0))); //
9979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9980 /* now some housekeeping stuff */
9982 /* we had to allocate for this iCode */
9983 pic16_freeAsmop(NULL,aop,ic,TRUE);
9985 /* we did not allocate which means left
9986 * already in a pointer register, then
9987 * if size > 0 && this could be used again
9988 * we have to point it back to where it
9990 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9991 if (AOP_SIZE(right) > 1
9992 && !OP_SYMBOL(result)->remat
9993 && ( OP_SYMBOL(result)->liveTo > ic->seq
9996 int size = AOP_SIZE(right) - 1;
9999 pic16_emitcode("decf","fsr0,f");
10000 //pic16_emitcode("dec","%s",rname);
10004 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10007 pic16_freeAsmop(right,NULL,ic,TRUE);
10008 pic16_freeAsmop(result,NULL,ic,TRUE);
10011 /*-----------------------------------------------------------------*/
10012 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
10013 /*-----------------------------------------------------------------*/
10014 static void genPagedPointerSet (operand *right,
10019 regs *preg = NULL ;
10023 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10025 retype= getSpec(operandType(right));
10027 pic16_aopOp(result,ic,FALSE);
10029 /* if the value is already in a pointer register
10030 then don't need anything more */
10031 if (!AOP_INPREG(AOP(result))) {
10032 /* otherwise get a free pointer register */
10034 preg = getFreePtr(ic,&aop,FALSE);
10035 pic16_emitcode("mov","%s,%s",
10037 pic16_aopGet(AOP(result),0,FALSE,TRUE));
10038 rname = preg->name ;
10040 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10042 pic16_freeAsmop(result,NULL,ic,TRUE);
10043 pic16_aopOp (right,ic,FALSE);
10045 /* if bitfield then unpack the bits */
10046 if (IS_BITFIELD(retype))
10047 genPackBits (retype,right,rname,PPOINTER);
10049 /* we have can just get the values */
10050 int size = AOP_SIZE(right);
10054 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
10057 pic16_emitcode("movx","@%s,a",rname);
10060 pic16_emitcode("inc","%s",rname);
10066 /* now some housekeeping stuff */
10068 /* we had to allocate for this iCode */
10069 pic16_freeAsmop(NULL,aop,ic,TRUE);
10071 /* we did not allocate which means left
10072 already in a pointer register, then
10073 if size > 0 && this could be used again
10074 we have to point it back to where it
10076 if (AOP_SIZE(right) > 1 &&
10077 !OP_SYMBOL(result)->remat &&
10078 ( OP_SYMBOL(result)->liveTo > ic->seq ||
10080 int size = AOP_SIZE(right) - 1;
10082 pic16_emitcode("dec","%s",rname);
10087 pic16_freeAsmop(right,NULL,ic,TRUE);
10092 /*-----------------------------------------------------------------*/
10093 /* genFarPointerSet - set value from far space */
10094 /*-----------------------------------------------------------------*/
10095 static void genFarPointerSet (operand *right,
10096 operand *result, iCode *ic)
10099 sym_link *retype = getSpec(operandType(right));
10101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10102 pic16_aopOp(result,ic,FALSE);
10104 /* if the operand is already in dptr
10105 then we do nothing else we move the value to dptr */
10106 if (AOP_TYPE(result) != AOP_STR) {
10107 /* if this is remateriazable */
10108 if (AOP_TYPE(result) == AOP_IMMD)
10109 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
10110 else { /* we need to get it byte by byte */
10111 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
10112 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
10113 if (options.model == MODEL_FLAT24)
10115 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
10119 /* so dptr know contains the address */
10120 pic16_freeAsmop(result,NULL,ic,TRUE);
10121 pic16_aopOp(right,ic,FALSE);
10123 /* if bit then unpack */
10124 if (IS_BITFIELD(retype))
10125 genPackBits(retype,right,"dptr",FPOINTER);
10127 size = AOP_SIZE(right);
10131 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10133 pic16_emitcode("movx","@dptr,a");
10135 pic16_emitcode("inc","dptr");
10139 pic16_freeAsmop(right,NULL,ic,TRUE);
10142 /*-----------------------------------------------------------------*/
10143 /* genGenPointerSet - set value from generic pointer space */
10144 /*-----------------------------------------------------------------*/
10145 static void genGenPointerSet (operand *right,
10146 operand *result, iCode *ic)
10148 int i, size, offset, lit;
10149 sym_link *retype = getSpec(operandType(right));
10151 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10153 pic16_aopOp(result,ic,FALSE);
10154 pic16_aopOp(right,ic,FALSE);
10155 size = AOP_SIZE(right);
10158 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10160 /* if the operand is already in dptr
10161 then we do nothing else we move the value to dptr */
10162 if (AOP_TYPE(result) != AOP_STR) {
10163 /* if this is remateriazable */
10164 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10165 // WARNING: anythig until "else" is untested!
10166 if (AOP_TYPE(result) == AOP_IMMD) {
10167 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10168 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
10169 // load FSR0 from immediate
10170 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10174 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10176 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10182 else { /* we need to get it byte by byte */
10183 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10184 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10186 // set up FSR0 with address of result
10187 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10188 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10190 /* hack hack! see if this the FSR. If so don't load W */
10191 if(AOP_TYPE(right) != AOP_ACC) {
10193 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10195 if(AOP_TYPE(right) == AOP_LIT)
10198 // note: pic16_popGet handles sign extension
10199 for(i=0;i<size;i++) {
10200 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
10202 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
10204 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10209 for(i=0;i<size;i++) {
10211 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10212 pic16_popCopyReg(&pic16_pc_postinc0)));
10214 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10215 pic16_popCopyReg(&pic16_pc_indf0)));
10221 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10222 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10224 } // if (AOP_TYPE(result) != AOP_IMMD)
10226 } // if (AOP_TYPE(result) != AOP_STR)
10227 /* so dptr know contains the address */
10230 /* if bit then unpack */
10231 if (IS_BITFIELD(retype))
10232 genPackBits(retype,right,"dptr",GPOINTER);
10234 size = AOP_SIZE(right);
10237 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
10239 // set up FSR0 with address of result
10240 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10241 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10244 if (AOP_TYPE(right) == AOP_LIT) {
10245 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10247 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
10249 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10251 } else { // no literal
10253 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10255 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10263 pic16_freeAsmop(right,NULL,ic,TRUE);
10264 pic16_freeAsmop(result,NULL,ic,TRUE);
10267 /*-----------------------------------------------------------------*/
10268 /* genPointerSet - stores the value into a pointer location */
10269 /*-----------------------------------------------------------------*/
10270 static void genPointerSet (iCode *ic)
10272 operand *right, *result ;
10273 sym_link *type, *etype;
10276 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10278 right = IC_RIGHT(ic);
10279 result = IC_RESULT(ic) ;
10281 /* depending on the type of pointer we need to
10282 move it to the correct pointer register */
10283 type = operandType(result);
10284 etype = getSpec(type);
10285 /* if left is of type of pointer then it is simple */
10286 if (IS_PTR(type) && !IS_FUNC(type->next)) {
10287 p_type = DCL_TYPE(type);
10290 /* we have to go by the storage class */
10291 p_type = PTR_TYPE(SPEC_OCLS(etype));
10293 /* if (SPEC_OCLS(etype)->codesp ) { */
10294 /* p_type = CPOINTER ; */
10297 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10298 /* p_type = FPOINTER ; */
10300 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10301 /* p_type = PPOINTER ; */
10303 /* if (SPEC_OCLS(etype) == idata ) */
10304 /* p_type = IPOINTER ; */
10306 /* p_type = POINTER ; */
10309 /* now that we have the pointer type we assign
10310 the pointer values */
10315 genNearPointerSet (right,result,ic);
10319 genPagedPointerSet (right,result,ic);
10323 genFarPointerSet (right,result,ic);
10327 genGenPointerSet (right,result,ic);
10331 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10332 "genPointerSet: illegal pointer type");
10336 /*-----------------------------------------------------------------*/
10337 /* genIfx - generate code for Ifx statement */
10338 /*-----------------------------------------------------------------*/
10339 static void genIfx (iCode *ic, iCode *popIc)
10341 operand *cond = IC_COND(ic);
10344 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10346 pic16_aopOp(cond,ic,FALSE);
10348 /* get the value into acc */
10349 if (AOP_TYPE(cond) != AOP_CRY)
10350 pic16_toBoolean(cond);
10353 /* the result is now in the accumulator */
10354 pic16_freeAsmop(cond,NULL,ic,TRUE);
10356 /* if there was something to be popped then do it */
10360 /* if the condition is a bit variable */
10361 if (isbit && IS_ITEMP(cond) &&
10363 genIfxJump(ic,SPIL_LOC(cond)->rname);
10364 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
10367 if (isbit && !IS_ITEMP(cond))
10368 genIfxJump(ic,OP_SYMBOL(cond)->rname);
10370 genIfxJump(ic,"a");
10376 /*-----------------------------------------------------------------*/
10377 /* genAddrOf - generates code for address of */
10378 /*-----------------------------------------------------------------*/
10379 static void genAddrOf (iCode *ic)
10381 operand *result, *left;
10383 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
10384 pCodeOp *pcop0, *pcop1, *pcop2;
10386 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10388 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
10389 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
10391 sym = OP_SYMBOL( left );
10393 size = AOP_SIZE(IC_RESULT(ic));
10395 if(pic16_debug_verbose) {
10396 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
10397 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
10400 /* Assume that what we want the address of is in data space
10401 * since there is no stack on the PIC, yet! -- VR */
10403 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10406 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10409 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10413 pic16_emitpcode(POC_MOVLW, pcop0);
10414 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10415 pic16_emitpcode(POC_MOVLW, pcop1);
10416 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10417 pic16_emitpcode(POC_MOVLW, pcop2);
10418 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10421 pic16_emitpcode(POC_MOVLW, pcop0);
10422 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10423 pic16_emitpcode(POC_MOVLW, pcop1);
10424 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10426 pic16_emitpcode(POC_MOVLW, pcop0);
10427 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10430 pic16_freeAsmop(result,NULL,ic,TRUE);
10431 pic16_freeAsmop(left, NULL, ic, FALSE);
10436 /*-----------------------------------------------------------------*/
10437 /* genFarFarAssign - assignment when both are in far space */
10438 /*-----------------------------------------------------------------*/
10439 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
10441 int size = AOP_SIZE(right);
10444 /* first push the right side on to the stack */
10446 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10448 pic16_emitcode ("push","acc");
10451 pic16_freeAsmop(right,NULL,ic,FALSE);
10452 /* now assign DPTR to result */
10453 pic16_aopOp(result,ic,FALSE);
10454 size = AOP_SIZE(result);
10456 pic16_emitcode ("pop","acc");
10457 pic16_aopPut(AOP(result),"a",--offset);
10459 pic16_freeAsmop(result,NULL,ic,FALSE);
10464 /*-----------------------------------------------------------------*/
10465 /* genAssign - generate code for assignment */
10466 /*-----------------------------------------------------------------*/
10467 static void genAssign (iCode *ic)
10469 operand *result, *right;
10470 int size, offset,know_W;
10471 unsigned long lit = 0L;
10473 result = IC_RESULT(ic);
10474 right = IC_RIGHT(ic) ;
10476 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10478 /* if they are the same */
10479 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
10482 pic16_aopOp(right,ic,FALSE);
10483 pic16_aopOp(result,ic,TRUE);
10485 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10487 /* if they are the same registers */
10488 if (pic16_sameRegs(AOP(right),AOP(result)))
10491 /* if the result is a bit */
10492 if (AOP_TYPE(result) == AOP_CRY) {
10493 /* if the right size is a literal then
10494 we know what the value is */
10495 if (AOP_TYPE(right) == AOP_LIT) {
10497 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10498 pic16_popGet(AOP(result),0));
10500 if (((int) operandLitValue(right)))
10501 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10502 AOP(result)->aopu.aop_dir,
10503 AOP(result)->aopu.aop_dir);
10505 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10506 AOP(result)->aopu.aop_dir,
10507 AOP(result)->aopu.aop_dir);
10511 /* the right is also a bit variable */
10512 if (AOP_TYPE(right) == AOP_CRY) {
10513 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10514 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10515 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10517 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10518 AOP(result)->aopu.aop_dir,
10519 AOP(result)->aopu.aop_dir);
10520 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
10521 AOP(right)->aopu.aop_dir,
10522 AOP(right)->aopu.aop_dir);
10523 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10524 AOP(result)->aopu.aop_dir,
10525 AOP(result)->aopu.aop_dir);
10529 /* we need to or */
10530 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10531 pic16_toBoolean(right);
10533 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10534 //pic16_aopPut(AOP(result),"a",0);
10538 /* bit variables done */
10540 size = AOP_SIZE(result);
10542 if(AOP_TYPE(right) == AOP_LIT)
10543 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10545 /* VR - What is this?! */
10546 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
10547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10548 if(aopIdx(AOP(result),0) == 4) {
10549 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10550 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10551 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10554 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
10559 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10560 if(AOP_TYPE(right) == AOP_LIT) {
10562 if(know_W != (lit&0xff))
10563 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
10565 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10567 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10571 } else if (AOP_TYPE(right) == AOP_CRY) {
10572 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10574 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
10575 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10577 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
10578 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10579 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10581 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10584 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
10585 normally should work, but mind that the W register live range
10586 is not checked, so if the code generator assumes that the W
10587 is already loaded after such a pair, wrong code will be generated.
10589 Checking the live range is the next step.
10590 This is experimental code yet and has not been fully tested yet.
10591 USE WITH CARE. Revert to old code by setting 0 to the condition above.
10592 Vangelis Rokas 030603 (vrokas@otenet.gr) */
10594 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
10596 /* This is the old code, which is assumed(?!) that works fine(!?) */
10598 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10599 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10608 pic16_freeAsmop (right,NULL,ic,FALSE);
10609 pic16_freeAsmop (result,NULL,ic,TRUE);
10612 /*-----------------------------------------------------------------*/
10613 /* genJumpTab - generates code for jump table */
10614 /*-----------------------------------------------------------------*/
10615 static void genJumpTab (iCode *ic)
10620 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10622 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10623 /* get the condition into accumulator */
10624 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10626 /* multiply by three */
10627 pic16_emitcode("add","a,acc");
10628 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10630 jtab = newiTempLabel(NULL);
10631 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10632 pic16_emitcode("jmp","@a+dptr");
10633 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10635 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10636 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10638 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10639 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10640 pic16_emitpLabel(jtab->key);
10642 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10644 /* now generate the jump labels */
10645 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10646 jtab = setNextItem(IC_JTLABELS(ic))) {
10647 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10648 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10654 /*-----------------------------------------------------------------*/
10655 /* genMixedOperation - gen code for operators between mixed types */
10656 /*-----------------------------------------------------------------*/
10658 TSD - Written for the PIC port - but this unfortunately is buggy.
10659 This routine is good in that it is able to efficiently promote
10660 types to different (larger) sizes. Unfortunately, the temporary
10661 variables that are optimized out by this routine are sometimes
10662 used in other places. So until I know how to really parse the
10663 iCode tree, I'm going to not be using this routine :(.
10665 static int genMixedOperation (iCode *ic)
10668 operand *result = IC_RESULT(ic);
10669 sym_link *ctype = operandType(IC_LEFT(ic));
10670 operand *right = IC_RIGHT(ic);
10676 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10678 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10684 nextright = IC_RIGHT(nextic);
10685 nextleft = IC_LEFT(nextic);
10686 nextresult = IC_RESULT(nextic);
10688 pic16_aopOp(right,ic,FALSE);
10689 pic16_aopOp(result,ic,FALSE);
10690 pic16_aopOp(nextright, nextic, FALSE);
10691 pic16_aopOp(nextleft, nextic, FALSE);
10692 pic16_aopOp(nextresult, nextic, FALSE);
10694 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10696 operand *t = right;
10700 pic16_emitcode(";remove right +","");
10702 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10704 operand *t = right;
10708 pic16_emitcode(";remove left +","");
10712 big = AOP_SIZE(nextleft);
10713 small = AOP_SIZE(nextright);
10715 switch(nextic->op) {
10718 pic16_emitcode(";optimize a +","");
10719 /* if unsigned or not an integral type */
10720 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10721 pic16_emitcode(";add a bit to something","");
10724 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10726 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10727 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10728 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10730 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10738 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10739 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10740 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10743 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10745 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10746 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10747 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10748 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10749 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10752 pic16_emitcode("rlf","known_zero,w");
10759 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10760 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10761 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10763 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10773 pic16_freeAsmop(right,NULL,ic,TRUE);
10774 pic16_freeAsmop(result,NULL,ic,TRUE);
10775 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10776 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10778 nextic->generated = 1;
10785 /*-----------------------------------------------------------------*/
10786 /* genCast - gen code for casting */
10787 /*-----------------------------------------------------------------*/
10788 static void genCast (iCode *ic)
10790 operand *result = IC_RESULT(ic);
10791 sym_link *ctype = operandType(IC_LEFT(ic));
10792 sym_link *rtype = operandType(IC_RIGHT(ic));
10793 operand *right = IC_RIGHT(ic);
10796 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10797 /* if they are equivalent then do nothing */
10798 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10801 pic16_aopOp(right,ic,FALSE) ;
10802 pic16_aopOp(result,ic,FALSE);
10804 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10806 /* if the result is a bit */
10807 if (AOP_TYPE(result) == AOP_CRY) {
10809 /* if the right size is a literal then
10810 * we know what the value is */
10811 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10813 if (AOP_TYPE(right) == AOP_LIT) {
10814 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10815 pic16_popGet(AOP(result),0));
10817 if (((int) operandLitValue(right)))
10818 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10819 AOP(result)->aopu.aop_dir,
10820 AOP(result)->aopu.aop_dir);
10822 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10823 AOP(result)->aopu.aop_dir,
10824 AOP(result)->aopu.aop_dir);
10828 /* the right is also a bit variable */
10829 if (AOP_TYPE(right) == AOP_CRY) {
10831 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10833 pic16_emitcode("clrc","");
10834 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10835 AOP(right)->aopu.aop_dir,
10836 AOP(right)->aopu.aop_dir);
10837 pic16_aopPut(AOP(result),"c",0);
10841 /* we need to or */
10842 if (AOP_TYPE(right) == AOP_REG) {
10843 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10844 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10845 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10847 pic16_toBoolean(right);
10848 pic16_aopPut(AOP(result),"a",0);
10852 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10855 size = AOP_SIZE(result);
10857 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10859 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10860 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10861 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10864 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10869 /* if they are the same size : or less */
10870 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10872 /* if they are in the same place */
10873 if (pic16_sameRegs(AOP(right),AOP(result)))
10876 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10878 if (IS_PTR_CONST(rtype))
10880 if (IS_CODEPTR(rtype))
10882 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10885 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10887 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10889 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10892 if(AOP_TYPE(right) == AOP_IMMD) {
10893 pCodeOp *pcop0, *pcop1, *pcop2;
10894 symbol *sym = OP_SYMBOL( right );
10896 size = AOP_SIZE(result);
10898 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10900 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10902 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10905 pic16_emitpcode(POC_MOVLW, pcop0);
10906 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10907 pic16_emitpcode(POC_MOVLW, pcop1);
10908 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10909 pic16_emitpcode(POC_MOVLW, pcop2);
10910 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10913 pic16_emitpcode(POC_MOVLW, pcop0);
10914 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10915 pic16_emitpcode(POC_MOVLW, pcop1);
10916 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10918 pic16_emitpcode(POC_MOVLW, pcop0);
10919 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10923 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10924 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10925 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10926 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10927 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10928 if(AOP_SIZE(result) <2)
10929 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10931 /* if they in different places then copy */
10932 size = AOP_SIZE(result);
10935 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10936 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10943 /* if the result is of type pointer */
10944 if (IS_PTR(ctype)) {
10946 sym_link *type = operandType(right);
10947 sym_link *etype = getSpec(type);
10949 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10951 /* pointer to generic pointer */
10952 if (IS_GENPTR(ctype)) {
10956 p_type = DCL_TYPE(type);
10958 /* we have to go by the storage class */
10959 p_type = PTR_TYPE(SPEC_OCLS(etype));
10961 /* if (SPEC_OCLS(etype)->codesp ) */
10962 /* p_type = CPOINTER ; */
10964 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10965 /* p_type = FPOINTER ; */
10967 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10968 /* p_type = PPOINTER; */
10970 /* if (SPEC_OCLS(etype) == idata ) */
10971 /* p_type = IPOINTER ; */
10973 /* p_type = POINTER ; */
10976 /* the first two bytes are known */
10977 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10978 size = GPTRSIZE - 1;
10981 if(offset < AOP_SIZE(right)) {
10982 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10983 if ((AOP_TYPE(right) == AOP_PCODE) &&
10984 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10985 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10986 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10988 pic16_aopPut(AOP(result),
10989 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10993 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10996 /* the last byte depending on type */
11000 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
11003 pic16_emitcode(";BUG!? ","%d",__LINE__);
11007 pic16_emitcode(";BUG!? ","%d",__LINE__);
11011 pic16_emitcode(";BUG!? ","%d",__LINE__);
11016 /* this should never happen */
11017 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11018 "got unknown pointer type");
11021 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
11025 /* just copy the pointers */
11026 size = AOP_SIZE(result);
11029 pic16_aopPut(AOP(result),
11030 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
11039 /* so we now know that the size of destination is greater
11040 than the size of the source.
11041 Now, if the next iCode is an operator then we might be
11042 able to optimize the operation without performing a cast.
11044 if(genMixedOperation(ic))
11047 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
11049 /* we move to result for the size of source */
11050 size = AOP_SIZE(right);
11053 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
11054 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
11058 /* now depending on the sign of the destination */
11059 size = AOP_SIZE(result) - AOP_SIZE(right);
11060 /* if unsigned or not an integral type */
11061 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
11063 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
11065 /* we need to extend the sign :( */
11068 /* Save one instruction of casting char to int */
11069 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
11070 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
11071 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
11073 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
11076 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
11078 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
11080 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
11083 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
11088 pic16_freeAsmop(right,NULL,ic,TRUE);
11089 pic16_freeAsmop(result,NULL,ic,TRUE);
11093 /*-----------------------------------------------------------------*/
11094 /* genDjnz - generate decrement & jump if not zero instrucion */
11095 /*-----------------------------------------------------------------*/
11096 static int genDjnz (iCode *ic, iCode *ifx)
11098 symbol *lbl, *lbl1;
11099 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11104 /* if the if condition has a false label
11105 then we cannot save */
11109 /* if the minus is not of the form
11111 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
11112 !IS_OP_LITERAL(IC_RIGHT(ic)))
11115 if (operandLitValue(IC_RIGHT(ic)) != 1)
11118 /* if the size of this greater than one then no
11120 if (getSize(operandType(IC_RESULT(ic))) > 1)
11123 /* otherwise we can save BIG */
11124 lbl = newiTempLabel(NULL);
11125 lbl1= newiTempLabel(NULL);
11127 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11129 if (IS_AOP_PREG(IC_RESULT(ic))) {
11130 pic16_emitcode("dec","%s",
11131 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11132 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11133 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
11137 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
11138 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
11140 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11141 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
11144 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
11145 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
11146 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
11147 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
11150 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11151 ifx->generated = 1;
11155 /*-----------------------------------------------------------------*/
11156 /* genReceive - generate code for a receive iCode */
11157 /*-----------------------------------------------------------------*/
11158 static void genReceive (iCode *ic)
11160 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11162 if (isOperandInFarSpace(IC_RESULT(ic)) &&
11163 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
11164 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
11166 int size = getSize(operandType(IC_RESULT(ic)));
11167 int offset = pic16_fReturnSizePic - size;
11170 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
11171 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
11175 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
11177 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11178 size = AOP_SIZE(IC_RESULT(ic));
11181 pic16_emitcode ("pop","acc");
11182 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
11185 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
11188 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11190 assignResultValue(IC_RESULT(ic), 0);
11193 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11196 /*-----------------------------------------------------------------*/
11197 /* genDummyRead - generate code for dummy read of volatiles */
11198 /*-----------------------------------------------------------------*/
11200 genDummyRead (iCode * ic)
11202 pic16_emitcode ("; genDummyRead","");
11203 pic16_emitcode ("; not implemented","");
11208 /*-----------------------------------------------------------------*/
11209 /* genpic16Code - generate code for pic16 based controllers */
11210 /*-----------------------------------------------------------------*/
11212 * At this point, ralloc.c has gone through the iCode and attempted
11213 * to optimize in a way suitable for a PIC. Now we've got to generate
11214 * PIC instructions that correspond to the iCode.
11216 * Once the instructions are generated, we'll pass through both the
11217 * peep hole optimizer and the pCode optimizer.
11218 *-----------------------------------------------------------------*/
11220 void genpic16Code (iCode *lic)
11225 lineHead = lineCurr = NULL;
11227 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
11228 pic16_addpBlock(pb);
11231 /* if debug information required */
11232 if (options.debug && currFunc) {
11234 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
11239 for (ic = lic ; ic ; ic = ic->next ) {
11241 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
11242 if ( cln != ic->lineno ) {
11243 if ( options.debug ) {
11244 debugFile->writeCLine (ic);
11247 if(!options.noCcodeInAsm) {
11248 pic16_addpCode2pBlock(pb,
11249 pic16_newpCodeCSource(ic->lineno, ic->filename,
11250 printCLine(ic->filename, ic->lineno)));
11256 if(options.iCodeInAsm) {
11258 /* insert here code to print iCode as comment */
11259 l = Safe_strdup(printILine(ic));
11260 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
11263 /* if the result is marked as
11264 spilt and rematerializable or code for
11265 this has already been generated then
11267 if (resultRemat(ic) || ic->generated )
11270 /* depending on the operation */
11289 /* IPOP happens only when trying to restore a
11290 spilt live range, if there is an ifx statement
11291 following this pop then the if statement might
11292 be using some of the registers being popped which
11293 would destroy the contents of the register so
11294 we need to check for this condition and handle it */
11296 ic->next->op == IFX &&
11297 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
11298 genIfx (ic->next,ic);
11316 genEndFunction (ic);
11332 pic16_genPlus (ic) ;
11336 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
11337 pic16_genMinus (ic);
11353 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
11357 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
11364 /* note these two are xlated by algebraic equivalence
11365 during parsing SDCC.y */
11366 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11367 "got '>=' or '<=' shouldn't have come here");
11371 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
11383 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
11387 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
11391 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
11415 genRightShift (ic);
11418 case GET_VALUE_AT_ADDRESS:
11423 if (POINTER_SET(ic))
11450 addSet(&_G.sendSet,ic);
11453 case DUMMY_READ_VOLATILE:
11463 /* now we are ready to call the
11464 peep hole optimizer */
11465 if (!options.nopeep) {
11466 peepHole (&lineHead);
11468 /* now do the actual printing */
11469 printLine (lineHead,codeOutFile);
11472 DFPRINTF((stderr,"printing pBlock\n\n"));
11473 pic16_printpBlock(stdout,pb);