From a5d585685493d85d5cb72b831a68ec747ae55a86 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Wed, 7 Sep 2011 19:42:28 +0000 Subject: 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 --- utils/TableGen/DisassemblerEmitter.cpp | 5 +-- utils/TableGen/FixedLenDecoderEmitter.cpp | 56 ++++++++++++++++++++++++++++--- utils/TableGen/FixedLenDecoderEmitter.h | 3 ++ 3 files changed, 58 insertions(+), 6 deletions(-) (limited to 'utils') 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 &EndBits, std::vector &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 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& InsnOperands = Operands[Opc]; for (std::vector::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 Opcodes; std::map > Operands; public: + std::string PredicateNamespace; std::string GuardPrefix, GuardPostfix; std::string ReturnOK, ReturnFail; std::string Locals; -- cgit v1.2.3