more subvariable extension pushes

This commit is contained in:
caheckman 2020-02-28 12:13:34 -05:00
parent 1115b02862
commit 2ef4843e70
2 changed files with 25 additions and 8 deletions

View file

@ -301,10 +301,7 @@ bool SubvariableFlow::tryCallReturnPush(PcodeOp *op,ReplaceVarnode *rvn)
if (fc->isOutputLocked()) return false; if (fc->isOutputLocked()) return false;
if (fc->isOutputActive()) return false; // Don't trim while in the middle of figuring out return value if (fc->isOutputActive()) return false; // Don't trim while in the middle of figuring out return value
patchlist.push_front(PatchRecord()); // Push to the front of the patch list addPush(op,rvn);
patchlist.front().type = PatchRecord::push_patch;
patchlist.front().patchOp = op;
patchlist.front().in1 = rvn;
// pullcount += 1; // This is a push NOT a pull // pullcount += 1; // This is a push NOT a pull
return true; return true;
} }
@ -655,10 +652,7 @@ bool SubvariableFlow::traceBackward(ReplaceVarnode *rvn)
case CPUI_INT_SEXT: case CPUI_INT_SEXT:
if ((rvn->mask & calc_mask(op->getIn(0)->getSize())) != rvn->mask) { if ((rvn->mask & calc_mask(op->getIn(0)->getSize())) != rvn->mask) {
if ((rvn->mask & 1)!=0 && flowsize > op->getIn(0)->getSize()) { if ((rvn->mask & 1)!=0 && flowsize > op->getIn(0)->getSize()) {
patchlist.push_front(PatchRecord()); // Push to the front of the patch list addPush(op,rvn);
patchlist.front().type = PatchRecord::push_patch;
patchlist.front().patchOp = op;
patchlist.front().in1 = rvn;
return true; return true;
} }
break; // Check if subvariable comes through extension break; // Check if subvariable comes through extension
@ -903,6 +897,13 @@ bool SubvariableFlow::traceBackwardSext(ReplaceVarnode *rvn)
if (!createLink(rop,rvn->mask,i,op->getIn(i))) // Same inputs and mask if (!createLink(rop,rvn->mask,i,op->getIn(i))) // Same inputs and mask
return false; return false;
return true; return true;
case CPUI_INT_ZEXT:
if (op->getIn(0)->getSize() < flowsize) {
// zero extension from a smaller size still acts as a signed extension
addPush(op,rvn);
return true;
}
break;
case CPUI_INT_SEXT: case CPUI_INT_SEXT:
if (flowsize != op->getIn(0)->getSize()) return false; if (flowsize != op->getIn(0)->getSize()) return false;
rop = createOp(CPUI_COPY,1,rvn); rop = createOp(CPUI_COPY,1,rvn);
@ -1037,6 +1038,21 @@ void SubvariableFlow::createNewOut(ReplaceOp *rop,uintb mask)
res->def = rop; res->def = rop;
} }
/// \brief Mark an operation where original data-flow is being pushed into a subgraph variable
///
/// The operation is not manipulating the logical value, but it produces a variable containing
/// the logical value. The original op will not change but will just produce a smaller value.
/// \param pushOp is the operation to mark
/// \param rvn is the output variable holding the logical value
void SubvariableFlow::addPush(PcodeOp *pushOp,ReplaceVarnode *rvn)
{
patchlist.push_front(PatchRecord()); // Push to the front of the patch list
patchlist.front().type = PatchRecord::push_patch;
patchlist.front().patchOp = pushOp;
patchlist.front().in1 = rvn;
}
/// \brief Mark an operation where a subgraph variable is naturally copied into the original data-flow /// \brief Mark an operation where a subgraph variable is naturally copied into the original data-flow
/// ///
/// If the operations naturally takes the given logical value as input but the output /// If the operations naturally takes the given logical value as input but the output

View file

@ -105,6 +105,7 @@ class SubvariableFlow {
bool traceBackwardSext(ReplaceVarnode *rvn); ///< Trace logical data-flow backward assuming sign-extensions bool traceBackwardSext(ReplaceVarnode *rvn); ///< Trace logical data-flow backward assuming sign-extensions
bool createLink(ReplaceOp *rop,uintb mask,int4 slot,Varnode *vn); bool createLink(ReplaceOp *rop,uintb mask,int4 slot,Varnode *vn);
bool createCompareBridge(PcodeOp *op,ReplaceVarnode *inrvn,int4 slot,Varnode *othervn); bool createCompareBridge(PcodeOp *op,ReplaceVarnode *inrvn,int4 slot,Varnode *othervn);
void addPush(PcodeOp *pushOp,ReplaceVarnode *rvn);
void addTerminalPatch(PcodeOp *pullop,ReplaceVarnode *rvn); void addTerminalPatch(PcodeOp *pullop,ReplaceVarnode *rvn);
void addTerminalPatchSameOp(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot); void addTerminalPatchSameOp(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot);
void addBooleanPatch(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot); void addBooleanPatch(PcodeOp *pullop,ReplaceVarnode *rvn,int4 slot);