From fdae13dc9bca4bdd2284a7437c0c50fe615228a2 Mon Sep 17 00:00:00 2001 From: sdattalo Date: Sat, 18 May 2002 22:43:04 +0000 Subject: [PATCH] Fixed fatal infinite loop in pcode optimizer. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2017 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic/gen.c | 227 ++++++++++++++++++++++----------------- src/pic/pcode.c | 5 +- src/pic/pcodepeep.c | 31 +++--- src/regression/rotate5.c | 25 +++++ 4 files changed, 177 insertions(+), 111 deletions(-) diff --git a/src/pic/gen.c b/src/pic/gen.c index 41d54342..77c064b1 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -7299,97 +7299,140 @@ static void genRightShiftLiteral (operand *left, /*-----------------------------------------------------------------*/ static void genSignedRightShift (iCode *ic) { - operand *right, *left, *result; - int size, offset; - char *l; - symbol *tlbl, *tlbl1 ; + operand *right, *left, *result; + int size, offset; + // char *l; + symbol *tlbl, *tlbl1 ; + pCodeOp *pctemp; - /* we do it the hard way put the shift count in b - and loop thru preserving the sign */ - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); - right = IC_RIGHT(ic); - left = IC_LEFT(ic); - result = IC_RESULT(ic); + /* we do it the hard way put the shift count in b + and loop thru preserving the sign */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp(right,ic,FALSE); + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + result = IC_RESULT(ic); + aopOp(right,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); - if ( AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic,1); - return ; - } - /* shift count is unknown then we have to form - a loop get the loop count in B : Note: we take - only the lower order byte since shifting - more that 32 bits make no sense anyway, ( the - largest size of an object can be only 32 bits ) */ - pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - pic14_emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + if ( AOP_TYPE(right) == AOP_LIT) { + genRightShiftLiteral (left,right,result,ic,1); + return ; + } + /* shift count is unknown then we have to form + a loop get the loop count in B : Note: we take + only the lower order byte since shifting + more that 32 bits make no sense anyway, ( the + largest size of an object can be only 32 bits ) */ + + //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); + //pic14_emitcode("inc","b"); + //freeAsmop (right,NULL,ic,TRUE); + //aopOp(left,ic,FALSE); + //aopOp(result,ic,FALSE); + + /* now move the left to the result if they are not the + same */ + if (!pic14_sameRegs(AOP(left),AOP(result)) && + AOP_SIZE(result) > 1) { - /* now move the left to the result if they are not the - same */ - if (!pic14_sameRegs(AOP(left),AOP(result)) && - AOP_SIZE(result) > 1) { + size = AOP_SIZE(result); + offset=0; + while (size--) { + /* + l = aopGet(AOP(left),offset,FALSE,TRUE); + if (*l == '@' && IS_AOP_PREG(result)) { - size = AOP_SIZE(result); - offset=0; - while (size--) { - l = aopGet(AOP(left),offset,FALSE,TRUE); - if (*l == '@' && IS_AOP_PREG(result)) { + pic14_emitcode("mov","a,%s",l); + aopPut(AOP(result),"a",offset); + } else + aopPut(AOP(result),l,offset); + */ + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - pic14_emitcode("mov","a,%s",l); - aopPut(AOP(result),"a",offset); - } else - aopPut(AOP(result),l,offset); - offset++; - } + offset++; } + } - /* mov the highest order bit to OVR */ - tlbl = newiTempLabel(NULL); - tlbl1= newiTempLabel(NULL); + /* mov the highest order bit to OVR */ + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); - size = AOP_SIZE(result); - offset = size - 1; - pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE)); - pic14_emitcode("rlc","a"); - pic14_emitcode("mov","ov,c"); - /* if it is only one byte then */ - if (size == 1) { - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_emitcode("mov","c,ov"); - pic14_emitcode("rrc","a"); - pic14_emitcode("","%05d_DS_:",tlbl1->key+100); - pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; - } + size = AOP_SIZE(result); + offset = size - 1; - reAdjustPreg(AOP(result)); + pctemp = popGetTempReg(); /* grab a temporary working register. */ + + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + + /* offset should be 0, 1 or 3 */ + emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3))); + emitSKPNZ; + emitpcode(POC_GOTO, popGetLabel(tlbl1->key)); + + emitpcode(POC_MOVWF, pctemp); + + + emitpLabel(tlbl->key); + + emitpcode(POC_RLFW, popGet(AOP(result),offset)); + emitpcode(POC_RRF, popGet(AOP(result),offset)); + + while(--size) { + emitpcode(POC_RRF, popGet(AOP(result),--offset)); + } + + emitpcode(POC_DECFSZ, pctemp); + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + emitpLabel(tlbl1->key); + + popReleaseTempReg(pctemp); +#if 0 + size = AOP_SIZE(result); + offset = size - 1; + pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("rlc","a"); + pic14_emitcode("mov","ov,c"); + /* if it is only one byte then */ + if (size == 1) { + l = aopGet(AOP(left),0,FALSE,FALSE); + MOVA(l); pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); pic14_emitcode("mov","c,ov"); - while (size--) { - l = aopGet(AOP(result),offset,FALSE,FALSE); - MOVA(l); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",offset--); - } - reAdjustPreg(AOP(result)); + pic14_emitcode("rrc","a"); pic14_emitcode("","%05d_DS_:",tlbl1->key+100); pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + aopPut(AOP(result),"a",0); + goto release ; + } -release: - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + reAdjustPreg(AOP(result)); + pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("mov","c,ov"); + while (size--) { + l = aopGet(AOP(result),offset,FALSE,FALSE); + MOVA(l); + pic14_emitcode("rrc","a"); + aopPut(AOP(result),"a",offset--); + } + reAdjustPreg(AOP(result)); + pic14_emitcode("","%05d_DS_:",tlbl1->key+100); + pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + + release: +#endif + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); + freeAsmop(right,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -7470,32 +7513,22 @@ static void genRightShift (iCode *ic) /* if it is only one byte then */ if (size == 1) { -/* - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - CLRC; - pic14_emitcode("rrc","a"); - pic14_emitcode("","%05d_DS_:",tlbl1->key+100); - pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); - aopPut(AOP(result),"a",0); -*/ - tlbl = newiTempLabel(NULL); - if (!pic14_sameRegs(AOP(left),AOP(result))) { - emitpcode(POC_MOVFW, popGet(AOP(left),0)); - emitpcode(POC_MOVWF, popGet(AOP(result),0)); - } - emitpcode(POC_COMFW, popGet(AOP(right),0)); - emitpcode(POC_RLF, popGet(AOP(result),0)); - emitpLabel(tlbl->key); - emitpcode(POC_RRF, popGet(AOP(result),0)); - emitpcode(POC_ADDLW, popGetLit(1)); - emitSKPC; - emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + tlbl = newiTempLabel(NULL); + if (!pic14_sameRegs(AOP(left),AOP(result))) { + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + } - goto release ; + emitpcode(POC_COMFW, popGet(AOP(right),0)); + emitpcode(POC_RLF, popGet(AOP(result),0)); + emitpLabel(tlbl->key); + emitpcode(POC_RRF, popGet(AOP(result),0)); + emitpcode(POC_ADDLW, popGetLit(1)); + emitSKPC; + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + + goto release ; } reAdjustPreg(AOP(result)); diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 2e1e2b58..2c0c5426 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -2802,7 +2802,10 @@ pCode * findNextInstruction(pCode *pc) while(pc) { if((pc->type == PC_OPCODE) || (pc->type == PC_WILD)) return pc; - +#ifdef PCODE_DEBUG + fprintf(stderr,"findNextInstruction: "); + printpCode(stderr, pc); +#endif pc = pc->next; } diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index a6d1e862..3352e97c 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -1414,27 +1414,28 @@ int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) if(!pcops || !pcopd) return 0; - + /* fprintf(stderr," Comparing operands %s", get_op( pcops)); fprintf(stderr," to %s\n", get_op( pcopd)); + */ if(pcops->type != pcopd->type) { - fprintf(stderr," - fail - diff types\n"); + //fprintf(stderr," - fail - diff types\n"); return 0; // different types } if(!pcops->name || !pcopd->name || strcmp(pcops->name,pcopd->name)) { - fprintf(stderr," - fail - diff names\n"); + //fprintf(stderr," - fail - diff names\n"); return 0; // different names } switch(pcops->type) { case PO_DIR: if( PCOR(pcops)->instance != PCOR(pcopd)->instance) { - fprintf(stderr, " - fail different instances\n"); + //fprintf(stderr, " - fail different instances\n"); return 0; } break; @@ -1442,7 +1443,7 @@ int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd) break; } - fprintf(stderr," - pass\n"); + //fprintf(stderr," - pass\n"); return 1; } @@ -1556,12 +1557,14 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) //if(PCI(pcs)->pcop->type == PO_GPR_TEMP) } else { - pcs->print(stderr,pcs); - pcd->print(stderr,pcd); + /* + pcs->print(stderr,pcs); + pcd->print(stderr,pcd); - fprintf(stderr, "comparing operands of these instructions, result %d\n", - pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]) - ); + fprintf(stderr, "comparing operands of these instructions, result %d\n", + pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]) + ); + */ return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]); } @@ -1778,7 +1781,7 @@ pCodeOp *pCodeOpCopy(pCodeOp *pcop) break; case PO_DIR: - fprintf(stderr,"pCodeOpCopy PO_DIR\n"); + //fprintf(stderr,"pCodeOpCopy PO_DIR\n"); pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcopnew)->r = PCOR(pcop)->r; PCOR(pcopnew)->rIdx = PCOR(pcop)->rIdx; @@ -1884,8 +1887,10 @@ int pCodePeepMatchRule(pCode *pc) pct = pct->next; //debug: //DFPRINTF((stderr," matched\n")); - if(!pcin) - DFPRINTF((stderr," end of code\n")); + if(!pcin && pct) { + DFPRINTF((stderr," partial match... no more code\n")); + matched = 0; + } if(!pct) DFPRINTF((stderr," end of rule\n")); } diff --git a/src/regression/rotate5.c b/src/regression/rotate5.c index c7446b21..815f13f2 100644 --- a/src/regression/rotate5.c +++ b/src/regression/rotate5.c @@ -203,10 +203,35 @@ void main(void) achar0 = 0x40; shift_right_6(); + + achar0 = 0xff; + achar1 = 0xff; + shift_right_1(); + + achar0 = 0xfe; + achar1 = 0xff; + shift_right_1(); + + achar0 = 0xfc; + shift_right_2(); + + achar0 = 0xf8; + shift_right_3(); + + achar0 = 0xf0; + shift_right_4(); + + achar0 = 0xe0; + shift_right_5(); + + achar0 = 0xc0; + shift_right_6(); + achar0 = 0x80; achar1 = 0xff; shift_right_7(); + success=failures; done(); } -- 2.30.2