GP-2956 Adjustment to RuleSubExtComm

This commit is contained in:
caheckman 2022-12-22 15:54:29 -05:00
parent 552eb9dd61
commit 2345c1289b

View file

@ -4019,6 +4019,10 @@ int4 RuleStoreVarnode::applyOp(PcodeOp *op,Funcdata &data)
/// This is in keeping with the philosophy to push SUBPIECE back earlier in the expression.
/// The original SUBPIECE is changed into the INT_ZEXT, but the original INT_ZEXT is
/// not changed, a new SUBPIECE is created.
/// There are corner cases, if the SUBPIECE doesn't hit extended bits or is ultimately unnecessary.
/// - `sub(zext(V),c) => sub(V,C)`
/// - `sub(zext(V),0) => zext(V)`
///
/// This rule also works with INT_SEXT.
void RuleSubExtComm::getOpList(vector<uint4> &oplist) const
@ -4029,24 +4033,37 @@ void RuleSubExtComm::getOpList(vector<uint4> &oplist) const
int4 RuleSubExtComm::applyOp(PcodeOp *op,Funcdata &data)
{
int4 subcut = (int4)op->getIn(1)->getOffset();
Varnode *base = op->getIn(0);
// Make sure subpiece preserves most sig bytes
if (op->getOut()->getSize()+subcut != base->getSize()) return 0;
if (!base->isWritten()) return 0;
PcodeOp *extop = base->getDef();
if ((extop->code()!=CPUI_INT_ZEXT)&&(extop->code()!=CPUI_INT_SEXT))
return 0;
Varnode *invn = extop->getIn(0);
if (invn->isFree()) return 0;
int4 subcut = (int4)op->getIn(1)->getOffset();
if (op->getOut()->getSize() + subcut <= invn->getSize()) {
// SUBPIECE doesn't hit the extended bits at all
data.opSetInput(op,invn,0);
if (invn->getSize() == op->getOut()->getSize()) {
data.opRemoveInput(op, 1);
data.opSetOpcode(op, CPUI_COPY);
}
return 1;
}
if (subcut >= invn->getSize()) return 0;
Varnode *newvn;
if (subcut != 0) {
PcodeOp *newop = data.newOp(2,op->getAddr());
data.opSetOpcode(newop,CPUI_SUBPIECE);
Varnode *newvn = data.newUniqueOut(invn->getSize()-subcut,newop);
newvn = data.newUniqueOut(invn->getSize()-subcut,newop);
data.opSetInput(newop,data.newConstant(op->getIn(1)->getSize(),(uintb)subcut),1);
data.opSetInput(newop,invn,0);
data.opInsertBefore(newop,op);
}
else
newvn = invn;
data.opRemoveInput(op,1);
data.opSetOpcode(op,extop->code());