Support custom match conditions to for instruction matching
These additional match conditions furthermore allows an instruction to bypass the opcode uniqueness check of the instruction matcher.
MODIFY
src/assembler/instruction.h
src/assembler/instruction.h
#include <type_traits>
#include <vector>
+#include "STLExtras.h"
#include "binutils.h"
#include "isa/isainfo.h"
#include "math.h"
@@ -419,6 +420,12 @@ public:
m_byteSize = nBits / CHAR_BIT;
}
+ void addExtraMatchCond(const std::function<bool(Instr_T)>& f) { m_extraMatchConditions.push_back(f); }
+ bool hasExtraMatchConds() const { return !m_extraMatchConditions.empty(); }
+ bool matchesWithExtras(Instr_T instr) {
+ return llvm::all_of(m_extraMatchConditions, [&](const auto& f) { return f(instr); });
+ }
+
private:
std::function<AssembleRes<Reg_T>(const Instruction<Reg_T>*, const TokenizedSrcLine&)> m_assembler;
std::function<DisassembleRes(const Instruction<Reg_T>*, const Instr_T, const Reg_T, const ReverseSymbolMap&)>
@@ -428,6 +435,9 @@ private:
const int m_expectedTokens;
std::vector<std::shared_ptr<Field<Reg_T>>> m_fields;
unsigned m_byteSize = -1;
+
+ /// An optional set of additional match conditions, if the default opcode-matching is insufficient.
+ std::vector<std::function<bool(Instr_T)>> m_extraMatchConditions;
};
template <typename Reg_T>

MODIFY
src/assembler/matcher.h
src/assembler/matcher.h
@@ -61,11 +61,11 @@ private:
if (isRoot || node.matcher.matches(instruction)) {
if (node.children.size() > 0) {
for (const auto& child : node.children) {
- if (auto matchedInstr = matchInstructionRec(instruction, child, false)) {
+ if (auto matchedInstr = matchInstructionRec(instruction, child, false); matchedInstr != nullptr) {
return matchedInstr;
}
}
- } else {
+ } else if (node.instruction->matchesWithExtras(instruction)) {
return &(*node.instruction);
}
}
@@ -79,7 +79,7 @@ private:
for (const auto& instr : instructions) {
if (auto instrRef = instr.get()) {
const size_t nOpParts = instrRef->getOpcode().opParts.size();
- if (nOpParts < fieldDepth) {
+ if (nOpParts < fieldDepth && !instrRef->hasExtraMatchConds()) {
QString err =
"Instruction '" + instr->name() +
"' cannot be decoded; aliases with other instruction (Needs more discernable parts)\n";

Support custom match conditions to for instruction matching

These additional match conditions furthermore allows an instruction to bypass the opcode uniqueness check of the instruction matcher.