X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=c440625b188675eda49cb7f1e22664e784dad505;hb=3dd222a7b0e8c4766d750f87a073ff9ff1e8ba50;hp=2604eeac64a0e6ebc530154fc798da47ea19c94f;hpb=077f4999890c8bf8597265d6913e8b458ff4a59a;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 2604eeac..c440625b 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -1,4 +1,4 @@ -/*------------------------------------------------------------------------- + /*------------------------------------------------------------------------- gen.c - source file for code generation for pic16 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) @@ -135,6 +135,7 @@ static char *one = "#0x01"; char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" }; +int fReturnIdx[] = {IDX_WREG, IDX_PRODL, IDX_PRODH, IDX_FSR0L }; unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic16; @@ -154,22 +155,14 @@ static struct { set *sendSet; set *stackRegSet; int usefastretfie; - bitVect *fregsUsed; + bitVect *fregsUsed; /* registers used in function */ + bitVect *sregsAlloc; + set *sregsAllocSet; /* registers used to store stack variables */ int stack_lat; /* stack offset latency */ int resDirect; int useWreg; /* flag when WREG is used to pass function parameter */ } _G; -/* Resolved ifx structure. This structure stores information - about an iCode ifx that makes it easier to generate code. -*/ -typedef struct resolvedIfx { - symbol *lbl; /* pointer to a label */ - int condition; /* true or false ifx */ - int generated; /* set true when the code associated with the ifx - * is generated */ -} resolvedIfx; - extern int pic16_ptrRegReq ; extern int pic16_nRegs; extern FILE *codeOutFile; @@ -683,26 +676,35 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) aop->size = getSize(sym->type); - DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__); - if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) ) - && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) { - pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) )); + DEBUGpic16_emitcode("; +++ ", "%s:%d\top = %s", __FILE__, __LINE__, pic16_decodeOp(ic->op)); + if((ic->op == '=' /*|| ic->op == CAST*/) && IC_RESULT(ic) && AOP( IC_RESULT(ic) ) + && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG)) { +// pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) )); for(i=0;isize;i++) aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx); _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */ } else + if(1 && ic->op == SEND) { + + /* if SEND do the send here */ + _G.resDirect = 1; + } else { for(i=0;isize;i++) { - aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 ); - _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx); + aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond(_G.fregsUsed, _G.sregsAlloc, 0 ); + _G.sregsAlloc = bitVectSetBit(_G.sregsAlloc, PCOR(pcop[i])->r->rIdx); } + } // fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size); #if 1 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack); - + + // we do not need to load the value if it is to be defined... + if (result) return aop; + if(_G.accInUse) { pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); } @@ -719,9 +721,17 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) assert (soffs < 0); soffs++; } // if - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/)); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p( - pic16_popCopyReg( pic16_frame_plusw ), pcop[i])); + + if(1 && ic->op == SEND) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + aop->size - i - 1 /*+ _G.stack_lat*/)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg( pic16_frame_plusw ), + pic16_popCopyReg(pic16_stack_postdec ))); + } else { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg( pic16_frame_plusw ), pcop[i])); + } } } @@ -797,7 +807,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } #endif -#if 0 +#if 1 /* special case for a function */ if (IS_FUNC(sym->type)) { sym->aop = aop = newAsmop(AOP_PCODE); @@ -869,8 +879,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) aop->size = PTRSIZE; else if(IN_CODESPACE( space ) || IN_FARSPACE( space )) aop->size = FPTRSIZE; - else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) ); - else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) ); + else if(IC_LEFT(ic) && AOP(IC_LEFT(ic))) aop->size = AOP_SIZE( IC_LEFT(ic) ); + else if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic))) aop->size = AOP_SIZE( IC_RIGHT(ic) ); else if(sym->onStack) { aop->size = PTRSIZE; } else { @@ -1193,7 +1203,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) b) has a spill location */ if (sym->isspilt || sym->nRegs == 0) { -// debugf2("%s:%d symbol %s\tisspilt: %d\tnRegs: %d\n", sym->isspilt, sym->nRegs); +// debugf3("symbol %s\tisspilt: %d\tnRegs: %d\n", sym->rname, sym->isspilt, sym->nRegs); DEBUGpic16_emitcode(";","%d",__LINE__); /* rematerialize it NOW */ if (sym->remat) { @@ -1220,7 +1230,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) #endif #if 1 - if (sym->ruonly ) { + if (sym->ruonly) { /* sym->aop = op->aop = aop = newAsmop(AOP_PCODE); aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset); @@ -1230,10 +1240,10 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) unsigned i; - aop = op->aop = sym->aop = newAsmop(AOP_STR); + aop = op->aop = sym->aop = newAsmop(AOP_REG); aop->size = getSize(sym->type); for ( i = 0 ; i < pic16_fReturnSizePic ; i++ ) - aop->aopu.aop_str[i] = fReturn[i]; + aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r; DEBUGpic16_emitcode(";","%d",__LINE__); return; @@ -1262,7 +1272,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK!\n", __FUNCTION__, __LINE__); DEBUGpic16_emitcode (";","%s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__); assert (getSize(sym->type) <= 1); - aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);//pic16_popRegFromString("_WREG", getSize(sym->type), 0, op); + aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg); } aop->size = getSize(sym->type); @@ -1373,8 +1383,13 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) } if(!_G.resDirect) { - for(i=0;isize;i++) + for(i=0;isize;i++) { PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1; + + if(bitVectBitValue(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx)) + bitVectUnSetBit(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx); + } + } _G.resDirect = 0; } @@ -1547,9 +1562,14 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_STR: aop->coff = offset ; - if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && - dname) - return "acc"; + +// if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && +// dname) +// return "acc"; + if(!strcmp(aop->aopu.aop_str[offset], "WREG")) { + aop->type = AOP_ACC; + return Safe_strdup("WREG"); + } DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]); return aop->aopu.aop_str[offset]; @@ -1653,13 +1673,15 @@ pCodeOp *pic16_popGetTempReg(int lock) } /*-----------------------------------------------------------------*/ -/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */ -/* don't save if inside v */ +/* pic16_popGetTempRegCond - create a new temporary pCodeOp which */ +/* is not part of f, but don't save if */ +/* inside v */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock) +pCodeOp *pic16_popGetTempRegCond(bitVect *f, bitVect *v, int lock) { - pCodeOp *pcop; + pCodeOp *pcop=NULL; symbol *cfunc; + int i; // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1672,15 +1694,58 @@ pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock) cfunc = currFunc; currFunc = NULL; - pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; + i = bitVectFirstBit(f); + while(i < 128) { - if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) { - /* push value on stack */ - pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + /* bypass registers that are used by function */ + if(!bitVectBitValue(f, i)) { + + /* bypass registers that are already allocated for stack access */ + if(!bitVectBitValue(v, i)) { + +// debugf("getting register rIdx = %d\n", i); + /* ok, get the operand */ + pcop = pic16_newpCodeOpReg( i ); + + /* should never by NULL */ + assert( pcop != NULL ); + + + /* sanity check */ + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + int found=0; + + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + + { + regs *sr; + + for(sr=setFirstItem(_G.sregsAllocSet);sr;sr=setNextItem(_G.sregsAllocSet)) { + + if(sr->rIdx == PCOR(pcop)->r->rIdx) { + /* already used in previous steps, break */ + found=1; + break; + } + } + } + + /* caller takes care of the following */ +// bitVectSetBit(v, i); + + if(!found) { + /* push value on stack */ + pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + addSet(&_G.sregsAllocSet, PCOR(pcop)->r); + } + + break; + } + } } + i++; } currFunc = cfunc; @@ -1700,6 +1765,7 @@ void pic16_popReleaseTempReg(pCodeOp *pcop, int lock) if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { PCOR(pcop)->r->isFree = 1; + pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) ); } } @@ -1725,17 +1791,20 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc) pCodeOpReg *pcor; pcor = Safe_calloc(1,sizeof(pCodeOpReg) ); - pcor->pcop.type = pc->pcop.type; + memcpy (pcor, pc, sizeof (pCodeOpReg)); + pcor->r->wasUsed = 1; + + //pcor->pcop.type = pc->pcop.type; if(pc->pcop.name) { if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name))) fprintf(stderr,"oops %s %d",__FILE__,__LINE__); } else pcor->pcop.name = NULL; - pcor->r = pc->r; - pcor->rIdx = pc->rIdx; - pcor->r->wasUsed=1; - pcor->instance = pc->instance; + //pcor->r = pc->r; + //pcor->rIdx = pc->rIdx; + //pcor->r->wasUsed=1; + //pcor->instance = pc->instance; // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); @@ -2011,7 +2080,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) PCOR(pcop)->instance = offset; pcop->type = PCOR(pcop)->r->pc_type; - DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s\n", __LINE__, dumpPicOptype(pcop->type)); + DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s", __LINE__, dumpPicOptype(pcop->type)); rs = aop->aopu.aop_reg[offset]->name; DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs); return pcop; @@ -2053,7 +2122,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) switch( aop->aopu.pcop->type ) { case PO_DIR: PCOR(pcop)->instance += offset; break; case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break; - case PO_WREG: assert (offset==0); break; + case PO_WREG: + assert (offset==0); + break; default: fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type); assert( 0 ); /* should never reach here */; @@ -2336,7 +2407,7 @@ static void mov2fp(pCodeOp *dst, asmop *src, int offset) void pic16_testStackOverflow(void) { -#define GSTACK_TEST_NAME "__gstack_test" +#define GSTACK_TEST_NAME "_gstack_test" pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME )); @@ -2344,7 +2415,8 @@ void pic16_testStackOverflow(void) symbol *sym; sym = newSymbol( GSTACK_TEST_NAME , 0 ); - strcpy(sym->rname, GSTACK_TEST_NAME); + sprintf(sym->rname, "%s%s", port->fun_prefix, GSTACK_TEST_NAME); +// strcpy(sym->rname, GSTACK_TEST_NAME); checkAddSym(&externs, sym); } @@ -2375,7 +2447,7 @@ void pic16_poppCodeOp(pCodeOp *pcop) void pushw(void) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2390,10 +2462,10 @@ void pushaop(asmop *aop, int offset) if(is_LitAOp(aop)) { pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); } else { pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1))); + pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec ))); } if(pic16_options.gstack) @@ -3306,7 +3378,9 @@ static void genCall (iCode *ic) // pushaop(AOP(IC_LEFT(sic)), size); pic16_mov2w (AOP(IC_LEFT(sic)), size); - pushw(); + + if(!_G.resDirect) + pushw(); } } @@ -3581,46 +3655,32 @@ static void genFunction (iCode *ic) char asymname[128]; pBlock *apb; - // debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type)); -#if 0 - { - int i, found=-1; - - sym = OP_SYMBOL( IC_LEFT(ic)); - for(i=0;i<=2;i++) { - if(interrupts[i]->name - && !STRCASECMP(interrupts[i]->name, sym->name)) { - found = i; - break; - } - } - - if(found == -1) { - fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", - __FILE__, __LINE__, sym->name); -// assert( 0 ); - } - _G.interruptvector = found; - } -#endif - - if(FUNC_INTNO(sym->type) == 256) + if(FUNC_INTNO(sym->type) == INTNO_UNSPEC) sprintf(asymname, "ivec_%s", sym->name); else sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name); - asym = newSymbol(asymname, 0); - - apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); - pic16_addpBlock( apb ); - - pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------")); - pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); - pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname ))); + + /* when an interrupt is declared as naked, do not emit the special + * wrapper segment at vector address. The user should take care for + * this instead. -- VR */ + + if(!IFFUNC_ISNAKED(ftype) && (FUNC_INTNO(sym->type) != INTNO_UNSPEC)) { + asym = newSymbol(asymname, 0); + apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); + pic16_addpBlock( apb ); + + pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------")); + pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); + //pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname ))); + pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_newpCodeOpLabel (sym->rname, 0))); - /* mark the end of this tiny function */ - pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL)); + /* mark the end of this tiny function */ + pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL)); + } else { + sprintf(asymname, "%s", sym->rname); + } { absSym *abSym; @@ -3634,6 +3694,7 @@ static void genFunction (iCode *ic) case 2: abSym->address = 0x000018; break; default: +// fprintf(stderr, "no interrupt number is given\n"); abSym->address = -1; break; } @@ -3653,7 +3714,6 @@ static void genFunction (iCode *ic) pic16_emitcode("","%s:",sym->rname); pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname)); - { absSym *ab; @@ -3665,7 +3725,6 @@ static void genFunction (iCode *ic) } } - if(IFFUNC_ISNAKED(ftype)) { DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); return; @@ -3676,7 +3735,10 @@ static void genFunction (iCode *ic) //pic16_emitcode("clr","ea"); } + currFunc = sym; /* update the currFunc symbol */ _G.fregsUsed = sym->regsUsed; + _G.sregsAlloc = newBitVect(128); + /* if this is an interrupt service routine then * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */ @@ -3701,15 +3763,19 @@ static void genFunction (iCode *ic) pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h )); // pic16_pBlockConvert2ISR(pb); - } /* emit code to setup stack frame if user enabled, * and function is not main() */ - - //fprintf(stderr, "function name: %s\n", sym->name); + +// debugf(stderr, "function name: %s ARGS=%p\n", sym->name, FUNC_ARGS(sym->type)); if(strcmp(sym->name, "main")) { - if(1 /*!options.ommitFramePtr || sym->regsUsed*/) { + if(0 + || !options.ommitFramePtr +// || sym->regsUsed + || IFFUNC_ARGS(sym->type) + || FUNC_HASSTACKPARM(sym->etype) + ) { /* setup the stack frame */ if(STACK_MODEL_LARGE) pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi)); @@ -3798,6 +3864,17 @@ static void genEndFunction (iCode *ic) /* now we need to restore the registers */ /* if any registers used */ + + /* first restore registers that might be used for stack access */ + if(_G.sregsAllocSet) { + regs *sr; + + _G.sregsAllocSet = reverseSet( _G.sregsAllocSet ); + for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setNextItem(_G.sregsAllocSet)) { + pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) ); + } + } + if (sym->regsUsed) { int i; @@ -3811,9 +3888,10 @@ static void genEndFunction (iCode *ic) } } pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END)); - } + + if ((IFFUNC_ISREENT(sym->type) || options.stackAuto) && sym->stack) { if (sym->stack == 1) { @@ -3832,7 +3910,12 @@ static void genEndFunction (iCode *ic) } if(strcmp(sym->name, "main")) { - if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) { + if(0 + || !options.ommitFramePtr +// || sym->regsUsed + || IFFUNC_ARGS(sym->type) + || FUNC_HASSTACKPARM(sym->etype) + ) { /* restore stack frame */ if(STACK_MODEL_LARGE) pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi )); @@ -3895,19 +3978,39 @@ static void genEndFunction (iCode *ic) } -void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest) +void pic16_storeForReturn(iCode *ic, /*operand *op,*/ int offset, pCodeOp *dest) { - if(is_LitOp(op)) { - unsigned long lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit); - if(lit == 0) { + unsigned long lit=1; + operand *op; + + op = IC_LEFT(ic); + + // this fails for is_LitOp(op) (if op is an AOP_PCODE) + if(AOP_TYPE(op) == AOP_LIT) { + if(!IS_FLOAT(operandType( op ))) { + lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit); + } else { + union { + unsigned long lit_int; + float lit_float; + } info; + + /* take care if literal is a float */ + info.lit_float = floatFromVal(AOP(op)->aopu.aop_lit); + lit = info.lit_int; + } + } + + if(is_LitOp(op)) { + if(/*(OP_LIVETO(op) <= ic->seq) &&*/ (lit == 0)) { pic16_emitpcode(POC_CLRF, dest); } else { pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest); } - } else { - if(dest->type == PO_WREG && (offset == 0)) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); + } else { + if(dest->type == PO_WREG && (offset == 0)) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); return; } pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest)); @@ -3935,27 +4038,16 @@ static void genRet (iCode *ic) size = AOP_SIZE(IC_LEFT(ic)); if(size <= 4) { - if(size>3) { - pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l)); -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l))); - } - if(size>2) { - pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh)); -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh))); - } - if(size>1) { - pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl)); -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl))); - } - -// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12 + if(size>3) + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 3, pic16_popCopyReg(&pic16_pc_fsr0l)); + + if(size>2) + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 2, pic16_popCopyReg(&pic16_pc_prodh)); - pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12 -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg))); + if(size>1) + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 1, pic16_popCopyReg(&pic16_pc_prodl)); + + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 0, pic16_popCopyReg(&pic16_pc_wreg)); } else { /* >32-bits, setup stack and FSR0 */ @@ -4752,9 +4844,9 @@ static void genSkipc(resolvedIfx *rifx) return; if(rifx->condition) - emitSKPC; - else emitSKPNC; + else + emitSKPC; pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key)); rifx->generated = 1; @@ -4857,11 +4949,6 @@ static int genChkZeroes(operand *op, int lit, int size) } #endif -#if !defined(__BORLANDC__) && !defined(_MSC_VER) -#define DEBUGpc(fmt,...) DEBUGpic16_emitcode("; =:=", "%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) -#endif -#define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT) -#define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE || AOP_TYPE(x) == AOP_STA) /*-----------------------------------------------------------------*/ /* mov2w_regOrLit :- move to WREG either the offset's byte from */ @@ -4880,7 +4967,7 @@ void mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) { /* genCmp :- greater or less than comparison */ /*-----------------------------------------------------------------*/ -#if USE_SIMPLE_GENCMP +#if USE_SIMPLE_GENCMP /* { */ /* genCmp performs a left < right comparison, stores * the outcome in result (if != NULL) and generates @@ -4916,6 +5003,10 @@ static void genCmp (operand *left,operand *right, resolveIfx (&rIfx, ifx); + /* handle for special cases */ + if(pic16_genCmp_special(left, right, result, ifx, &rIfx, sign)) + return; + /********************************************************************** * handle bits - bit compares are promoted to int compares seemingly! * **********************************************************************/ @@ -4942,9 +5033,7 @@ static void genCmp (operand *left,operand *right, * make sure that left is register (or the like) * *************************************************/ if (!isAOP_REGlike(left)) { - #if !defined(__BORLANDC__) && !defined(_MSC_VER) DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right)); - #endif assert (isAOP_LIT(left)); assert (isAOP_REGlike(right)); // swap left and right @@ -4958,7 +5047,7 @@ static void genCmp (operand *left,operand *right, } // if // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed), - // that's we handled it above. + // that's why we handled it above. lit++; dummy = left; @@ -4980,9 +5069,7 @@ static void genCmp (operand *left,operand *right, if (isAOP_LIT(right)) { if (!sign) { // unsigned comparison to a literal - #if !defined(__BORLANDC__) && !defined(_MSC_VER) DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1); - #endif if (lit == 0) { // unsigned left < 0? always false if (performedLt) emitCLRC; else emitSETC; @@ -4990,9 +5077,7 @@ static void genCmp (operand *left,operand *right, } } else { // signed comparison to a literal - #if !defined(__BORLANDC__) && !defined(_MSC_VER) DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask); - #endif if ((lit & mask) == ((0x80 << (size*8)) & mask)) { // signed left < 0x80000000? always false if (performedLt) emitCLRC; else emitSETC; @@ -5066,7 +5151,7 @@ result_in_carry: * now CARRY contains the result of the comparison: * * SUBWF sets CARRY iff * * F-W >= 0 <==> F >= W <==> !(F < W) * - * (F=left, W=right) + * (F=left, W=right) * ****************************************************/ if (performedLt) { @@ -5092,16 +5177,14 @@ correct_result_in_carry: } // if (result) // perform conditional jump - // genSkipc branches to rifx->label if (rifx->condition != CARRY) if (ifx) { //DEBUGpc ("generate control flow"); - rIfx.condition ^= 1; genSkipc (&rIfx); ifx->generated = 1; } // if } -#elif 1 +#elif 1 /* } */ /* { */ /* original code */ static void genCmp (operand *left,operand *right, @@ -5824,7 +5907,7 @@ check_carry: } -#else /* old version of genCmp() */ /* } else { */ +#elif 0 /* VR version of genCmp() */ /* } else { */ /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */ static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx, @@ -5934,10 +6017,6 @@ static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl, } } - - - -#if 1 /* { */ static void genCmp (operand *left, operand *right, operand *result, iCode *ifx, int sign) { @@ -6089,7 +6168,6 @@ static void genCmp (operand *left, operand *right, } } else { - /* unsigned compare */ DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); @@ -6100,10 +6178,8 @@ static void genCmp (operand *left, operand *right, compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); } - if(ifx)ifx->generated = 1; - if(AOP_SIZE(result)) { pic16_emitpLabel(falselbl->key); pic16_outBitC( result ); @@ -6137,513 +6213,56 @@ static void genCmp (operand *left, operand *right, // pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - /* WREG already holds left + 0x80 */ - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); - - while( size-- ) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size)); -// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - pic16_emitpcode(POC_MOVWF, pct); - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); -// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - - /* WREG already holds left + 0x80 */ - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); -// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl); - } - - if(ifx)ifx->generated = 1; - - if(AOP_SIZE(result)) { - pic16_emitpLabel(tlbl->key); - pic16_emitpLabel(falselbl->key); - pic16_outBitOp( result, pct2 ); - } else { - pic16_emitpLabel(tlbl->key); - } - - } else { - /* unsigned compare */ - DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); - - compareAopfirstpass=1; - while(size--) { - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); - - } - - if(ifx)ifx->generated = 1; - if(AOP_SIZE(result)) { - - pic16_emitpLabel(falselbl->key); - pic16_outBitC( result ); - } - - } - } -} - -#else /* } else { */ - -/* new version of genCmp -- VR 20041012 */ -static void genCmp (operand *left,operand *right, - operand *result, iCode *ifx, int sign) -{ - int size; //, offset = 0 ; - unsigned long lit = 0L,i = 0; - resolvedIfx rFalseIfx; - int willCheckCarry=0; - // resolvedIfx rTrueIfx; - symbol *truelbl; - - FENTRY; - - /* General concept: - * subtract right from left if at the end the carry flag is set then we - * know that left is greater than right */ - - resolveIfx(&rFalseIfx,ifx); - truelbl = newiTempLabel(NULL); - size = max(AOP_SIZE(left),AOP_SIZE(right)); - - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); - - /* POC_CPFSGT compare f, wreg, skip if f greater than wreg - * POC_CPFSLT compare f, wreg, skip if f less then wreg */ - - - /* if literal is on the right then swap with left */ - if ((AOP_TYPE(right) == AOP_LIT)) { - operand *tmp = right ; - unsigned long mask = (0x100 << (8*(size-1))) - 1; - - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - -// lit = (lit - 1) & mask; - right = left; - left = tmp; - rFalseIfx.condition ^= 1; /* reverse compare */ - } else - if ((AOP_TYPE(left) == AOP_LIT)) { - /* float compares are handled by support functions */ - lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit); - } - - - //if(IC_TRUE(ifx) == NULL) - /* if left & right are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - - pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); - - } else { - symbol *lbl = newiTempLabel(NULL); - - if(AOP_TYPE(left) == AOP_LIT) { - DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign); - - if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) - willCheckCarry = 1; - else willCheckCarry = 0; - - /* Special cases */ - if((lit == 0) && (sign == 0)) { - /* unsigned compare to 0 */ - DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign); - - size--; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size)); - - genSkipz2(&rFalseIfx,0); - if(ifx)ifx->generated = 1; - return; - } - - if(size==1) { - /* Special cases */ - lit &= 0xff; - if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) { - /* degenerate compare can never be true */ - if(rFalseIfx.condition == 0) - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key)); - - if(ifx) ifx->generated = 1; - return; - } - - if(sign) { - /* signed comparisons to a literal byte */ - DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign); - - int lp1 = (lit+1) & 0xff; - - DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1); - switch (lp1) { - case 0: - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,0,7); - break; - case 0x7f: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f)); - genSkipz2(&rFalseIfx,1); - break; - default: - pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit )); - - if(rFalseIfx.condition) - pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0)); - else - pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0)); - - if(willCheckCarry) { - if(!rFalseIfx.condition) { emitCLRC; emitSETC; } - else { emitSETC; emitCLRC; } - - } else { - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - } - -/* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); -*/ - break; - } - } else { - /* unsigned comparisons to a literal byte */ - DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign); - - switch(lit & 0xff ) { - /* special cases */ - case 0: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - genSkipz2(&rFalseIfx,0); - break; - case 0x7f: - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,0,7); - break; - default: - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0)); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rFalseIfx.condition ^= 1; - if (AOP_TYPE(result) == AOP_CRY) - genSkipc(&rFalseIfx); - else { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); - } - break; - } - } - - if(ifx) ifx->generated = 1; - if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) - goto check_carry; - return; - - } else { - - /* Size is greater than 1 */ - - if(sign) { - int lp1 = lit+1; - - size--; - - if(lp1 == 0) { - /* this means lit = 0xffffffff, or -1 */ - - - DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__); - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,size,7); - if(ifx) ifx->generated = 1; - return; - } - - if(lit == 0) { - int s = size; - - if(rFalseIfx.condition) { - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - } - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(size--) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - - - emitSKPZ; - if(rFalseIfx.condition) { - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - pic16_emitpLabel(truelbl->key); - }else { - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,s,7); - } - - if(ifx) ifx->generated = 1; - return; - } - - if((size == 1) && (0 == (lp1&0xff))) { - /* lower byte of signed word is zero */ - DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit); - i = ((lp1 >> 8) & 0xff) ^0x80; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - - - if(ifx) ifx->generated = 1; - return; - } - - if(lit & (0x80 << (size*8))) { - /* Lit is less than zero */ - DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - - if(rFalseIfx.condition) - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - else - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - - - } else { - /* Lit is greater than or equal to zero */ - DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,right,size,7); - //rFalseIfx.condition ^= 1; - - //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0)); - //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - if(rFalseIfx.condition) - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - else - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - - } - - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - - while(size--) { - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff)); - emitSKPNZ; - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - } - rFalseIfx.condition ^= 1; - //rFalseIfx.condition = 1; - genSkipc(&rFalseIfx); - - pic16_emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - // end of if (sign) - } else { - - /* compare word or long to an unsigned literal on the right.*/ - - - size--; - if(lit < 0xff) { - DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit); - switch (lit) { - case 0: - break; /* handled above */ -/* - case 0xff: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(size--) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - genSkipz2(&rFalseIfx,0); - break; -*/ - default: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(--size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - - emitSKPZ; - if(rFalseIfx.condition) - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - else - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0)); - - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - } - - pic16_emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - } - - - lit++; - DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit); - i = (lit >> (size*8)) & 0xff; - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - - while(size--) { - i = (lit >> (size*8)) & 0xff; - - if(i) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); - emitSKPNZ; - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - } else { - /* this byte of the lit is zero, - * if it's not the last then OR in the variable */ - if(size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - } - } - - - pic16_emitpLabel(lbl->key); - - rFalseIfx.condition ^= 1; - - genSkipc(&rFalseIfx); - } - - if(sign) - pic16_emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; - } - } - /* Compare two variables */ - - DEBUGpic16_emitcode(";sign","%d",sign); - - size--; - if(sign) { - /* Sigh. thus sucks... */ - if(size) { - pCodeOp *pctemp; - - pctemp = pic16_popGetTempReg(1); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size)); - pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); - pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); - pic16_popReleaseTempReg(pctemp, 1); - } else { - /* Signed char comparison */ - /* Special thanks to Nikolai Golovchenko for this snippet */ - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */ - pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - genSkipc(&rFalseIfx); - - if(ifx) ifx->generated = 1; - return; - } - - } else { - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); - } - - - /* The rest of the bytes of a multi-byte compare */ - while (size) { - - emitSKPZ; - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key)); - size--; - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); - - - } + /* WREG already holds left + 0x80 */ + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); + + while( size-- ) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size)); +// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); + pic16_emitpcode(POC_MOVWF, pct); + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); +// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - pic16_emitpLabel(lbl->key); + /* WREG already holds left + 0x80 */ + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); +// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl); + } + + if(ifx)ifx->generated = 1; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || - (AOP_TYPE(result) == AOP_REG)) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); - } else { - genSkipc(&rFalseIfx); - } - //genSkipc(&rFalseIfx); - if(ifx) ifx->generated = 1; + if(AOP_SIZE(result)) { + pic16_emitpLabel(tlbl->key); + pic16_emitpLabel(falselbl->key); + pic16_outBitOp( result, pct2 ); + } else { + pic16_emitpLabel(tlbl->key); + } - return; + } else { + /* unsigned compare */ + DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); - } + compareAopfirstpass=1; + while(size--) { + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); -check_carry: - if ((AOP_TYPE(result) != AOP_CRY) - && AOP_SIZE(result)) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + } - if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key ); + if(ifx)ifx->generated = 1; + if(AOP_SIZE(result)) { - pic16_outBitC(result); - } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if the result is used in the next - ifx conditional branch then generate - code a little differently */ - if (ifx ) - genIfxJump (ifx,"c"); - else - pic16_outBitC(result); - /* leave the result in acc */ - } + pic16_emitpLabel(falselbl->key); + pic16_outBitC( result ); + } + } + } } -#endif /* } */ - #endif /* } */ @@ -7057,6 +6676,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) int preserve_result = 0; int generate_result = 0; int i=0; + unsigned long lit = -1; FENTRY; @@ -7081,6 +6701,10 @@ static void genCmpEq (iCode *ic, iCode *ifx) left = tmp; } + if (AOP_TYPE(right) == AOP_LIT) { + lit = (unsigned long) floatFromVal (AOP(right)->aopu.aop_lit); + } + if ( regsInCommon(left, result) || regsInCommon(right, result) ) preserve_result = 1; @@ -7102,9 +6726,11 @@ static void genCmpEq (iCode *ic, iCode *ifx) else pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i)); } - if(is_LitOp(right)) - pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i)); - else + if(is_LitOp(right)) { + if (is_LitOp(left) || (0 != ((lit >> (8*i))&0x00FF))) { + pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i)); + } + } else pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i)); pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key)); @@ -7571,7 +7197,7 @@ static void genAndOp (iCode *ic) only those used in arthmetic operations remain */ pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE); + pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); DEBUGpic16_pic16_AopType(__LINE__,left,right,result); @@ -7620,7 +7246,7 @@ static void genOrOp (iCode *ic) only those used in arthmetic operations remain */ pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE); + pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); DEBUGpic16_pic16_AopType(__LINE__,left,right,result); @@ -8601,6 +8227,7 @@ static void genXor (iCode *ic, iCode *ifx) static void genInline (iCode *ic) { char *buffer, *bp, *bp1; + char *cbuf; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -8608,8 +8235,66 @@ static void genInline (iCode *ic) buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy(buffer,IC_INLINE(ic)); + + while((bp1=strstr(bp, "\\n"))) { + *bp1++ = '\n'; + *bp1++ = ' '; + bp = bp1; + } + bp = bp1 = buffer; -// fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer); + cbuf = Safe_strdup( buffer ); + + if(asmInlineMap) + { + symbol *sym; + char *s; + int cblen; + + cbuf = Safe_strdup(buffer); + cblen = strlen(buffer)+1; + memset(cbuf, 0, cblen); + + bp = buffer; + bp1 = cbuf; + while(*bp) { + if(*bp != '%')*bp1++ = *bp++; + else { + int i; + + bp++; + i = *bp - '0'; + if(i>elementsInSet(asmInlineMap))break; + + bp++; + s = indexSet(asmInlineMap, i); + DEBUGpc("searching symbol s = `%s'", s); + sym = findSym(SymbolTab, NULL, s); + + if(sym->reqv) { + strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name); + } else { + strcat(bp1, sym->rname); + } + + while(*bp1)bp1++; + } + + if(strlen(bp1) > cblen - 16) { + int i = strlen(cbuf); + cblen += 50; + cbuf = realloc(cbuf, cblen); + memset(cbuf+i, 0, 50); + bp1 = cbuf + i; + } + } + + free(buffer); + buffer = Safe_strdup( cbuf ); + free(cbuf); + + bp = bp1 = buffer; + } /* emit each line as a code */ while (*bp) { @@ -8657,7 +8342,7 @@ static void genRRC (iCode *ic) left = IC_LEFT(ic); result=IC_RESULT(ic); pic16_aopOp (left,ic,FALSE); - pic16_aopOp (result,ic,FALSE); + pic16_aopOp (result,ic,TRUE); DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); @@ -8702,7 +8387,7 @@ static void genRLC (iCode *ic) left = IC_LEFT(ic); result=IC_RESULT(ic); pic16_aopOp (left,ic,FALSE); - pic16_aopOp (result,ic,FALSE); + pic16_aopOp (result,ic,TRUE); DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); @@ -9737,7 +9422,7 @@ void pic16_genLeftShiftLiteral (operand *left, pic16_freeAsmop(right,NULL,ic,TRUE); pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,TRUE); size = getSize(operandType(result)); @@ -10345,7 +10030,7 @@ static void genRightShiftLiteral (operand *left, pic16_freeAsmop(right,NULL,ic,TRUE); pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,TRUE); DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left)); @@ -10360,8 +10045,10 @@ static void genRightShiftLiteral (operand *left, /* I suppose that the left size >= result size */ if(shCount == 0){ - while(res_size--) - movLeft2Result(left, lsize, result, res_size); + assert (res_size <= lsize); + while (res_size--) { + mov2f (AOP(result), AOP(left), res_size); + } // for } else if(shCount >= (lsize * 8)){ @@ -10693,7 +10380,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) { pic16_aopOp(right,ic,FALSE); pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,TRUE); sign = !SPEC_USIGN(operandType (left)); signedCount = !SPEC_USIGN(operandType (right)); @@ -10831,9 +10518,17 @@ static void genRightShift (iCode *ic) { #endif -void pic16_loadFSR0(operand *op) +/* load FSR0 with address of/from op according to is_LitOp() or if lit is 1 */ +void pic16_loadFSR0(operand *op, int lit) { - pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); + if(OP_SYMBOL(op)->remat || is_LitOp( op )) { + pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); + } else { + assert (!OP_SYMBOL(op)->remat); + // set up FSR0 with address of result + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),1), pic16_popCopyReg(&pic16_pc_fsr0h))); + } } /*-----------------------------------------------------------------*/ @@ -10866,11 +10561,13 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - if((ptype == POINTER) && (result)) { + // distinguish (p->bitfield) and p.bitfield, remat seems to work... + if(OP_SYMBOL(left)->remat && (ptype == POINTER) && (result)) { /* workaround to reduce the extra lfsr instruction */ pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr)); } else { + pic16_loadFSR0 (left, 0); pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); } @@ -10886,7 +10583,12 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp /* the following call to pic16_loadFSR0 is temporary until * optimization to handle single bit assignments is added * to the function. Until then use the old safe way! -- VR */ - pic16_loadFSR0( left ); + + if (OP_SYMBOL(left)->remat) { + // access symbol directly + pic16_mov2w (AOP(left), 0); + } else { + pic16_loadFSR0( left, 0 ); /* read the first byte */ switch (ptype) { @@ -10900,9 +10602,10 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp case CPOINTER: pic16_emitcode("clr","a"); pic16_emitcode("movc","a","@a+dptr"); + assert (0); break; } - + } /* if we have bitdisplacement then it fits */ /* into this byte completely or if length is */ @@ -10993,7 +10696,9 @@ static void genDataPointerGet(operand *left, int size, offset = 0, leoffset=0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(result, ic, FALSE); + pic16_aopOp(result, ic, TRUE); + + FENTRY; size = AOP_SIZE(result); // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); @@ -11045,8 +10750,8 @@ static void genDataPointerGet(operand *left, while (size--) { DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset); - if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE - || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) { +// pic16_DumpOp("(result)",result); + if(is_LitAOp(AOP(result))) { pic16_mov2w(AOP(left), offset); // patch 8 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); } else { @@ -11072,7 +10777,7 @@ static void genNearPointerGet (operand *left, operand *result, iCode *ic) { - asmop *aop = NULL; +// asmop *aop = NULL; //regs *preg = NULL ; sym_link *rtype, *retype; sym_link *ltype = operandType(left); @@ -11102,7 +10807,7 @@ static void genNearPointerGet (operand *left, } DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp (result,ic,FALSE); + pic16_aopOp (result,ic,TRUE); DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result); @@ -11128,6 +10833,7 @@ static void genNearPointerGet (operand *left, if((nextic->op == IFX) && (result == IC_COND(nextic)) && (OP_LIVETO(result) == nextic->seq) + && (OP_SYMBOL(left)->remat) // below fails for "if (p->bitfield)" ) { /* everything is ok then */ /* find a way to optimize the genIfx iCode */ @@ -11153,18 +10859,7 @@ static void genNearPointerGet (operand *left, /* otherwise get a free pointer register */ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* VR -- the whole concept is to load FSR0 with the address of the symbol */ - /* bitfields will be handled by genUnpackBits */ - if(!IS_BITFIELD(retype)) { - - if(is_LitAOp( AOP(left) )) { - pic16_loadFSR0( left ); - } else { - // set up FSR0 with address from left - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10 - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10 - } - } + ; } /* if bitfield then unpack the bits */ @@ -11177,11 +10872,8 @@ static void genNearPointerGet (operand *left, DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* fsr0 is loaded already -- VR */ -// pic16_loadFSR0( left ); + pic16_loadFSR0( left, 0 ); -// pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); -// pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); while(size--) { if(size) { pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), @@ -11191,29 +10883,9 @@ static void genNearPointerGet (operand *left, pic16_popGet(AOP(result), offset++))); } } -#if 0 -// pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0)); -// pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); - if(size) - pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0)); -#endif -/* - while (size--) { - if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { - - pic16_emitcode("mov","a,@%s",rname); - pic16_aopPut(AOP(result),"a",offset); - } else { - sprintf(buffer,"@%s",rname); - pic16_aopPut(AOP(result),buffer,offset); - } - offset++ ; - if (size) - pic16_emitcode("inc","%s",rname); - } -*/ } +#if 0 /* now some housekeeping stuff */ if (aop) { /* we had to allocate for this iCode */ @@ -11235,6 +10907,7 @@ static void genNearPointerGet (operand *left, // pic16_emitcode("dec","%s",rname); } } +#endif /* done */ pic16_freeAsmop(left,NULL,ic,TRUE); @@ -11274,7 +10947,7 @@ static void genPagedPointerGet (operand *left, rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); pic16_freeAsmop(left,NULL,ic,TRUE); - pic16_aopOp (result,ic,FALSE); + pic16_aopOp (result,ic,TRUE); /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) @@ -11352,7 +11025,7 @@ static void genFarPointerGet (operand *left, } /* so dptr know contains the address */ pic16_freeAsmop(left,NULL,ic,TRUE); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,TRUE); /* if bit then unpack */ if (IS_BITFIELD(retype)) @@ -11466,7 +11139,7 @@ static void genGenPointerGet (operand *left, // set up FSR0 with address from left pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); - + offset = 0 ; while(size--) { @@ -11500,11 +11173,10 @@ static void genGenPointerGet (operand *left, { int size, offset, lit; sym_link *retype = getSpec(operandType(result)); - char fgptrget[32]; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,TRUE); size = AOP_SIZE(result); DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); @@ -11536,30 +11208,10 @@ static void genGenPointerGet (operand *left, pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl))); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2)); - switch( size ) { - case 1: strcpy(fgptrget, "__gptrget1"); break; - case 2: strcpy(fgptrget, "__gptrget2"); break; - case 3: strcpy(fgptrget, "__gptrget3"); break; - case 4: strcpy(fgptrget, "__gptrget4"); break; - default: - werror(W_POSSBUG2, __FILE__, __LINE__); - abort(); - } - - pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget )); + pic16_callGenericPointerRW(0, size); assignResultValue(result, 1); - { - symbol *sym; - - sym = newSymbol( fgptrget, 0 ); - strcpy(sym->rname, fgptrget); - checkAddSym(&externs, sym); - -// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget); - } - goto release; } @@ -11727,7 +11379,6 @@ static void genPackBits (sym_link *etype , operand *result, int rLen = 0 ; int blen, bstr ; sym_link *retype; - char *l ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); blen = SPEC_BLEN(etype); @@ -11744,7 +11395,7 @@ static void genPackBits (sym_link *etype , operand *result, lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); - if((p_type == POINTER) && (result)) { + if(OP_SYMBOL(result)->remat && (p_type == POINTER) && (result)) { /* workaround to reduce the extra lfsr instruction */ if(lit) { pic16_emitpcode(POC_BSF, @@ -11754,7 +11405,7 @@ static void genPackBits (sym_link *etype , operand *result, pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); } } else { - pic16_loadFSR0( result ); + pic16_loadFSR0(result, 0); if(lit) { pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); @@ -11766,7 +11417,7 @@ static void genPackBits (sym_link *etype , operand *result, return; } - + /* move literal to W */ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); offset++; } else @@ -11797,80 +11448,143 @@ static void genPackBits (sym_link *etype , operand *result, pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0)); return; - } else + } else { + /* move right to W */ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); + } - /* if the bit lenth is less than or */ + /* if the bit length is less than or */ /* it exactly fits a byte then */ if((shCnt=SPEC_BSTR(etype)) || SPEC_BLEN(etype) <= 8 ) { - - pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); - - /* shift left acc */ - AccLsh(shCnt); - - /* using PRODL as a temporary register here */ - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); - - switch (p_type) { + int fsr0_setup = 0; + + if (blen != 8 || bstr != 0) { + // we need to combine the value with the old value + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); + + DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt, + SPEC_BSTR(etype), SPEC_BLEN(etype)); + + /* shift left acc */ + AccLsh(shCnt); + + /* using PRODH as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); + + if (OP_SYMBOL(result)->remat) { + // access symbol directly + pic16_mov2w (AOP(result), 0); + } else { + /* get old value */ + switch (p_type) { case FPOINTER: case POINTER: - pic16_loadFSR0( result ); + pic16_loadFSR0( result, 0 ); + fsr0_setup = 1; pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); // pic16_emitcode ("mov","b,a"); // pic16_emitcode("mov","a,@%s",rname); break; case GPOINTER: - werror(W_POSSBUG2, __FILE__, __LINE__); + if (AOP(result)->aopu.aop_reg[2]) { + // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?) + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2)); + + pic16_callGenericPointerRW(0, 1); + } else { + // data pointer (just 2 byte given) + pic16_loadFSR0( result, 0 ); + fsr0_setup = 1; + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + } + + // warnings will be emitted below + //pic16_emitpcomment ("; =?= genPackBits, GPOINTER..."); + //werror(W_POSSBUG2, __FILE__, __LINE__); break; - } + default: + assert (0 && "invalid pointer type specified"); + break; + } + } #if 1 - pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( (unsigned char)((unsigned char)(0xff << (blen+bstr)) | (unsigned char)(0xff >> (8-bstr))) )); - pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); + } // if (blen != 8 || bstr != 0) + + /* write new value back */ + if (OP_SYMBOL(result)->remat) { + pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0)); + } else { + switch (p_type) { + case FPOINTER: + case POINTER: + if (!fsr0_setup) pic16_loadFSR0( result, 0 ); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + break; + + case GPOINTER: + if (AOP(result)->aopu.aop_reg[2]) { + // prepare call to __gptrset1, this is actually genGenPointerSet(WREG, result, ?ic?) + pic16_emitpcode (POC_MOVWF, pic16_popCopyReg (pic16_stack_postdec/*pic16_pc_postdec1*/)); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2)); + + pic16_callGenericPointerRW(1, 1); + } else { + // data pointer (just 2 byte given) + if (!fsr0_setup) pic16_loadFSR0( result, 0 ); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + } + + // this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY) + //pic16_emitpcomment ("; =?= genPackBits, GPOINTER access"); + werror(W_POSSBUG2, __FILE__, __LINE__); + break; + + default: + assert (0 && "invalid pointer type specified"); + break; + } + } #endif return; } +#if 0 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); exit(-1); +#endif - /* if we r done */ - if ( SPEC_BLEN(etype) <= 8 ) - return ; - - pic16_emitcode("inc","%s",rname); - rLen = SPEC_BLEN(etype) ; - - - + pic16_loadFSR0(result, 0); // load FSR0 with address of result + rLen = SPEC_BLEN(etype)-8; + /* now generate for lengths greater than one byte */ while (1) { - - l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE); - rLen -= 8 ; - if (rLen <= 0 ) - break ; + if (rLen <= 0 ) { + mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset); + break ; + } switch (p_type) { case POINTER: - if (*l == '@') { - MOVA(l); - pic16_emitcode("mov","@%s,a",rname); - } else - pic16_emitcode("mov","@%s,%s",rname,l); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0)); break; +/* case FPOINTER: MOVA(l); pic16_emitcode("movx","@dptr,a"); @@ -11880,21 +11594,25 @@ static void genPackBits (sym_link *etype , operand *result, MOVA(l); DEBUGpic16_emitcode(";lcall","__gptrput"); break; +*/ + default: + assert(0); } - pic16_emitcode ("inc","%s",rname); - } - MOVA(l); + + pic16_mov2w(AOP(right), offset++); + } /* last last was not complete */ if (rLen) { /* save the byte & read byte */ switch (p_type) { case POINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("mov","a,@%s",rname); +// pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); break; +/* case FPOINTER: pic16_emitcode ("mov","b,a"); pic16_emitcode("movx","a,@dptr"); @@ -11906,29 +11624,40 @@ static void genPackBits (sym_link *etype , operand *result, pic16_emitcode ("lcall","__gptrget"); pic16_emitcode ("pop","b"); break; +*/ + default: + assert(0); } - - pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); - pic16_emitcode ("orl","a,b"); + DEBUGpic16_emitcode(";", "rLen = %i", rLen); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen)); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); +// pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); +// pic16_emitcode ("orl","a,b"); } - if (p_type == GPOINTER) - pic16_emitcode("pop","b"); +// if (p_type == GPOINTER) +// pic16_emitcode("pop","b"); switch (p_type) { - case POINTER: - pic16_emitcode("mov","@%s,a",rname); + case POINTER: + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); +// pic16_emitcode("mov","@%s,a",rname); break; - - case FPOINTER: +/* + case FPOINTER: pic16_emitcode("movx","@dptr,a"); break; - case GPOINTER: + case GPOINTER: DEBUGpic16_emitcode(";lcall","__gptrput"); break; +*/ + default: + assert(0); } + +// pic16_freeAsmop(right, NULL, ic, TRUE); } /*-----------------------------------------------------------------*/ /* genDataPointerSet - remat pointer to data space */ @@ -12004,7 +11733,6 @@ static void genNearPointerSet (operand *right, iCode *ic) { asmop *aop = NULL; - char *l; sym_link *retype; sym_link *ptype = operandType(result); sym_link *resetype; @@ -12037,32 +11765,14 @@ static void genNearPointerSet (operand *right, /* if the value is already in a pointer register * then don't need anything more */ if (1 || !AOP_INPREG(AOP(result))) { // AOP_INPREG(AOP(result)) is not always correct... - /* otherwise get a free pointer register */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -// if( (AOP_TYPE(result) == AOP_PCODE) -// && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE) -// || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10 - if(is_LitAOp( AOP(result) )) - { - if(!IS_BITFIELD(resetype)) - pic16_loadFSR0( result ); // patch 10 - } else { - if(!IS_BITFIELD(resetype)) { - // set up FSR0 with address of result - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10 - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10 - } - } - - } -// else -// rname = pic16_aopGet(AOP(result),0,FALSE,FALSE); + ; + } DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -// pic16_loadFSR0( result ); - /* if bitfield then unpack the bits */ if (IS_BITFIELD(resetype)) { genPackBits (resetype, result, right, NULL, POINTER); @@ -12071,15 +11781,10 @@ static void genNearPointerSet (operand *right, int size = AOP_SIZE(right); int offset = 0 ; + pic16_loadFSR0(result, 0); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { - l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); - if (*l == '@' ) { - //MOVA(l); - //pic16_emitcode("mov","@%s,a",rname); - pic16_emitcode("movf","indf0,w ;1"); - } else { - if (AOP_TYPE(right) == AOP_LIT) { pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); if (size) { @@ -12098,41 +11803,40 @@ static void genNearPointerSet (operand *right, pic16_popCopyReg(&pic16_pc_indf0))); } } - } offset++; } - } + } DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* now some housekeeping stuff */ if (aop) { - /* we had to allocate for this iCode */ - pic16_freeAsmop(NULL,aop,ic,TRUE); + /* we had to allocate for this iCode */ + pic16_freeAsmop(NULL,aop,ic,TRUE); } else { - /* we did not allocate which means left - * already in a pointer register, then - * if size > 0 && this could be used again - * we have to point it back to where it - * belongs */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_SIZE(right) > 1 - && !OP_SYMBOL(result)->remat - && ( OP_SYMBOL(result)->liveTo > ic->seq - || ic->depth )) { - - int size = AOP_SIZE(right) - 1; - - while (size--) - pic16_emitcode("decf","fsr0,f"); - //pic16_emitcode("dec","%s",rname); - } - } + /* we did not allocate which means left + * already in a pointer register, then + * if size > 0 && this could be used again + * we have to point it back to where it + * belongs */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (AOP_SIZE(right) > 1 + && !OP_SYMBOL(result)->remat + && ( OP_SYMBOL(result)->liveTo > ic->seq + || ic->depth )) { + + int size = AOP_SIZE(right) - 1; + + while (size--) + pic16_emitcode("decf","fsr0,f"); + //pic16_emitcode("dec","%s",rname); + } + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* done */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* done */ //release: - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -12398,7 +12102,6 @@ static void genGenPointerSet (operand *right, { int size; sym_link *retype = getSpec(operandType(right)); - char fgptrput[32]; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -12441,27 +12144,7 @@ static void genGenPointerSet (operand *right, pic16_popCopyReg(&pic16_pc_prodl))); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2)); - - /* put code here */ - switch (size) { - case 1: strcpy(fgptrput, "__gptrput1"); break; - case 2: strcpy(fgptrput, "__gptrput2"); break; - case 3: strcpy(fgptrput, "__gptrput3"); break; - case 4: strcpy(fgptrput, "__gptrput4"); break; - default: - werror(W_POSSBUG2, __FILE__, __LINE__); - abort(); - } - - pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput )); - - { - symbol *sym; - - sym = newSymbol( fgptrput, 0 ); - strcpy(sym->rname, fgptrput); - checkAddSym(&externs, sym); - } + pic16_callGenericPointerRW(1, size); release: pic16_freeAsmop(right,NULL,ic,TRUE); @@ -12594,8 +12277,8 @@ static void genAddrOf (iCode *ic) /* get address of symbol on stack */ DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name); #if 0 - fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__, - OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack); + fprintf(stderr, "%s:%d symbol %s on stack offset %i\n", __FILE__, __LINE__, + OP_SYMBOL(IC_LEFT(ic))->name, OP_SYMBOL(IC_LEFT(ic))->stack); #endif // operands on stack are accessible via "FSR2 + index" with index @@ -12820,7 +12503,7 @@ static void genAssign (iCode *ic) pic16_popCopyReg(&pic16_pc_tblptru))); } - size = min(AOP_SIZE(right), AOP_SIZE(result)); + size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result)); while(size--) { pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), @@ -12828,8 +12511,9 @@ static void genAssign (iCode *ic) offset++; } - if(AOP_SIZE(result) > AOP_SIZE(right)) { - size = AOP_SIZE(result) - AOP_SIZE(right); + size = getSize(OP_SYM_ETYPE(right)); + if(AOP_SIZE(result) > size) { + size = AOP_SIZE(result) - size; while(size--) { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); offset++; @@ -12970,9 +12654,10 @@ static void genJumpTab (iCode *ic) pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl)); pic16_emitpLabelFORCE(jtab->key); - #endif + pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); +// pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_BEGIN, "")); /* now generate the jump labels */ @@ -13136,8 +12821,8 @@ static void genCast (iCode *ic) // if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) // return ; - pic16_aopOp(right,ic,FALSE) ; pic16_aopOp(result,ic,FALSE); + pic16_aopOp(right,ic,FALSE) ; DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); @@ -13383,6 +13068,8 @@ static void genCast (iCode *ic) goto release ; } + + assert( 0 ); /* just copy the pointers */ size = AOP_SIZE(result); offset = 0 ; @@ -13410,8 +13097,10 @@ static void genCast (iCode *ic) /* we move to result for the size of source */ size = AOP_SIZE(right); offset = 0 ; + while (size--) { - mov2f(AOP(result), AOP(right), offset); + if(!_G.resDirect) + mov2f(AOP(result), AOP(right), offset); offset++; } @@ -13566,10 +13255,26 @@ static void genReceive (iCode *ic) static void genDummyRead (iCode * ic) { - pic16_emitcode ("; genDummyRead",""); - pic16_emitcode ("; not implemented",""); + operand *op; + int i; - ic = ic; + op = IC_RIGHT(ic); + if (op && IS_SYMOP(op)) { + if (IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) { + fprintf (stderr, "%s: volatile symbols in codespace?!? -- might go wrong...\n", __FUNCTION__); + return; + } + pic16_aopOp (op, ic, FALSE); + for (i=0; i < AOP_SIZE(op); i++) { + // may need to protect this from the peepholer -- this is not nice but works... + pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir(";", "VOLATILE READ - BEGIN")); + pic16_mov2w (AOP(op),i); + pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir(";", "VOLATILE READ - END")); + } // for i + pic16_freeAsmop (op, NULL, ic, TRUE); + } else if (op) { + fprintf (stderr, "%s: not implemented for non-symbols (volatile operand might not be read)\n", __FUNCTION__); + } // if } /*-----------------------------------------------------------------*/