summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-08-17 17:44:15 +0000
committerOwen Anderson <resistor@mac.com>2011-08-17 17:44:15 +0000
commit83e3f67fb68d497b600da83a62f000fcce7868a9 (patch)
tree304ea462b8e700eb92526a43c9c2749341fb9e83 /utils
parent0e6d230abdbf6ba67a2676c118431a4df8fb15dd (diff)
downloadllvm-83e3f67fb68d497b600da83a62f000fcce7868a9.tar.gz
llvm-83e3f67fb68d497b600da83a62f000fcce7868a9.tar.bz2
llvm-83e3f67fb68d497b600da83a62f000fcce7868a9.tar.xz
Allow the MCDisassembler to return a "soft fail" status code, indicating an instruction that is disassemblable, but invalid. Only used for ARM UNPREDICTABLE instructions at the moment.
Patch by James Molloy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137830 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/DisassemblerEmitter.cpp10
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp38
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.h16
3 files changed, 45 insertions, 19 deletions
diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
index 126925369c..ccf644b00e 100644
--- a/utils/TableGen/DisassemblerEmitter.cpp
+++ b/utils/TableGen/DisassemblerEmitter.cpp
@@ -128,5 +128,15 @@ void DisassemblerEmitter::run(raw_ostream &OS) {
return;
}
+ // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses.
+ if (Target.getName() == "ARM" ||
+ Target.getName() == "Thumb") {
+ FixedLenDecoderEmitter(Records,
+ "CHECK(S, ", ");",
+ "S", "Fail",
+ "DecodeStatus S = Success;\n(void)S;").run(OS);
+ return;
+ }
+
FixedLenDecoderEmitter(Records).run(OS);
}
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index 4ccb9c42db..d1f271208e 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -238,19 +238,24 @@ protected:
// Width of instructions
unsigned BitWidth;
+ // Parent emitter
+ const FixedLenDecoderEmitter *Emitter;
+
public:
FilterChooser(const FilterChooser &FC) :
AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes),
Operands(FC.Operands), Filters(FC.Filters),
FilterBitValues(FC.FilterBitValues), Parent(FC.Parent),
- BestIndex(FC.BestIndex), BitWidth(FC.BitWidth) { }
+ BestIndex(FC.BestIndex), BitWidth(FC.BitWidth),
+ Emitter(FC.Emitter) { }
FilterChooser(const std::vector<const CodeGenInstruction*> &Insts,
const std::vector<unsigned> &IDs,
std::map<unsigned, std::vector<OperandInfo> > &Ops,
- unsigned BW) :
+ unsigned BW,
+ const FixedLenDecoderEmitter *E) :
AllInstructions(Insts), Opcodes(IDs), Operands(Ops), Filters(),
- Parent(NULL), BestIndex(-1), BitWidth(BW) {
+ Parent(NULL), BestIndex(-1), BitWidth(BW), Emitter(E) {
for (unsigned i = 0; i < BitWidth; ++i)
FilterBitValues.push_back(BIT_UNFILTERED);
@@ -264,7 +269,8 @@ public:
FilterChooser &parent) :
AllInstructions(Insts), Opcodes(IDs), Operands(Ops),
Filters(), FilterBitValues(ParentFilterBitValues),
- Parent(&parent), BestIndex(-1), BitWidth(parent.BitWidth) {
+ Parent(&parent), BestIndex(-1), BitWidth(parent.BitWidth),
+ Emitter(parent.Emitter) {
doFilter();
}
@@ -563,17 +569,17 @@ unsigned Filter::usefulness() const {
void FilterChooser::emitTop(raw_ostream &o, unsigned Indentation,
std::string Namespace) {
o.indent(Indentation) <<
- "static bool decode" << Namespace << "Instruction" << BitWidth
+ "static MCDisassembler::DecodeStatus decode" << Namespace << "Instruction" << BitWidth
<< "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, "
<< "const void *Decoder) {\n";
- o.indent(Indentation) << " unsigned tmp = 0;\n (void)tmp;\n";
+ o.indent(Indentation) << " unsigned tmp = 0;\n (void)tmp;\n" << Emitter->Locals << "\n";
++Indentation; ++Indentation;
// Emits code to decode the instructions.
emit(o, Indentation);
o << '\n';
- o.indent(Indentation) << "return false;\n";
+ o.indent(Indentation) << "return " << Emitter->ReturnFail << ";\n";
--Indentation; --Indentation;
o.indent(Indentation) << "}\n";
@@ -744,8 +750,8 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
}
if (Decoder != "")
- o.indent(Indentation) << " if (!" << Decoder
- << "(MI, tmp, Address, Decoder)) return false;\n";
+ o.indent(Indentation) << " " << Emitter->GuardPrefix << Decoder
+ << "(MI, tmp, Address, Decoder)" << Emitter->GuardPostfix << "\n";
else
o.indent(Indentation) << " MI.addOperand(MCOperand::CreateImm(tmp));\n";
@@ -776,15 +782,15 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
// If a custom instruction decoder was specified, use that.
if (I->numFields() == 0 && I->Decoder.size()) {
- o.indent(Indentation) << " if (!" << I->Decoder
- << "(MI, insn, Address, Decoder)) return false;\n";
+ o.indent(Indentation) << " " << Emitter->GuardPrefix << I->Decoder
+ << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n";
break;
}
emitBinaryParser(o, Indentation, *I);
}
- o.indent(Indentation) << " return true; // " << nameWithID(Opc)
+ o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc)
<< '\n';
o.indent(Indentation) << "}\n";
return true;
@@ -821,14 +827,14 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
// If a custom instruction decoder was specified, use that.
if (I->numFields() == 0 && I->Decoder.size()) {
- o.indent(Indentation) << " if (!" << I->Decoder
- << "(MI, insn, Address, Decoder)) return false;\n";
+ o.indent(Indentation) << " " << Emitter->GuardPrefix << I->Decoder
+ << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n";
break;
}
emitBinaryParser(o, Indentation, *I);
}
- o.indent(Indentation) << " return true; // " << nameWithID(Opc)
+ o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc)
<< '\n';
o.indent(Indentation) << "}\n";
@@ -1426,7 +1432,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o)
// Emit the decoder for this namespace+width combination.
FilterChooser FC(NumberedInstructions, I->second, Operands,
- 8*I->first.second);
+ 8*I->first.second, this);
FC.emitTop(o, 0, I->first.first);
}
diff --git a/utils/TableGen/FixedLenDecoderEmitter.h b/utils/TableGen/FixedLenDecoderEmitter.h
index 300a2f49f8..535299c32d 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.h
+++ b/utils/TableGen/FixedLenDecoderEmitter.h
@@ -49,9 +49,16 @@ struct OperandInfo {
class FixedLenDecoderEmitter : public TableGenBackend {
public:
- FixedLenDecoderEmitter(RecordKeeper &R) :
+ FixedLenDecoderEmitter(RecordKeeper &R,
+ std::string GPrefix = "if (",
+ std::string GPostfix = " == MCDisassembler::Fail) return MCDisassembler::Fail;",
+ std::string ROK = "MCDisassembler::Success",
+ std::string RFail = "MCDisassembler::Fail",
+ std::string L = "") :
Records(R), Target(R),
- NumberedInstructions(Target.getInstructionsByEnumValue()) {}
+ NumberedInstructions(Target.getInstructionsByEnumValue()),
+ GuardPrefix(GPrefix), GuardPostfix(GPostfix),
+ ReturnOK(ROK), ReturnFail(RFail), Locals(L) {}
// run - Output the code emitter
void run(raw_ostream &o);
@@ -62,7 +69,10 @@ private:
std::vector<const CodeGenInstruction*> NumberedInstructions;
std::vector<unsigned> Opcodes;
std::map<unsigned, std::vector<OperandInfo> > Operands;
-
+public:
+ std::string GuardPrefix, GuardPostfix;
+ std::string ReturnOK, ReturnFail;
+ std::string Locals;
};
} // end llvm namespace