1010#define BOLT_CORE_MCINSTUTILS_H
1111
1212#include " bolt/Core/BinaryBasicBlock.h"
13+ #include " bolt/Core/MCPlus.h"
1314#include < map>
1415#include < variant>
1516
@@ -177,11 +178,44 @@ static inline raw_ostream &operator<<(raw_ostream &OS,
177178
178179// / Instruction-matching helpers operating on a single instruction at a time.
179180// /
181+ // / The idea is to make low-level instruction matching as readable as possible.
182+ // / The classes contained in this namespace are intended to be used as a
183+ // / domain-specific language to match MCInst with the particular opcode and
184+ // / operands.
185+ // /
186+ // / The goals of this DSL include
187+ // / * matching a single instruction against a template consisting of the
188+ // / particular target-specific opcode and a pattern of operands
189+ // / * matching operands against the known values (such as 42, AArch64::X1 or
190+ // / "the value of --brk-operand=N command line argument")
191+ // / * capturing operands of an instruction ("whatever is the destination
192+ // / register of AArch64::ADDXri instruction, store it to Xd variable to be
193+ // / queried later")
194+ // / * expressing repeated operands of a single matched instruction (such as
195+ // / "ADDXri Xd, Xd, 42, 0" for an arbitrary register Xm) as well as across
196+ // / multiple calls to matchInst(), which is naturally achieved by combining
197+ // / capturing operands and matching against the known values
198+ // / * matching multi-instruction code patterns by sequentially calling
199+ // / matchInst() while passing around already matched operands
200+ // /
201+ // / The non-goals (compared to MCPlusBuilder::MCInstMatcher) include
202+ // / * matching an arbitrary tree of instructions in a single matchInst() call
203+ // / * encapsulation of target-specific knowledge ("match an increment of Xm
204+ // / by 42")
205+ // /
180206// / Unlike MCPlusBuilder::MCInstMatcher, this matchInst() function focuses on
181- // / the cases where a precise control over the instruction order is important:
207+ // / the cases where a precise control over the instruction order is important.
208+ // / For example, one has to match two particular instructions against the
209+ // / following pattern (for two different registers Xm and Xn)
210+ // /
211+ // / ADDXrs Xm, Xn, Xm, #0
212+ // / BR Xm
213+ // /
214+ // / and return the register holding the branch target. Assuming the instructions
215+ // / are available as MaybeAdd and MaybeBr, the following code can be used:
182216// /
183217// / // Bring the short names into the local scope:
184- // / using namespace MCInstMatcher ;
218+ // / using namespace LowLevelInstMatcherDSL ;
185219// / // Declare the registers to capture:
186220// / Reg Xn, Xm;
187221// / // Capture the 0th and 1st operands, match the 2nd operand against the
@@ -191,9 +225,13 @@ static inline raw_ostream &operator<<(raw_ostream &OS,
191225// / // Match the 0th operand against Xm:
192226// / if (!matchInst(MaybeBr, AArch64::BR, Xm))
193227// / return AArch64::NoRegister;
228+ // / // Manually check that Xm and Xn did not match the same register.
229+ // / if (Xm.get() == Xn.get())
230+ // / return AArch64::NoRegister;
194231// / // Return the matched register:
195232// / return Xm.get();
196- namespace MCInstMatcher {
233+ // /
234+ namespace LowLevelInstMatcherDSL {
197235
198236// The base class to match an operand of type T.
199237//
@@ -282,7 +320,7 @@ template <class... OpMatchers>
282320bool matchInst (const MCInst &Inst, unsigned Opcode, const OpMatchers &...Ops) {
283321 if (Inst.getOpcode () != Opcode)
284322 return false ;
285- assert (sizeof ...(Ops) <= Inst. getNumOperands ( ) &&
323+ assert (sizeof ...(Ops) <= MCPlus::getNumPrimeOperands (Inst ) &&
286324 " Too many operands are matched for the Opcode" );
287325
288326 // Ask each matcher to remember its current value in case of rollback.
@@ -301,7 +339,7 @@ bool matchInst(const MCInst &Inst, unsigned Opcode, const OpMatchers &...Ops) {
301339 return true ;
302340}
303341
304- } // namespace MCInstMatcher
342+ } // namespace LowLevelInstMatcherDSL
305343
306344} // namespace bolt
307345} // namespace llvm
0 commit comments