X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=b3fd810568a562041fd30adaa7cf35fb97a3d7e4;hb=d93b49a56912a139d1ae9fc2f6cfba38e4118609;hp=fee949adc1061d4711364416fb0a9a83e080c8d4;hpb=f1bbfcc96aff36fcfec4313d8707e26fc189dfec;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index fee949ad..b3fd8105 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) @@ -7,6 +7,7 @@ PIC port - Scott Dattalo scott@dattalo.com (2000) PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002) - Vangelis Rokas vrokas@otenet.gr (2003,2004,2005) + Bug Fixes - Raphael Neider rneider@web.de (2004,2005) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -68,7 +69,6 @@ extern void pic16_printpBlock(FILE *of, pBlock *pb); static asmop *newAsmop (short type); static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op); extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...); -static void mov2f(asmop *dst, asmop *src, int offset); static void mov2fp(pCodeOp *dst, asmop *src, int offset); static pCodeOp *pic16_popRegFromIdx(int rIdx); @@ -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; @@ -310,7 +303,9 @@ void pic16_emitpLabelFORCE(int key) pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset)); } -void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop) +/* gen.h defines a macro pic16_emitpcode that allows for debug information to be inserted on demand + * NEVER call pic16_emitpcode_real directly, please... */ +void pic16_emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop) { if(pcop) @@ -683,19 +678,25 @@ 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); @@ -722,9 +723,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])); + } } } @@ -1233,10 +1242,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; @@ -1263,9 +1272,9 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) sym->usl.spillLoc->offset, op); } else { 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__); + pic16_emitpcomment (";!!! %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); @@ -1376,8 +1385,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; } @@ -1550,9 +1564,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]; @@ -1656,13 +1675,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__); @@ -1675,15 +1696,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; @@ -1703,6 +1767,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) ); } } @@ -1728,17 +1793,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); @@ -2317,7 +2385,7 @@ void pic16_mov2w (asmop *aop, int offset) pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset)); } -static void mov2f(asmop *dst, asmop *src, int offset) +void pic16_mov2f(asmop *dst, asmop *src, int offset) { if(is_LitAOp(src)) { pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset)); @@ -2341,7 +2409,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 )); @@ -2349,7 +2417,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); } @@ -2380,7 +2449,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(); } @@ -2395,10 +2464,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) @@ -2724,7 +2793,7 @@ static void genUminusFloat(operand *op,operand *result) size = AOP_SIZE(op); while(size--) { - mov2f(AOP(result), AOP(op), offset); + pic16_mov2f(AOP(result), AOP(op), offset); offset++; } @@ -3311,7 +3380,9 @@ static void genCall (iCode *ic) // pushaop(AOP(IC_LEFT(sic)), size); pic16_mov2w (AOP(IC_LEFT(sic)), size); - pushw(); + + if(!_G.resDirect) + pushw(); } } @@ -3588,43 +3659,31 @@ static void genFunction (iCode *ic) // 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))); + pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */ - /* 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; @@ -3638,6 +3697,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; } @@ -3657,7 +3717,6 @@ static void genFunction (iCode *ic) pic16_emitcode("","%s:",sym->rname); pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname)); - { absSym *ab; @@ -3669,7 +3728,6 @@ static void genFunction (iCode *ic) } } - if(IFFUNC_ISNAKED(ftype)) { DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); return; @@ -3680,7 +3738,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 */ @@ -3705,15 +3766,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(0 || !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)); @@ -3802,6 +3867,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; @@ -3815,9 +3891,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) { @@ -3836,7 +3913,12 @@ static void genEndFunction (iCode *ic) } if(strcmp(sym->name, "main")) { - if(0 || !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 )); @@ -3899,36 +3981,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) { unsigned long lit=1; - - // 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; + 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; + /* 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(lit == 0) { + 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)); @@ -3956,27 +4041,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 */ @@ -4773,9 +4847,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; @@ -4878,11 +4952,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 */ @@ -4901,7 +4970,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 @@ -4937,6 +5006,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! * **********************************************************************/ @@ -4963,9 +5036,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 @@ -4979,14 +5050,14 @@ 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; left = right; right = dummy; - performedLt ^= 1; // instead of "left < right" we check for "right >= left+1" + performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1" } else if (isAOP_LIT(right)) { lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); } // if @@ -5001,9 +5072,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; @@ -5011,9 +5080,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; @@ -5087,7 +5154,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) { @@ -5113,16 +5180,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, @@ -5755,7 +5820,7 @@ static void genCmp (operand *left,operand *right, 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_MOVWF, pctemp); //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)); @@ -5845,7 +5910,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, @@ -5955,10 +6020,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) { @@ -6097,84 +6158,6 @@ static void genCmp (operand *left, operand *right, // 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_MOVLW, pic16_popGetLit(BYTEofLONG(lit, 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 { - /* compare registers */ - DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__); - - - if(sign) { - pCodeOp *pct, *pct2; - - /* signed compare */ - DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__); - - pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */ - pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */ - tlbl = newiTempLabel( NULL ); - - compareAopfirstpass=1; - - 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); - - 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; @@ -6182,489 +6165,106 @@ static void genCmp (operand *left, operand *right, 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)); + } else { + pic16_emitpLabel(tlbl->key); + } + } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - genSkipc(&rFalseIfx); - - if(ifx) ifx->generated = 1; - return; - } + /* unsigned compare */ + DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); + + compareAopfirstpass=1; + while(size--) { + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size))); + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); - } else { + } + if(ifx)ifx->generated = 1; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); - } + if(AOP_SIZE(result)) { + pic16_emitpLabel(falselbl->key); + pic16_outBitC( result ); + } + } + } else { + /* compare registers */ + DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__); - /* The rest of the bytes of a multi-byte compare */ - while (size) { - emitSKPZ; - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key)); - size--; + if(sign) { + pCodeOp *pct, *pct2; + + /* signed compare */ + DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); + pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */ + pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */ + tlbl = newiTempLabel( NULL ); + + compareAopfirstpass=1; + 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); + + 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)); - 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; + /* 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; - return; + 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__); -check_carry: - if ((AOP_TYPE(result) != AOP_CRY) - && AOP_SIZE(result)) { - DEBUGpic16_emitcode ("; ***","%s %d",__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)pic16_emitpLabel( rFalseIfx.lbl->key ); + } - 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 */ - } + if(ifx)ifx->generated = 1; + if(AOP_SIZE(result)) { -} -#endif /* } */ + pic16_emitpLabel(falselbl->key); + pic16_outBitC( result ); + } + } + } +} #endif /* } */ @@ -8636,14 +8236,70 @@ 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; - + +#if 0 + /* This is an experimental code for #pragma inline + and is temporarily disabled for 2.5.0 release */ + if(asmInlineMap) + { + symbol *sym; + char *s; + char *cbuf; + 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; + } +#endif /* 0 */ + /* emit each line as a code */ while (*bp) { if (*bp == '\n') { @@ -9041,7 +8697,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, } else { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER)); } @@ -9056,7 +8712,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, } else { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offr)); } default: @@ -9896,7 +9552,7 @@ static void genLeftShift (iCode *ic) #endif { /* we don't know if left is a literal or a register, take care -- VR */ - mov2f(AOP(result), AOP(left), offset); + pic16_mov2f(AOP(result), AOP(left), offset); } offset++; } @@ -9928,7 +9584,7 @@ static void genLeftShift (iCode *ic) #if 1 /* this is already done, why change it? */ if (!pic16_sameRegs(AOP(left),AOP(result))) { - mov2f(AOP(result), AOP(left), 0); + pic16_mov2f(AOP(result), AOP(left), 0); } #endif @@ -10079,7 +9735,7 @@ static void genLeftShift (iCode *ic) } else { /* we don't know if left is a literal or a register, take care -- VR */ - mov2f(AOP(result), AOP(left), offset); + pic16_mov2f(AOP(result), AOP(left), offset); } offset++; } @@ -10108,7 +9764,7 @@ static void genLeftShift (iCode *ic) tlbl = newiTempLabel(NULL); if (!pic16_sameRegs(AOP(left),AOP(result))) { - mov2f(AOP(result), AOP(left), 0); + pic16_mov2f(AOP(result), AOP(left), 0); // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); // pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); @@ -10234,7 +9890,7 @@ static void genrshTwo (operand *result,operand *left, if(sign) { pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),MSB16)); } } @@ -10395,7 +10051,7 @@ static void genRightShiftLiteral (operand *left, if(shCount == 0){ assert (res_size <= lsize); while (res_size--) { - mov2f (AOP(result), AOP(left), res_size); + pic16_mov2f (AOP(result), AOP(left), res_size); } // for } @@ -10405,7 +10061,7 @@ static void genRightShiftLiteral (operand *left, pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB)); if(sign) { pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB)); } } else { @@ -10774,7 +10430,7 @@ static void genGenericShift (iCode *ic, int isShiftLeft) { // (e.g. char c = 0x100 << -3 will become c = 0x00 >> 3 == 0x00 instad of 0x20) // This is fine, as it only occurs for left shifting with negative count which is not standardized! for (offset=0; offset < min(AOP_SIZE(left), AOP_SIZE(result)); offset++) { - mov2f (AOP(result),AOP(left), offset); + pic16_mov2f (AOP(result),AOP(left), offset); } // for // if result is longer than left, fill with zeros (or sign) @@ -10869,26 +10525,74 @@ static void genRightShift (iCode *ic) { /* load FSR0 with address of/from op according to is_LitOp() or if lit is 1 */ void pic16_loadFSR0(operand *op, int lit) { - if(is_LitOp( op ) || lit) { + 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))); } } +/*----------------------------------------------------------------*/ +/* pic16_derefPtr - move one byte from the location ptr points to */ +/* to WREG (doWrite == 0) or one byte from WREG */ +/* to the location ptr points to (doWrite != 0) */ +/*----------------------------------------------------------------*/ +static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_setup) +{ + switch (p_type) { + case FPOINTER: + case POINTER: + if (!fsr0_setup || !*fsr0_setup) + { + pic16_loadFSR0( ptr, 0 ); + if (fsr0_setup) *fsr0_setup = 1; + } + if (doWrite) + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + else + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + break; + + case GPOINTER: + if (AOP(ptr)->aopu.aop_reg[2]) { + if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec)); + // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?) + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),1), pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(ptr),2)); + pic16_callGenericPointerRW(doWrite, 1); + } else { + // data pointer (just 2 byte given) + if (!fsr0_setup || !*fsr0_setup) + { + pic16_loadFSR0( ptr, 0 ); + if (fsr0_setup) *fsr0_setup = 1; + } + if (doWrite) + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + else + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + } + break; + + default: + assert (0 && "invalid pointer type specified"); + break; + } +} + /*-----------------------------------------------------------------*/ /* genUnpackBits - generates code for unpacking bits */ /*-----------------------------------------------------------------*/ static void genUnpackBits (operand *result, operand *left, char *rname, int ptype) { int shCnt ; - int rlen = 0 ; sym_link *etype, *letype; int blen=0, bstr=0; int lbstr; - int offset = 0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); etype = getSpec(operandType(result)); @@ -10908,11 +10612,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(!IS_PTR(operandType(left))/* && OP_SYMBOL(left)->remat && (ptype == POINTER)*/) { /* 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)); } @@ -10928,23 +10634,13 @@ 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, 1 ); - - /* read the first byte */ - switch (ptype) { - case POINTER: - case IPOINTER: - case PPOINTER: - case FPOINTER: - case GPOINTER: - pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); - break; - case CPOINTER: - pic16_emitcode("clr","a"); - pic16_emitcode("movc","a","@a+dptr"); - break; - } - + + if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) { + // access symbol directly + pic16_mov2w (AOP(left), 0); + } else { + pic16_derefPtr (left, ptype, 0, NULL); + } /* if we have bitdisplacement then it fits */ /* into this byte completely or if length is */ @@ -10975,55 +10671,6 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); exit(-1); - /* bit field did not fit in a byte */ - rlen = SPEC_BLEN(etype) - 8; - pic16_aopPut(AOP(result),"a",offset++); - - while (1) { - - switch (ptype) { - case POINTER: - case IPOINTER: - pic16_emitcode("inc","%s",rname); - pic16_emitcode("mov","a,@%s",rname); - break; - - case PPOINTER: - pic16_emitcode("inc","%s",rname); - pic16_emitcode("movx","a,@%s",rname); - break; - - case FPOINTER: - pic16_emitcode("inc","dptr"); - pic16_emitcode("movx","a,@dptr"); - break; - - case CPOINTER: - pic16_emitcode("clr","a"); - pic16_emitcode("inc","dptr"); - pic16_emitcode("movc","a","@a+dptr"); - break; - - case GPOINTER: - pic16_emitcode("inc","dptr"); - pic16_emitcode("lcall","__gptrget"); - break; - } - - rlen -= 8; - /* if we are done */ - if ( rlen <= 0 ) - break ; - - pic16_aopPut(AOP(result),"a",offset++); - - } - - if (rlen) { - pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen)); - pic16_aopPut(AOP(result),"a",offset); - } - return ; } @@ -11037,6 +10684,8 @@ static void genDataPointerGet(operand *left, DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(result, ic, TRUE); + FENTRY; + size = AOP_SIZE(result); // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); @@ -11087,8 +10736,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 { @@ -11117,12 +10766,14 @@ static void genNearPointerGet (operand *left, // asmop *aop = NULL; //regs *preg = NULL ; sym_link *rtype, *retype; - sym_link *ltype = operandType(left); + sym_link *ltype, *letype; FENTRY; rtype = operandType(result); retype= getSpec(rtype); + ltype = operandType(left); + letype= getSpec(ltype); pic16_aopOp(left,ic,FALSE); @@ -11170,6 +10821,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 */ @@ -11188,18 +10840,8 @@ static void genNearPointerGet (operand *left, } #endif - - /* if the value is already in a pointer register - * then don't need anything more */ - if (1 || !AOP_INPREG(AOP(left))) { // AOP_INPREG(AOP(left)) is not always correct... - /* otherwise get a free pointer register */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - ; - } - /* if bitfield then unpack the bits */ - if (IS_BITFIELD(retype)) + if (IS_BITFIELD(letype)) genUnpackBits (result, left, NULL, POINTER); else { /* we have can just get the values */ @@ -11508,8 +11150,7 @@ static void genGenPointerGet (operand *left, operand *result, iCode *ic) { int size, offset, lit; - sym_link *retype = getSpec(operandType(result)); - char fgptrget[32]; + sym_link *letype = getSpec(operandType(left)); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); @@ -11517,6 +11158,12 @@ static void genGenPointerGet (operand *left, size = AOP_SIZE(result); DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); + + /* if bit then unpack */ + if (IS_BITFIELD(letype)) { + genUnpackBits(result,left,"BAD",GPOINTER); + goto release; + } if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!) @@ -11545,38 +11192,13 @@ 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 ); - sym->used++; - strcpy(sym->rname, fgptrget); - checkAddSym(&externs, sym); - -// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget); - } - goto release; } - /* if bit then unpack */ - if (IS_BITFIELD(retype)) - genUnpackBits(result,left,"BAD",GPOINTER); - release: pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); @@ -11753,7 +11375,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, @@ -11763,7 +11385,7 @@ static void genPackBits (sym_link *etype , operand *result, pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); } } else { - pic16_loadFSR0(result, 1); + pic16_loadFSR0(result, 0); if(lit) { pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); @@ -11830,45 +11452,12 @@ static void genPackBits (sym_link *etype , operand *result, /* using PRODH as a temporary register here */ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); - /* get old value */ - switch (p_type) { - case FPOINTER: - case POINTER: - pic16_loadFSR0( result, 1 ); - 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: - 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_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrget1")); - { - symbol *sym; - sym = newSymbol( "__gptrget1", 0 ); - strcpy(sym->rname, "__gptrget1"); - checkAddSym(&externs, sym); - } - } else { - // data pointer (just 2 byte given) - pic16_loadFSR0( result, 1 ); - 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 (IS_SYMOP(result) && !IS_PTR(operandType (result))/*OP_SYMBOL(result)->remat*/) { + /* access symbol directly */ + pic16_mov2w (AOP(result), 0); + } else { + /* get old value */ + pic16_derefPtr (result, p_type, 0, &fsr0_setup); } #if 1 pic16_emitpcode(POC_ANDLW, pic16_popGetLit( @@ -11878,42 +11467,11 @@ static void genPackBits (sym_link *etype , operand *result, } // if (blen != 8 || bstr != 0) /* write new value back */ - switch (p_type) { - case FPOINTER: - case POINTER: - if (!fsr0_setup) pic16_loadFSR0( result, 1 ); - 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_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrput1")); - { - symbol *sym; - sym = newSymbol( "__gptrput1", 0 ); - strcpy(sym->rname, "__gptrput1"); - checkAddSym(&externs, sym); - } - } else { - // data pointer (just 2 byte given) - if (!fsr0_setup) pic16_loadFSR0( result, 1 ); - 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; - } + if (IS_SYMOP(result) & !IS_PTR(operandType(result))) { + pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0)); + } else { + pic16_derefPtr (result, p_type, 1, &fsr0_setup); + } #endif return; @@ -11927,7 +11485,7 @@ static void genPackBits (sym_link *etype , operand *result, #endif - pic16_loadFSR0(result, 1); // load FSR0 with address of result + pic16_loadFSR0(result, 0); // load FSR0 with address of result rLen = SPEC_BLEN(etype)-8; /* now generate for lengths greater than one byte */ @@ -12121,17 +11679,6 @@ static void genNearPointerSet (operand *right, pic16_aopOp(right,ic,FALSE); DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* 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__); - - ; - } - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if bitfield then unpack the bits */ if (IS_BITFIELD(resetype)) { genPackBits (resetype, result, right, NULL, POINTER); @@ -12460,8 +12007,7 @@ static void genGenPointerSet (operand *right, operand *result, iCode *ic) { int size; - sym_link *retype = getSpec(operandType(right)); - char fgptrput[32]; + sym_link *retype = getSpec(operandType(result)); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -12484,7 +12030,6 @@ static void genGenPointerSet (operand *right, DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size); - /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */ /* value of right+0 is placed on stack, which will be retrieved @@ -12504,28 +12049,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 ); - sym->used++; - strcpy(sym->rname, fgptrput); - checkAddSym(&externs, sym); - } + pic16_callGenericPointerRW(1, size); release: pic16_freeAsmop(right,NULL,ic,TRUE); @@ -12550,6 +12074,7 @@ static void genPointerSet (iCode *ic) move it to the correct pointer register */ type = operandType(result); etype = getSpec(type); + /* if left is of type of pointer then it is simple */ if (IS_PTR(type) && !IS_FUNC(type->next)) { p_type = DCL_TYPE(type); @@ -12658,8 +12183,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 @@ -12852,16 +12377,21 @@ static void genAssign (iCode *ic) if (AOP_TYPE(right) == AOP_REG) { DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__); while (size--) { - pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++)); } // while goto release; } + /* when do we have to read the program memory? + * - if right itself is a symbol in code space + * (we don't care what it points to if it's a pointer) + * - AND right is not a function (we would want its address) + */ if(AOP_TYPE(right) != AOP_LIT - && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype)) + && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right))) && !IS_FUNC(OP_SYM_TYPE(right)) - ) { + && !IS_ITEMP(right)) + { DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__); fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name); @@ -12884,7 +12414,8 @@ static void genAssign (iCode *ic) pic16_popCopyReg(&pic16_pc_tblptru))); } - size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result)); + /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */ + size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result)); while(size--) { pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), @@ -12892,7 +12423,9 @@ static void genAssign (iCode *ic) offset++; } - size = getSize(OP_SYM_ETYPE(right)); + /* FIXME: for pointers we need to extend differently (according + * to pointer type DATA/CODE/EEPROM/... :*/ + size = getSize(OP_SYM_TYPE(right)); if(AOP_SIZE(result) > size) { size = AOP_SIZE(result) - size; while(size--) { @@ -13035,9 +12568,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 */ @@ -13201,8 +12735,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); @@ -13389,7 +12923,7 @@ static void genCast (iCode *ic) while (size--) { if(offset < AOP_SIZE(right)) { DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type); - mov2f(AOP(result), AOP(right), offset); + pic16_mov2f(AOP(result), AOP(right), offset); /* if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { @@ -13448,6 +12982,8 @@ static void genCast (iCode *ic) goto release ; } + + assert( 0 ); /* just copy the pointers */ size = AOP_SIZE(result); offset = 0 ; @@ -13475,8 +13011,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) + pic16_mov2f(AOP(result), AOP(right), offset); offset++; } @@ -13493,7 +13031,7 @@ static void genCast (iCode *ic) /* Save one instruction of casting char to int */ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset)); } else { pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));