diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 3131a73e4a..428ac0763c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -4482,6 +4482,7 @@ void universal_action(Architecture *conf) actprop->addRule( new RuleIdentityEl("analysis") ); actprop->addRule( new RuleOrMask("analysis") ); actprop->addRule( new RuleAndMask("analysis") ); + actprop->addRule( new RuleOrConsume("analysis") ); actprop->addRule( new RuleOrCollapse("analysis") ); actprop->addRule( new RuleAndOrLump("analysis") ); actprop->addRule( new RuleShiftBitops("analysis") ); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc index 9cd6697cc5..39c0d3c937 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc @@ -390,6 +390,35 @@ int4 RuleAndMask::applyOp(PcodeOp *op,Funcdata &data) return 1; } +/// \class RuleOrConsume +/// \brief Simply OR with unconsumed input: `V = A | B => V = B if nzm(A) & consume(V) == 0 +void RuleOrConsume::getOpList(vector &oplist) const + +{ + oplist.push_back(CPUI_INT_OR); + oplist.push_back(CPUI_INT_XOR); +} + +int4 RuleOrConsume::applyOp(PcodeOp *op,Funcdata &data) + +{ + Varnode *outvn = op->getOut(); + int4 size = outvn->getSize(); + if (size > sizeof(uintb)) return 0; // FIXME: uintb should be arbitrary precision + uintb consume = outvn->getConsume(); + if ((consume & op->getIn(0)->getNZMask()) == 0) { + data.opRemoveInput(op,0); + data.opSetOpcode(op, CPUI_COPY); + return 1; + } + else if ((consume & op->getIn(1)->getNZMask()) == 0) { + data.opRemoveInput(op,1); + data.opSetOpcode(op, CPUI_COPY); + return 1; + } + return 0; +} + /// \class RuleOrCollapse /// \brief Collapse unnecessary INT_OR /// diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh index fe6b160a11..29113da32d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.hh @@ -128,6 +128,16 @@ public: virtual void getOpList(vector &oplist) const; virtual int4 applyOp(PcodeOp *op,Funcdata &data); }; +class RuleOrConsume : public Rule { +public: + RuleOrConsume(const string &g) : Rule(g, 0, "orconsume") {} ///< Constructor + virtual Rule *clone(const ActionGroupList &grouplist) const { + if (!grouplist.contains(getGroup())) return (Rule *)0; + return new RuleOrConsume(getGroup()); + } + virtual void getOpList(vector &oplist) const; + virtual int4 applyOp(PcodeOp *op,Funcdata &data); +}; class RuleOrCollapse : public Rule { public: RuleOrCollapse(const string &g) : Rule(g, 0, "orcollapse") {} ///< Constructor