diff options
author | James Molloy <james.molloy@arm.com> | 2011-09-07 19:42:28 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2011-09-07 19:42:28 +0000 |
commit | a5d585685493d85d5cb72b831a68ec747ae55a86 (patch) | |
tree | 99483c51a38667c6c06586cc25abd758a8b2fccc /utils | |
parent | 2c207a0f677a2d78b768acb559e6b9f6f112a50d (diff) | |
download | llvm-a5d585685493d85d5cb72b831a68ec747ae55a86.tar.gz llvm-a5d585685493d85d5cb72b831a68ec747ae55a86.tar.bz2 llvm-a5d585685493d85d5cb72b831a68ec747ae55a86.tar.xz |
Second of a three-patch series aiming to fix MSR/MRS on Cortex-M. This adds predicate checking to the Disassembler.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139250 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/DisassemblerEmitter.cpp | 5 | ||||
-rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.cpp | 56 | ||||
-rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.h | 3 |
3 files changed, 58 insertions, 6 deletions
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp index 614ec3630f..24db080b26 100644 --- a/utils/TableGen/DisassemblerEmitter.cpp +++ b/utils/TableGen/DisassemblerEmitter.cpp @@ -132,11 +132,12 @@ void DisassemblerEmitter::run(raw_ostream &OS) { if (Target.getName() == "ARM" || Target.getName() == "Thumb") { FixedLenDecoderEmitter(Records, + "ARM", "if (!Check(S, ", ")) return MCDisassembler::Fail;", "S", "MCDisassembler::Fail", - "MCDisassembler::DecodeStatus S = MCDisassembler::Success;\n(void)S;").run(OS); + " MCDisassembler::DecodeStatus S = MCDisassembler::Success;\n(void)S;").run(OS); return; } - FixedLenDecoderEmitter(Records).run(OS); + FixedLenDecoderEmitter(Records, Target.getName()).run(OS); } diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index d1f271208e..27a5587031 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -330,6 +330,10 @@ protected: std::vector<unsigned> &EndBits, std::vector<uint64_t> &FieldVals, insn_t &Insn); + // Emits code to check the Predicates member of an instruction are true. + // Returns true if predicate matches were emitted, false otherwise. + bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,unsigned Opc); + // Emits code to decode the singleton. Return true if we have matched all the // well-known bits. bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc); @@ -571,8 +575,9 @@ void FilterChooser::emitTop(raw_ostream &o, unsigned Indentation, o.indent(Indentation) << "static MCDisassembler::DecodeStatus decode" << Namespace << "Instruction" << BitWidth << "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, " - << "const void *Decoder) {\n"; + << "const void *Decoder, const MCSubtargetInfo &STI) {\n"; o.indent(Indentation) << " unsigned tmp = 0;\n (void)tmp;\n" << Emitter->Locals << "\n"; + o.indent(Indentation) << " unsigned Bits = STI.getFeatureBits();\n"; ++Indentation; ++Indentation; // Emits code to decode the instructions. @@ -757,6 +762,43 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, } +static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, + std::string PredicateNamespace) { + const char *X = str.str().c_str(); + if (X[0] == '!') + o << "!(Bits & " << PredicateNamespace << "::" << &X[1] << ")"; + else + o << "(Bits & " << PredicateNamespace << "::" << X << ")"; +} + +bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, + unsigned Opc) { + ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); + for (unsigned i = 0; i < Predicates->getSize(); ++i) { + Record *Pred = Predicates->getElementAsRecord(i); + if (!Pred->getValue("AssemblerMatcherPredicate")) + continue; + + std::string P = Pred->getValueAsString("AssemblerCondString"); + + if (!P.length()) + continue; + + if (i != 0) + o << " && "; + + StringRef SR(P); + std::pair<StringRef, StringRef> pairs = SR.split(','); + while (pairs.second.size()) { + emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); + o << " && "; + pairs = pairs.second.split(','); + } + emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); + } + return Predicates->getSize() > 0; +} + // Emits code to decode the singleton. Return true if we have matched all the // well-known bits. bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, @@ -775,7 +817,9 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, // If we have matched all the well-known bits, just issue a return. if (Size == 0) { - o.indent(Indentation) << "{\n"; + o.indent(Indentation) << "if ("; + emitPredicateMatch(o, Indentation, Opc); + o << ") {\n"; o.indent(Indentation) << " MI.setOpcode(" << Opc << ");\n"; std::vector<OperandInfo>& InsnOperands = Operands[Opc]; for (std::vector<OperandInfo>::iterator @@ -792,7 +836,7 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc) << '\n'; - o.indent(Indentation) << "}\n"; + o.indent(Indentation) << "}\n"; // Closing predicate block. return true; } @@ -804,12 +848,16 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, for (I = Size; I != 0; --I) { o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} "; if (I > 1) - o << "&& "; + o << " && "; else o << "for singleton decoding...\n"; } o.indent(Indentation) << "if ("; + if (emitPredicateMatch(o, Indentation, Opc) > 0) { + o << " &&\n"; + o.indent(Indentation+4); + } for (I = Size; I != 0; --I) { NumBits = EndBits[I-1] - StartBits[I-1] + 1; diff --git a/utils/TableGen/FixedLenDecoderEmitter.h b/utils/TableGen/FixedLenDecoderEmitter.h index 535299c32d..7460f83c69 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.h +++ b/utils/TableGen/FixedLenDecoderEmitter.h @@ -50,6 +50,7 @@ struct OperandInfo { class FixedLenDecoderEmitter : public TableGenBackend { public: FixedLenDecoderEmitter(RecordKeeper &R, + std::string PredicateNamespace, std::string GPrefix = "if (", std::string GPostfix = " == MCDisassembler::Fail) return MCDisassembler::Fail;", std::string ROK = "MCDisassembler::Success", @@ -57,6 +58,7 @@ public: std::string L = "") : Records(R), Target(R), NumberedInstructions(Target.getInstructionsByEnumValue()), + PredicateNamespace(PredicateNamespace), GuardPrefix(GPrefix), GuardPostfix(GPostfix), ReturnOK(ROK), ReturnFail(RFail), Locals(L) {} @@ -70,6 +72,7 @@ private: std::vector<unsigned> Opcodes; std::map<unsigned, std::vector<OperandInfo> > Operands; public: + std::string PredicateNamespace; std::string GuardPrefix, GuardPostfix; std::string ReturnOK, ReturnFail; std::string Locals; |