From: vrokas Date: Fri, 17 Sep 2004 00:27:35 +0000 (+0000) Subject: * src/pic16/gen.c (mov2f): New function to move an operand to X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=cef02d0dae9b2c3d273d09f5026aef204ac39809;p=fw%2Fsdcc * src/pic16/gen.c (mov2f): New function to move an operand to another without considering if it is a literal or a register, * (pic16_sameRegs): don't check if they are both AOP_REG, * (AccRsh): removed andmask=0 lines, * (genLeftShift): duplicated to be improved in future versions, * src/pic16/main.c (_process_pragma): emit stack default size in hex, * src/pic16/pcode.c: added POC_INFSNZW, updated inverted_op fields in POC_INCFSZ, POC_INCFSZW, POC_INFSNZ, * (pic16initMnemonics): added initialization for POC_INFSNZW, * (insertBankSwitch): fixed inserting banksel directives algorithm for instructions that follow a skip instruction, this fixes a report for broken subtraction code generation, * src/pic16/ralloc.c (deassignLRs): do not free register if current iCode is a left op, just in case result and right share the same registers git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3499 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index ac6a8335..7fcc0a42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2004-09-17 Vangelis Rokas + + * src/pic16/gen.c (mov2f): New function to move an operand to + another without considering if it is a literal or a register, + * (pic16_sameRegs): don't check if they are both AOP_REG, + * (AccRsh): removed andmask=0 lines, + * (genLeftShift): duplicated to be improved in future versions, + * src/pic16/main.c (_process_pragma): emit stack default size in hex, + * src/pic16/pcode.c: added POC_INFSNZW, updated inverted_op fields + in POC_INCFSZ, POC_INCFSZW, POC_INFSNZ, + * (pic16initMnemonics): added initialization for POC_INFSNZW, + * (insertBankSwitch): fixed inserting banksel directives algorithm + for instructions that follow a skip instruction, this fixes a report + for broken subtraction code generation, + * src/pic16/ralloc.c (deassignLRs): do not free register if current + iCode is a left op, just in case result and right share the same + registers + 2004-09-16 Erik Petrich * src/hc08/main.c, diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 6ec83ba7..5c67e4dc 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -58,6 +58,7 @@ 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 mov2w (asmop *aop, int offset); +static void mov2f(asmop *dsr, asmop *src, int offset); //static int aopIdx (asmop *aop, int offset); int pic16_labelOffset=0; @@ -983,9 +984,11 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 ) if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE; +#if 0 if (aop1->type != AOP_REG || aop2->type != AOP_REG ) return FALSE ; +#endif if (aop1->size != aop2->size ) return FALSE ; @@ -2051,6 +2054,17 @@ static void mov2w (asmop *aop, int offset) } +static void mov2f(asmop *dst, asmop *src, int offset) +{ + if(is_LitAOp(src)) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset), + pic16_popGet(dst, offset))); + } +} + /* push pcop into stack */ void pic16_pushpCodeOp(pCodeOp *pcop) @@ -7603,12 +7617,10 @@ static void AccRsh (int shCount, int andmask) return; break; case 1 : pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); -// andmask = 0; /* no need */ break; case 2 : pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); -// andmask = 0; /* no need */ break; case 3 : pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); @@ -8554,6 +8566,192 @@ static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian) /* genLeftShift - generates code for left shifting */ /*-----------------------------------------------------------------*/ static void genLeftShift (iCode *ic) +{ + operand *left,*right, *result; + int size, offset; +// char *l; + symbol *tlbl , *tlbl1; + pCodeOp *pctemp; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + result = IC_RESULT(ic); + + pic16_aopOp(right,ic,FALSE); + + /* if the shift count is known then do it + as efficiently as possible */ + if (AOP_TYPE(right) == AOP_LIT) { + genLeftShiftLiteral (left,right,result,ic); + return ; + } + + /* shift count is unknown then we have to form + * a loop. Get the loop count in WREG : Note: we take + * only the lower order byte since shifting + * more than 32 bits make no sense anyway, ( the + * largest size of an object can be only 32 bits ) */ + + pic16_aopOp(left,ic,FALSE); + pic16_aopOp(result,ic,FALSE); + + /* now move the left to the result if they are not the + * same, and if size > 1, + * and if right is not same to result (!!!) -- VR */ + if (!pic16_sameRegs(AOP(left),AOP(result)) + && (AOP_SIZE(result) > 1)) { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + size = AOP_SIZE(result); + offset=0; + while (size--) { + +#if 0 + l = pic16_aopGet(AOP(left),offset,FALSE,TRUE); + if (*l == '@' && (IS_AOP_PREG(result))) { + + pic16_emitcode("mov","a,%s",l); + pic16_aopPut(AOP(result),"a",offset); + } else +#endif + { + /* we don't know if left is a literal or a register, take care -- VR */ + mov2f(AOP(result), AOP(left), offset); + } + offset++; + } + } + + size = AOP_SIZE(result); + + /* if it is only one byte then */ + if (size == 1) { + if(optimized_for_speed) { + pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe)); + pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); + } else { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + tlbl = newiTempLabel(NULL); + +#if 1 + /* this is already done, why change it? */ + if (!pic16_sameRegs(AOP(left),AOP(result))) { + mov2f(AOP(result), AOP(left), 0); + } +#endif + + pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0)); + pic16_emitpLabel(tlbl->key); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1)); + emitSKPC; + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + } + goto release ; + } + + if (pic16_sameRegs(AOP(left),AOP(result))) { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + tlbl = newiTempLabel(NULL); + pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); + genMultiAsm(POC_RRCF, result, size,1); + pic16_emitpLabel(tlbl->key); + genMultiAsm(POC_RLCF, result, size,0); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1)); + emitSKPC; + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + goto release; + } + + //tlbl = newiTempLabel(NULL); + //offset = 0 ; + //tlbl1 = newiTempLabel(NULL); + + //reAdjustPreg(AOP(result)); + + //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + //pic16_emitcode("","%05d_DS_:",tlbl->key+100); + //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE); + //MOVA(l); + //pic16_emitcode("add","a,acc"); + //pic16_aopPut(AOP(result),"a",offset++); + //while (--size) { + // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE); + // MOVA(l); + // pic16_emitcode("rlc","a"); + // pic16_aopPut(AOP(result),"a",offset++); + //} + //reAdjustPreg(AOP(result)); + + //pic16_emitcode("","%05d_DS_:",tlbl1->key+100); + //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + + + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); + + size = AOP_SIZE(result); + offset = 1; + + pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */ + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + + /* offset should be 0, 1 or 3 */ + + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1)); + emitSKPNZ; + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key)); + + pic16_emitpcode(POC_MOVWF, pctemp); + + + pic16_emitpLabel(tlbl->key); + + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + while(--size) + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++)); + + pic16_emitpcode(POC_DECFSZ, pctemp); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + pic16_emitpLabel(tlbl1->key); + + pic16_popReleaseTempReg(pctemp); + + + release: + pic16_freeAsmop (right,NULL,ic,TRUE); + pic16_freeAsmop(left,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); +} + + + +#if 0 +#error old code (left here for reference) +/*-----------------------------------------------------------------*/ +/* genLeftShift - generates code for left shifting */ +/*-----------------------------------------------------------------*/ +static void genLeftShift (iCode *ic) { operand *left,*right, *result; int size, offset; @@ -8591,6 +8789,8 @@ static void genLeftShift (iCode *ic) if (!pic16_sameRegs(AOP(left),AOP(result)) && AOP_SIZE(result) > 1) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = AOP_SIZE(result); offset=0; while (size--) { @@ -8600,9 +8800,9 @@ static void genLeftShift (iCode *ic) pic16_emitcode("mov","a,%s",l); pic16_aopPut(AOP(result),"a",offset); } else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - //pic16_aopPut(AOP(result),l,offset); + + /* we don't know if left is a literal or a register, take care -- VR */ + mov2f(AOP(result), AOP(left), offset); } offset++; } @@ -8627,10 +8827,14 @@ static void genLeftShift (iCode *ic) pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); } else { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + tlbl = newiTempLabel(NULL); if (!pic16_sameRegs(AOP(left),AOP(result))) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + mov2f(AOP(result), AOP(left), 0); + +// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); +// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); } pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); @@ -8646,6 +8850,8 @@ static void genLeftShift (iCode *ic) if (pic16_sameRegs(AOP(left),AOP(result))) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + tlbl = newiTempLabel(NULL); pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); genMultiAsm(POC_RRCF, result, size,1); @@ -8719,6 +8925,7 @@ static void genLeftShift (iCode *ic) pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* genrshOne - right shift a one byte quantity by known count */ diff --git a/src/pic16/main.c b/src/pic16/main.c index c62ea9dd..88103383 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -187,7 +187,7 @@ _process_pragma(const char *sz) if(stackLen < 1) { stackLen = 64; - fprintf(stderr, "%s:%d setting stack to default size 0x%x\n", __FILE__, __LINE__, stackLen); + fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen); } // fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen); diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 8ed4d51e..463a2f51 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -1274,7 +1274,7 @@ pCodeInstruction pic16_pciINCFSZ = { 0, // fast call/return mode select bit 0, // second memory operand 0, // second literal operand - POC_NOP, + POC_INFSNZ, PCC_REGISTER, // inCond PCC_REGISTER , // outCond PCI_MAGIC @@ -1301,7 +1301,7 @@ pCodeInstruction pic16_pciINCFSZW = { 0, // fast call/return mode select bit 0, // second memory operand 0, // second literal operand - POC_NOP, + POC_INFSNZW, PCC_REGISTER, // inCond PCC_W , // outCond PCI_MAGIC @@ -1313,7 +1313,7 @@ pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New genericDestruct, genericPrint}, POC_INFSNZ, - "INCFSNZ", + "INFSNZ", NULL, // from branch NULL, // to branch NULL, // label @@ -1328,12 +1328,39 @@ pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New 0, // fast call/return mode select bit 0, // second memory operand 0, // second literal operand - POC_NOP, + POC_INCFSZ, PCC_REGISTER, // inCond PCC_REGISTER , // outCond PCI_MAGIC }; +pCodeInstruction pic16_pciINFSNZW = { // vrokas - New + {PC_OPCODE, NULL, NULL, 0, NULL, + // AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_INFSNZW, + "INFSNZ", + NULL, // from branch + NULL, // to branch + NULL, // label + NULL, // operand + NULL, // flow block + NULL, // C source + 3, // num ops + 0,0, // dest, bit instruction + 1,1, // branch, skip + 0, // literal operand + 1, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_INCFSZW, + PCC_REGISTER, // inCond + PCC_W , // outCond + PCI_MAGIC +}; + pCodeInstruction pic16_pciIORWF = { {PC_OPCODE, NULL, NULL, 0, NULL, // genericAnalyze, @@ -3003,6 +3030,7 @@ void pic16initMnemonics(void) pic16Mnemonics[POC_INCFSZ] = &pic16_pciINCFSZ; pic16Mnemonics[POC_INCFSZW] = &pic16_pciINCFSZW; pic16Mnemonics[POC_INFSNZ] = &pic16_pciINFSNZ; + pic16Mnemonics[POC_INFSNZW] = &pic16_pciINFSNZW; pic16Mnemonics[POC_IORWF] = &pic16_pciIORWF; pic16Mnemonics[POC_IORFW] = &pic16_pciIORFW; pic16Mnemonics[POC_IORLW] = &pic16_pciIORLW; @@ -6022,7 +6050,7 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow) pCodeOp *pic16_popGetLabel(unsigned int key); extern int pic16_labelOffset; -static void insertBankSwitch(int position, pCode *pc) +static void insertBankSwitch(unsigned char position, pCode *pc) { pCode *new_pc; @@ -6037,7 +6065,7 @@ static void insertBankSwitch(int position, pCode *pc) // position = 0; // position is always before (sanity check!) #if 0 - fprintf(stderr, "%s:%d: inserting bank switch\n", __FUNCTION__, __LINE__); + fprintf(stderr, "%s:%d: inserting bank switch (pos: %d)\n", __FUNCTION__, __LINE__, position); pc->print(stderr, pc); #endif @@ -6057,8 +6085,10 @@ static void insertBankSwitch(int position, pCode *pc) case 2: { symbol *tlbl; - pCode *pcnext, *pcprev, *npci; + pCode *pcnext, *pcprev, *npci, *ppc; PIC_OPCODE ipci; + int ofs1=0, ofs2=0, len=0; + /* just like 0, but previous was a skip instruction, * so some care should be taken */ @@ -6070,23 +6100,23 @@ static void insertBankSwitch(int position, pCode *pc) ipci = PCI(pcprev)->inverted_op; npci = pic16_newpCode(ipci, PCI(pcprev)->pcop); -#if 1 - PCI(npci)->from = PCI(pcprev)->from; - PCI(npci)->to = PCI(pcprev)->to; - PCI(npci)->label = PCI(pcprev)->label; - PCI(npci)->pcflow = PCI(pcprev)->pcflow; - PCI(npci)->cline = PCI(pcprev)->cline; -#endif - -// memmove(PCI(pcprev), PCI(npci), sizeof(pCode) + sizeof(PIC_OPCODE) + sizeof(char const * const)); +// fprintf(stderr, "%s:%d old OP: %d\tnew OP: %d\n", __FILE__, __LINE__, PCI(pcprev)->op, ipci); -#if 1 - pic16_pCodeInsertAfter(pcprev->prev, npci); - /* unlink the pCode */ - pcprev->prev->next = pcprev->next; - pcprev->next->prev = pcprev->prev; -#endif + /* copy info from old pCode */ + ofs1 = ofs2 = sizeof( pCode ) + sizeof(PIC_OPCODE); + len = sizeof(pCodeInstruction) - ofs1 - sizeof( char const * const *); + ofs1 += strlen( PCI(pcprev)->mnemonic) + 1; + ofs2 += strlen( PCI(npci)->mnemonic) + 1; + memcpy(&PCI(npci)->from, &PCI(pcprev)->from, (unsigned int)(&(PCI(npci)->pci_magic)) - (unsigned int)(&(PCI(npci)->from))); + PCI(npci)->op = PCI(pcprev)->inverted_op; + /* unlink old pCode */ + ppc = pcprev->prev; + ppc->next = pcprev->next; + pcprev->next->prev = ppc; + pic16_pCodeInsertAfter(ppc, npci); + + /* extra instructions to handle invertion */ pcnext = pic16_newpCode(POC_GOTO, pic16_popGetLabel(tlbl->key)); pic16_pCodeInsertAfter(pc->prev, pcnext); pic16_pCodeInsertAfter(pc->prev, new_pc); @@ -6534,7 +6564,7 @@ static void pic16_FixRegisterBanking(pBlock *pb) pCode *pc=NULL; pCode *pcprev=NULL; regs *reg, *prevreg; - int flag=0; + unsigned char flag=0; if(!pb) return; @@ -6591,9 +6621,10 @@ static void pic16_FixRegisterBanking(pBlock *pb) * not a skip type instruction */ pcprev = findPrevpCode(pc->prev, PC_OPCODE); - /* FIXME: if previous is SKIP pCode, we should move the BANKSEL - * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */ - flag = 0; + flag = 0; /* add before this instruction */ + + /* if previous instruction is a skip one, then set flag + * to 2 and call insertBankSwitch */ if(pcprev && isPCI_SKIP(pcprev))flag=2; //goto loop; prevreg = reg; diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index b9d044c1..c290d3ad 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -228,6 +228,7 @@ typedef enum POC_INCFSZ, POC_INCFSZW, POC_INFSNZ, + POC_INFSNZW, POC_IORWF, POC_IORFW, POC_IORLW, diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index ffd938c2..d06ecc89 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -1970,6 +1970,13 @@ deassignLRs (iCode * ic, eBBlock * ebp) if (!bitVectBitValue (_G.regAssigned, sym->key)) continue; + /* special case for shifting: there is a case where shift count + * can be allocated in the same register as the result, so do not + * free right registers if same as result registers, cause genShiftLeft + * will fail -- VR */ + if(ic->op == LEFT_OP) + continue; + /* special case check if this is an IFX & the privious one was a pop and the previous one was not spilt then keep track