summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2011-09-07 19:42:28 +0000
committerJames Molloy <james.molloy@arm.com>2011-09-07 19:42:28 +0000
commita5d585685493d85d5cb72b831a68ec747ae55a86 (patch)
tree99483c51a38667c6c06586cc25abd758a8b2fccc /utils
parent2c207a0f677a2d78b768acb559e6b9f6f112a50d (diff)
downloadllvm-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.cpp5
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp56
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.h3
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;