From 998bc7b7fc11e191943ed839f790fff34b78df3b Mon Sep 17 00:00:00 2001 From: vrokas Date: Wed, 15 Mar 2006 00:43:05 +0000 Subject: [PATCH] * src/SDCCmain.c (linkEdit): do not test for PIC16 target since, PIC16 linking is done manually in pic16 port's _linkEdit, * src/SDCCsymt.c (compStructSize): for target PIC16 and shell variable PIC16_PACKED_BITFIELDS, compact bitfield structures as much as possible, * src/pic16/gen.c (aopForSym): when direct register name is WREG then allocate asmop as AOP_ACC, (aopForRemat): added parameter 'bool result' in function declaration, (pic16_aopGet): return AOP_ACC when accessing WREG, (pic16_popGetTempReg): minor modification, (pic16_popRegFromIdx): first try with 'pic16_regWithIdx' then with 'pic16_allocWithIdx', (genPcall): removed ftype, usage of OP_SYM_TYPE asserted error when calling function in absolute addresses, (genAssign): take into account AOP_ACC asmop, * src/pic16/pcode.c (pic16_newpCodeOpReg): minor modifications, * src/pic16/pcoderegs.c: some debug functions and lines added, * src/pic16/ralloc.c (decodeRegType): added but commented out, * (pic16_typeRegWithIdx): search 'pic16_dynInternalRegs' for given register too, * (pic16_findFreeReg, pic16_findFreeRegNext): allocate new register via call to allocReg, not by manually allocating a new one, (pic16_assignRegisters): now before going through the register allocating functions mark all registers as free. This eliminates some side effects resulting from peephole parser done earlier in the backbone git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4061 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- .version | 2 +- ChangeLog | 28 +++++ src/SDCCmain.c | 2 +- src/SDCCsymt.c | 24 +++-- src/pic16/gen.c | 232 +++++++++++++++++++++++++++--------------- src/pic16/pcode.c | 16 +-- src/pic16/pcoderegs.c | 32 ++++-- src/pic16/ralloc.c | 141 +++++++++++++++---------- 8 files changed, 317 insertions(+), 160 deletions(-) diff --git a/.version b/.version index fe16b348..0cadbc1e 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.5.4 +2.5.5 diff --git a/ChangeLog b/ChangeLog index bd706364..1fc24424 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2006-03-14 Vangelis Rokas + + * src/.version: increased version number to 2.5.5 + * src/SDCCmain.c (linkEdit): do not test for PIC16 target since, PIC16 + linking is done manually in pic16 port's _linkEdit, + * src/SDCCsymt.c (compStructSize): for target PIC16 and shell variable + PIC16_PACKED_BITFIELDS, compact bitfield structures as much as possible, + * src/pic16/gen.c (aopForSym): when direct register name is WREG then + allocate asmop as AOP_ACC, + (aopForRemat): added parameter 'bool result' in function declaration, + (pic16_aopGet): return AOP_ACC when accessing WREG, + (pic16_popGetTempReg): minor modification, + (pic16_popRegFromIdx): first try with 'pic16_regWithIdx' then with + 'pic16_allocWithIdx', + (genPcall): removed ftype, usage of OP_SYM_TYPE asserted error when + calling function in absolute addresses, + (genAssign): take into account AOP_ACC asmop, + * src/pic16/pcode.c (pic16_newpCodeOpReg): minor modifications, + * src/pic16/pcoderegs.c: some debug functions and lines added, + * src/pic16/ralloc.c (decodeRegType): added but commented out, + * (pic16_typeRegWithIdx): search 'pic16_dynInternalRegs' for given + register too, + * (pic16_findFreeReg, pic16_findFreeRegNext): allocate new register via + call to allocReg, not by manually allocating a new one, + (pic16_assignRegisters): now before going through the register + allocating functions mark all registers as free. This eliminates some + side effects resulting from peephole parser done earlier in the backbone + 2006-03-13 Maarten Brock * src/SDCCicode.c (geniCodeLogic), diff --git a/src/SDCCmain.c b/src/SDCCmain.c index f8b61bd7..9d6a445d 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -1786,7 +1786,7 @@ linkEdit (char **envp) set *tempSet=NULL, *libSet=NULL; strcpy(buffer3, linkerScriptFileName); - if(TARGET_IS_PIC16 || TARGET_IS_PIC) { + if(/*TARGET_IS_PIC16 ||*/ TARGET_IS_PIC) { /* use $l to set the linker include directories */ tempSet = appendStrSet(libDirsSet, "-I\"", "\""); diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 0c0c00cc..40e1fed6 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1280,12 +1280,24 @@ compStructSize (int su, structdef * sdef) bitOffset += loop->bitVar; } else { - /* does not fit; need to realign first */ - sum++; - loop->offset = (su == UNION ? sum = 0 : sum); - bitOffset = 0; - SPEC_BSTR (loop->etype) = bitOffset; - bitOffset += loop->bitVar; + if( TARGET_IS_PIC16 && getenv("PIC16_PACKED_BITFIELDS") ) { + /* if PIC16 && enviroment variable is set, then + * tightly pack bitfields, this means that when a + * bitfield goes beyond byte alignment, do not + * automatically start allocatint from next byte, + * but also use the available bits first */ + fprintf(stderr, ": packing bitfields in structures\n"); + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + loop->offset = (su == UNION ? sum = 0 : sum); + } else { + /* does not fit; need to realign first */ + sum++; + loop->offset = (su == UNION ? sum = 0 : sum); + bitOffset = 0; + SPEC_BSTR (loop->etype) = bitOffset; + bitOffset += loop->bitVar; + } } while (bitOffset>8) { bitOffset -= 8; diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 6a0d0683..2290438c 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -851,14 +851,21 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } /* if it is in direct space */ if (IN_DIRSPACE(space)) { - sym->aop = aop = newAsmop (AOP_DIR); - aop->aopu.aop_dir = sym->rname ; - aop->size = getSize(sym->type); - DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size); - pic16_allocDirReg( IC_LEFT(ic) ); - return aop; - } - + if(!strcmp(sym->rname, "_WREG")) { + sym->aop = aop = newAsmop (AOP_ACC); + aop->size = getSize(sym->type); /* should always be 1 */ + assert(aop->size == 1); + DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size); + reutn (aop); + } else { + sym->aop = aop = newAsmop (AOP_DIR); + aop->aopu.aop_dir = sym->rname ; + aop->size = getSize(sym->type); + DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); + return (aop); + } + } if (IN_FARSPACE(space) && !IN_CODESPACE(space)) { sym->aop = aop = newAsmop (AOP_DIR); @@ -920,7 +927,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) /*-----------------------------------------------------------------*/ /* aopForRemat - rematerialzes an object */ /*-----------------------------------------------------------------*/ -static asmop *aopForRemat (operand *op) // x symbol *sym) +static asmop *aopForRemat (operand *op, bool result) // x symbol *sym) { symbol *sym = OP_SYMBOL(op); operand *refop; @@ -938,6 +945,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); } +// if(!result) /* fixme-vr */ for (;;) { oldic = ic; @@ -1225,7 +1233,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) /* rematerialize it NOW */ if (sym->remat) { - sym->aop = op->aop = aop = aopForRemat (op); + sym->aop = op->aop = aop = aopForRemat (op, result); // aop->size = getSize(sym->type); // DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd); return; @@ -1581,7 +1589,7 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) // return "acc"; if(!strcmp(aop->aopu.aop_str[offset], "WREG")) { aop->type = AOP_ACC; - return Safe_strdup("WREG"); + return Safe_strdup("_WREG"); } DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]); @@ -1658,7 +1666,7 @@ int _TempReg_lock = 0; /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGetTempReg(int lock) { - pCodeOp *pcop; + pCodeOp *pcop=NULL; symbol *cfunc; // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1671,6 +1679,34 @@ pCodeOp *pic16_popGetTempReg(int lock) cfunc = currFunc; currFunc = NULL; +#if 0 + { + regs *rr; + int i; + + /* this code might seem better but it does the *same* job with + * the old code, it all depends on ralloc.c to get a free/unused + * register */ + + i=0; + while(i < pic16_nRegs) { + rr = pic16_typeRegWithIdx(i, REG_GPR, 0); + fprintf(stderr, "%s:%d checking for TempReg Idx=%d rr=%p\n", __FILE__, __LINE__, i, rr); + if((!rr || (rr && rr->isFree)) + && !bitVectBitValue(cfunc->regsUsed, i)) { + pcop = pic16_newpCodeOpReg( i ); + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->r->isFree = 0; + break; + } + i++; + } + + if(pcop) { + pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + } + } +#else pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { PCOR(pcop)->r->wasUsed=1; @@ -1679,6 +1715,7 @@ pCodeOp *pic16_popGetTempReg(int lock) /* push value on stack */ pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); } +#endif currFunc = cfunc; @@ -1889,6 +1926,7 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING")); PCOR(pcop)->r = pic16_dirregWithName(pcop->name); +// PCOR(pcop)->r->wasUsed = 1; /* make sure that register doesn't exist, * and operand isn't NULL @@ -1913,11 +1951,14 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx) pCodeOp *pcop; // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx); - +// fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcop)->rIdx = rIdx; PCOR(pcop)->r = pic16_regWithIdx(rIdx); - + if(!PCOR(pcop)->r) + PCOR(pcop)->r = pic16_allocWithIdx(rIdx); + PCOR(pcop)->r->isFree = 0; PCOR(pcop)->r->wasUsed = 1; @@ -1994,9 +2035,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) char *rs; pCodeOp *pcop; - FENTRY2; - /* offset is greater than - size then zero */ + FENTRY2; + /* offset is greater than + * size then zero */ // if (offset > (aop->size - 1) && // aop->type != AOP_LIT) @@ -2004,69 +2045,65 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) /* depending on type */ switch (aop->type) { - - case AOP_R0: - case AOP_R1: - case AOP_DPTR: - case AOP_DPTR2: - DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type)); - fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type)); - assert( 0 ); - return NULL; - - - case AOP_FSR0: - case AOP_FSR2: - pcop = Safe_calloc(1, sizeof(pCodeOpReg)); - PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */ - PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx ); - PCOR(pcop)->r->wasUsed = 1; - PCOR(pcop)->r->isFree = 0; + case AOP_R0: + case AOP_R1: + case AOP_DPTR: + case AOP_DPTR2: + DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type)); + fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type)); + assert( 0 ); + return NULL; + + case AOP_FSR0: + case AOP_FSR2: + pcop = Safe_calloc(1, sizeof(pCodeOpReg)); + PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */ + PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx ); + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->r->isFree = 0; - PCOR(pcop)->instance = offset; - pcop->type = PCOR(pcop)->r->pc_type; - return (pcop); - - case AOP_IMMD: - DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); - return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); - - case AOP_STA: - /* pCodeOp is already allocated from aopForSym */ - DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset); - pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]); - - return (pcop); + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; + return (pcop); + + case AOP_IMMD: + DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); + return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); + + case AOP_STA: + /* pCodeOp is already allocated from aopForSym */ + DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset); + pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]); + return (pcop); - case AOP_ACC: - { - int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; + case AOP_ACC: + { + int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; - fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); + fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); - DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); + DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; - PCOR(pcop)->instance = offset; - pcop->type = PCOR(pcop)->r->pc_type; -// rs = aop->aopu.aop_reg[offset]->name; -// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); - return pcop; + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; + DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); + return pcop; // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset); // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); // assert( 0 ); - } + } case AOP_DIR: - DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); + DEBUGpic16_emitcode(";","%d\tAOP_DIR (name = %s)", __LINE__, aop->aopu.aop_dir); return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL); #if 0 @@ -2086,7 +2123,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); // pcop->type = PO_GPR_REGISTER; PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx); + PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx); PCOR(pcop)->r->wasUsed=1; PCOR(pcop)->r->isFree=0; @@ -2487,6 +2524,8 @@ void pushaop(asmop *aop, int offset) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(_G.resDirect)return; + if(is_LitAOp(aop)) { pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset)); pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); @@ -3308,8 +3347,8 @@ static void genCall (iCode *ic) DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1); // pushaop(AOP(IC_LEFT(sic)), size); - pic16_mov2w (AOP(IC_LEFT(sic)), size); - + pic16_mov2w( AOP(IC_LEFT(sic)), size ); + if(!_G.resDirect) pushw(); } @@ -3745,22 +3784,41 @@ static void genFunction (iCode *ic) /* if any registers used */ if (sym->regsUsed) { - /* save the registers used */ - DEBUGpic16_emitcode("; **", "Saving used registers in stack"); - pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i)) { - pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); - _G.nRegsSaved++; - - if(!pic16_regWithIdx(i)->wasUsed) { - fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n", - __FILE__, __LINE__, pic16_regWithIdx(i)->name); - pic16_regWithIdx(i)->wasUsed = 1; + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); + + if(!xinst) { + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Saving used registers in stack"); + for ( i = 0 ; i < sym->regsUsed->size ; i++) { + if (bitVectBitValue(sym->regsUsed,i)) { +#if 0 + fprintf(stderr, "%s:%d local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i); +#endif + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); + _G.nRegsSaved++; + + if(!pic16_regWithIdx(i)->wasUsed) { + fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0\n", + __FILE__, __LINE__, pic16_regWithIdx(i)->name); + pic16_regWithIdx(i)->wasUsed = 1; + } + } + } + } else { + + /* xinst */ + DEBUGpic16_emitcode("; **", "Allocate a space in stack to be used as temporary registers"); + for(i=0;iregsUsed->size;i++) { + if(bitVectBitValue(sym->regsUsed, i)) { + _G.nRegsSaved++; } } + +// pic16_emitpcode(POC_ADDFSR, pic16_popGetLit2(2, pic16_popGetLit(_G.nRegsSaved))); } + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END)); + } } @@ -12470,8 +12528,16 @@ static void genAssign (iCode *ic) } else { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!_G.resDirect) /* use this aopForSym feature */ - pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); + if(!_G.resDirect) { /* use this aopForSym feature */ + if(AOP_TYPE(result) == AOP_ACC) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset)); + } else + if(AOP_TYPE(right) == AOP_ACC) { + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); + } + } } offset++; diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 34ecf951..e20eb832 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -4244,26 +4244,28 @@ pCodeOp *pic16_newpCodeOpBit_simple (struct asmop *op, int offs, int bit) pCodeOp *pic16_newpCodeOpReg(int rIdx) { pCodeOp *pcop; + regs *r; pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); pcop->name = NULL; if(rIdx >= 0) { - PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_regWithIdx(rIdx); + r = pic16_regWithIdx(rIdx); + if(!r) + r = pic16_allocWithIdx(rIdx); } else { - PCOR(pcop)->r = pic16_findFreeReg(REG_GPR); + r = pic16_findFreeReg(REG_GPR); - if(PCOR(pcop)->r) - PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; - else { + if(!r) { fprintf(stderr, "%s:%d Could not find a free GPR register\n", __FUNCTION__, __LINE__); exit(-1); } } + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = r; pcop->type = PCOR(pcop)->r->pc_type; return pcop; @@ -5932,7 +5934,7 @@ static void AnalyzepBlock(pBlock *pb) } if(PCI(pc)->pcop->type == PO_GPR_REGISTER) { if(PCOR(PCI(pc)->pcop)->r) { - pic16_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx); + pic16_allocWithIdx(PCOR(PCI(pc)->pcop)->r->rIdx); /* FIXME! - VR */ DFPRINTF((stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx)); } else { if(PCI(pc)->pcop->name) diff --git a/src/pic16/pcoderegs.c b/src/pic16/pcoderegs.c index 9cbcd596..1de9fbe1 100644 --- a/src/pic16/pcoderegs.c +++ b/src/pic16/pcoderegs.c @@ -37,6 +37,11 @@ #include "pcoderegs.h" #include "pcodeflow.h" + +#define DEBUG_REMOVE1PCODE 0 +#define HAVE_DBGREGUSAGE 0 + + extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2); extern pCode * pic16_findPrevInstruction(pCode *pci); extern pBranch * pic16_pBranchAppend(pBranch *h, pBranch *n); @@ -66,7 +71,8 @@ void AddRegToFlow(regs *reg, pCodeFlow *pcfl) /*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ -#if 0 + +#if HAVE_DBGREGUSAGE static void dbg_regusage(set *fregs) { regs *reg; @@ -119,13 +125,13 @@ static void dbg_regusage(set *fregs) } } } -#endif /*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ -#if 0 -static void dbg_dumpregusage(void) + +//static +void dbg_dumpregusage(void) { fprintf(stderr,"*** Register Usage ***\n"); @@ -187,7 +193,9 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) if(PCC_REGISTER & PCI(pc)->outCond) addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl); - addSetIfnotP(& (reg->reglives.usedpCodes), pc); + addSetIfnotP(& (reg->reglives.usedpCodes), pc); + +// reg->wasUsed=1; #if 1 /* check to see if this pCode has 2 memory operands, @@ -205,6 +213,8 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl); addSetIfnotP(& (reg->reglives.usedpCodes), pc); + +// reg->wasUsed=1; } } #endif @@ -254,7 +264,9 @@ void pic16_pCodeRegMapLiveRanges(pBlock *pb) } #endif -// dbg_dumpregusage(); +#if HAVE_DBGREGUSAGE + dbg_dumpregusage(); +#endif } @@ -271,7 +283,7 @@ static void Remove1pcode(pCode *pc, regs *reg) deleteSetItem (&(reg->reglives.usedpCodes),pc); -#if 0 +#if DEBUG_REMOVE1PCODE fprintf(stderr,"removing instruction:\n"); pc->print(stderr,pc); #endif @@ -289,10 +301,12 @@ static void Remove1pcode(pCode *pc, regs *reg) if(pcn) { if(PCI(pcn)->cline) { -#if 0 + +#if DEBUG_REMOVE1PCODE fprintf(stderr, "source line has been optimized completely out\n"); pc->print(stderr,pc); #endif + } else { PCI(pcn)->cline = PCI(pc)->cline; } @@ -324,7 +338,7 @@ static void RemoveRegsFromSet(set *regset) if(used == 0) { -// fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name); +// fprintf(stderr,"%s:%d: getting rid of reg %s\n",__FILE__, __LINE__, reg->name); reg->isFree = 1; reg->wasUsed = 0; diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index b3b3392c..83761a20 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -321,6 +321,21 @@ pic16_decodeOp (unsigned int op) return buffer; } + +#if 0 +static char *decodeRegType(short type) +{ + switch(type) { + case REG_GPR: return "REG_GPR"; + case REG_PTR: return "REG_PTR"; + case REG_CND: return "REG_CNT"; + + default: + return ""; + } +} +#endif + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ static char * @@ -371,7 +386,12 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia if(name) dReg->name = Safe_strdup(name); else { - sprintf(buffer,"r0x%02X", dReg->rIdx); + if(xinst && pc_type == PO_GPR_TEMP) { + sprintf(buffer,"0x%02x", dReg->rIdx); + } else { + sprintf(buffer,"r0x%02x", dReg->rIdx); + } + if(type == REG_STK) { *buffer = 's'; } @@ -417,12 +437,18 @@ regWithIdx (set *dRegs, int idx, unsigned fixed) { regs *dReg; +//#define D(text) text +#define D(text) + for (dReg = setFirstItem(dRegs) ; dReg ; dReg = setNextItem(dRegs)) { + D(fprintf(stderr, "%s:%d testing reg w/rIdx = %d (%d f:%d)\t", __FUNCTION__, __LINE__, dReg->rIdx, idx, fixed)); if(idx == dReg->rIdx && (fixed == dReg->isFixed)) { + D(fprintf(stderr, "found!\n")); return dReg; - } + } else + D(fprintf(stderr, "not found!\n")); } return NULL; @@ -443,6 +469,8 @@ regFindFree (set *dRegs) // __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree); if(dReg->isFree) { +// fprintf(stderr, "%s:%d free register found, rIdx = %d\n", __FILE__, __LINE__, dReg->rIdx); + return dReg; } } @@ -528,11 +556,12 @@ allocReg (short type) { regs * reg=NULL; -#define MAX_P16_NREGS 6 +#define MAX_P16_NREGS 16 #if 0 if(dynrIdx > pic16_nRegs) + werror(W_POSSBUG2, __FILE__, __LINE__); return NULL; #endif @@ -540,12 +569,13 @@ allocReg (short type) reg = regFindFree( pic16_dynAllocRegs ); if(reg) { -// fprintf(stderr, "%s: [%s] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx); +// fprintf(stderr, "%s: [%s][cf:%p] found FREE register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx); } if(!reg) { reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL); -// fprintf(stderr, "%s: [%s] allocating NEW register %s, rIdx: %d\n", __FILE__, (_inRegAllocator)?"ralloc":"", reg->name, reg->rIdx); +// fprintf(stderr, "%s [%s][cf:%p] allocating NEW register %s, rIdx: %d\n", __FILE__, +// (_inRegAllocator)?"ralloc":"", currFunc, reg->name, reg->rIdx); #if 1 if(_inRegAllocator && (dynrIdx > MAX_P16_NREGS)) { @@ -553,15 +583,13 @@ allocReg (short type) // return (NULL); } #endif - -// addSet(&pic16_dynAllocRegs, reg); } addSet(&pic16_dynAllocRegs, reg); hTabAddItem(&dynAllocRegNames, regname2key(reg->name), reg); - reg->isFree=0; - +// fprintf(stderr, "%s:%d added reg to pic16_dynAllocRegs = %p\n", __FUNCTION__, __LINE__, pic16_dynAllocRegs); + debugLog ("%s of type %s for register rIdx: %d (0x%x)\n", __FUNCTION__, debugLogRegType (type), dynrIdx-1, dynrIdx-1); #if 0 @@ -569,6 +597,7 @@ allocReg (short type) __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree); #endif if(reg) { + reg->isFree=0; reg->accessBank = 1; /* this is a temporary register alloc in accessBank */ reg->isLocal = 1; /* this is a local frame register */ // reg->wasUsed = 1; @@ -607,7 +636,7 @@ pic16_dirregWithName (char *name) while(reg) { if(STRCASECMP(reg->name, name) == 0) { -// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey); +// fprintf(stderr, "%s:%d: FOUND name = %s\thash = %d\n", __FUNCTION__, __LINE__, reg->name, hkey); return(reg); } @@ -634,7 +663,7 @@ pic16_allocregWithName (char *name) hkey = regname2key(name); -// fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); + fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey); reg = hTabFirstItemWK(dynAllocRegNames, hkey); @@ -985,7 +1014,7 @@ regs *pic16_typeRegWithIdx (int idx, int type, int fixed) regs *dReg; debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx); -// fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx); +// fprintf(stderr, "%s - requesting index = 0x%x (type = %d [%s])\n", __FUNCTION__, idx, type, decodeRegType(type)); switch (type) { @@ -1000,6 +1029,11 @@ regs *pic16_typeRegWithIdx (int idx, int type, int fixed) return dReg; } + if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx, fixed)) != NULL ) { + debugLog ("Found an Internal Register!\n"); + return dReg; + } + break; case REG_STK: if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) { @@ -1071,10 +1105,10 @@ pic16_allocWithIdx (int idx) debugLog ("Dynamic Register not found\n"); - +// return (NULL); //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx); werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "regWithIdx not found"); + "allocWithIdx not found"); exit (1); } @@ -1096,7 +1130,8 @@ pic16_findFreeReg(short type) case REG_GPR: if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL) return dReg; - return allocReg( REG_GPR ); //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL)); +// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); + return allocReg( REG_GPR ); case REG_STK: @@ -1123,7 +1158,8 @@ pic16_findFreeRegNext(short type, regs *creg) case REG_GPR: if((dReg = regFindFreeNext(pic16_dynAllocRegs, creg)) != NULL) return dReg; - return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); +// return (addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL))); + return (allocReg( REG_GPR ) ); case REG_STK: @@ -2860,6 +2896,7 @@ regTypeNum () static DEFSETFUNC (markRegFree) { ((regs *)item)->isFree = 1; +// ((regs *)item)->wasUsed = 0; return 0; } @@ -3386,6 +3423,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) bitVect *uses; iCode *dic, *sic; + return NULL; + debugLog ("%s\n", __FUNCTION__); /* if returning a literal then do nothing */ if (!IS_SYMOP (op)) @@ -4043,44 +4082,17 @@ pic16_packRegisters (eBBlock * ebp) #if 0 - /* if this is an arithmetic operation - * && result or left is not rematerializable (so it is a plain arithmetic op) - * && and left is not used after this iCode */ + /* try to optimize FSR0 usage when reading data memory pointers */ - if(getenv("OPTIMIZE_NEAR_POINTER_GET")) - - if (IS_ARITHMETIC_OP(ic) - && !IS_OP_LITERAL (IC_LEFT (ic)) - && !OP_SYMBOL (IC_RESULT(ic))->rematiCode - && !OP_SYMBOL (IC_LEFT(ic))->rematiCode - && (OP_LIVETO (IC_LEFT(ic) ) <= ic->seq) - ) { - iCode *dic = ic->prev; - - /* search backwards to find assignment from a remat pointer */ - while(dic && dic->seq >= OP_LIVEFROM( IC_LEFT(ic) )) { - - /* is it a pointer_get? */ - if(POINTER_GET(dic) - && IS_DATA_PTR(OP_SYM_TYPE (IC_LEFT (dic)))) { - fprintf(stderr, "%s:%d `%s' is a data pointer (ic seq: %d)\n", __FILE__, __LINE__, - OP_SYMBOL(IC_LEFT(dic))->rname, dic->seq); - - /* so we can replace ic->left with dic->left, & remove assignment */ - ReplaceOpWithCheaperOp( &IC_LEFT(ic), IC_LEFT(dic) ); - - bitVectUnSetBit(OP_USES( IC_LEFT(ic) ), ic->key); - bitVectUnSetBit(OP_DEFS( IC_RESULT(dic) ), dic->key ); - -// dic->op = DUMMY_READ_VOLATILE; -#if 1 - remiCodeFromeBBlock(ebp, dic); - hTabDeleteItem(&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); -#endif - break; - } - dic = dic->prev; - } + if(getenv("OPTIMIZE_NEAR_POINTER_GET")) { + static int fsr0usage=0; + static iCode *usic; + + if(POINTER_GET(ic) /* this is a memory read */ + && ic->loop /* this is in a loop */ + ) { + fprintf(stderr, "might optimize FSR0 usage\n"); + } } #endif @@ -4368,6 +4380,9 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count) printiCChain (ebbs[i]->sch, debugF); } } + +void dbg_dumpregusage(void); + /*-----------------------------------------------------------------*/ /* pic16_assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ @@ -4385,6 +4400,24 @@ pic16_assignRegisters (ebbIndex * ebbi) _inRegAllocator = 1; + pic16_freeAllRegs(); +#if 0 + dbg_dumpregusage(); + /* clear whats left over from peephole parser */ + pic16_dynAllocRegs= newSet(); //NULL; +// pic16_dynStackRegs= newSet(); //NULL; +// pic16_dynProcessorRegs=newSet(); //NULL; +// pic16_dynDirectRegs=newSet(); //NULL; +// pic16_dynDirectBitRegs=newSet(); //NULL; +// pic16_dynInternalRegs=newSet(); //NULL; +// pic16_dynAccessRegs=newSet(); //NULL; + +// dynDirectRegNames=NULL; + dynAllocRegNames=NULL; +// dynProcRegNames=NULL; +// dynAccessRegNames=NULL; +#endif + setToNull ((void *) &_G.funcrUsed); pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; @@ -4461,6 +4494,8 @@ pic16_assignRegisters (ebbIndex * ebbi) if (options.dump_rassgn) dumpEbbsToFileExt (DUMP_RASSGN, ebbi); +// dumpLR(ebbs, count); + /* now get back the chain */ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); -- 2.30.2