X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FDisassemblerEmitter.cpp;h=f02051a2cd6c7fbfbf5c757fbe11d67545226e47;hb=ecf670391ba6efc58ee31dedc2bd3ffbea7cb8e1;hp=3284366c6dd8e2da3583f32971ea4efe48a99a5e;hpb=b68a3ee82a8a34f7bae1d68d76f574e76a5535ef;p=oota-llvm.git diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp index 3284366c6dd..f02051a2cd6 100644 --- a/utils/TableGen/DisassemblerEmitter.cpp +++ b/utils/TableGen/DisassemblerEmitter.cpp @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "DisassemblerEmitter.h" #include "CodeGenTarget.h" -#include "Record.h" #include "X86DisassemblerTables.h" #include "X86RecognizableInstr.h" -#include "ARMDecoderEmitter.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; using namespace llvm::X86Disassembler; @@ -39,12 +39,12 @@ using namespace llvm::X86Disassembler; /// all cases as a 64-bit instruction with only OPSIZE set. (The XS prefix /// may have effects on its execution, but does not change the instruction /// returned.) This allows considerable space savings in other tables. -/// - Four tables (ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, and -/// THREEBYTE3A_SYM) contain the hierarchy that the decoder traverses while -/// decoding an instruction. At the lowest level of this hierarchy are -/// instruction UIDs, 16-bit integers that can be used to uniquely identify -/// the instruction and correspond exactly to its position in the list of -/// CodeGenInstructions for the target. +/// - Six tables (ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM, +/// THREEBYTEA6_SYM, and THREEBYTEA7_SYM contain the hierarchy that the +/// decoder traverses while decoding an instruction. At the lowest level of +/// this hierarchy are instruction UIDs, 16-bit integers that can be used to +/// uniquely identify the instruction and correspond exactly to its position +/// in the list of CodeGenInstructions for the target. /// - One table (INSTRUCTIONS_SYM) contains information about the operands of /// each instruction and how to decode them. /// @@ -93,45 +93,58 @@ using namespace llvm::X86Disassembler; /// X86RecognizableInstr.cpp contains the implementation for a single /// instruction. -void DisassemblerEmitter::run(raw_ostream &OS) { - CodeGenTarget Target; +namespace llvm { - OS << "/*===- TableGen'erated file " - << "---------------------------------------*- C -*-===*\n" - << " *\n" - << " * " << Target.getName() << " Disassembler\n" - << " *\n" - << " * Automatically generated file, do not edit!\n" - << " *\n" - << " *===---------------------------------------------------------------" - << "-------===*/\n"; +extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, + std::string PredicateNamespace, + std::string GPrefix, + std::string GPostfix, + std::string ROK, + std::string RFail, + std::string L); + +void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { + CodeGenTarget Target(Records); + emitSourceFileHeader(" * " + Target.getName() + " Disassembler", OS); // X86 uses a custom disassembler. if (Target.getName() == "X86") { DisassemblerTables Tables; - + const std::vector &numberedInstructions = Target.getInstructionsByEnumValue(); - + for (unsigned i = 0, e = numberedInstructions.size(); i != e; ++i) RecognizableInstr::processInstr(Tables, *numberedInstructions[i], i); - // FIXME: As long as we are using exceptions, might as well drop this to the - // actual conflict site. - if (Tables.hasConflicts()) - throw TGError(Target.getTargetRecord()->getLoc(), - "Primary decode conflict"); + if (Tables.hasConflicts()) { + PrintError(Target.getTargetRecord()->getLoc(), "Primary decode conflict"); + return; + } Tables.emit(OS); return; } - // Fixed-instruction-length targets use a common disassembler. - if (Target.getName() == "ARM") { - ARMDecoderEmitter(Records).run(OS); + // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses. + if (Target.getName() == "ARM" || Target.getName() == "Thumb" || + Target.getName() == "AArch64" || Target.getName() == "ARM64") { + std::string PredicateNamespace = Target.getName(); + if (PredicateNamespace == "Thumb") + PredicateNamespace = "ARM"; + + EmitFixedLenDecoder(Records, OS, PredicateNamespace, + "if (!Check(S, ", ")) return MCDisassembler::Fail;", + "S", "MCDisassembler::Fail", + " MCDisassembler::DecodeStatus S = " + "MCDisassembler::Success;\n(void)S;"); return; - } + } - throw TGError(Target.getTargetRecord()->getLoc(), - "Unable to generate disassembler for this target"); + EmitFixedLenDecoder(Records, OS, Target.getName(), + "if (", " == MCDisassembler::Fail)" + " return MCDisassembler::Fail;", + "MCDisassembler::Success", "MCDisassembler::Fail", ""); } + +} // End llvm namespace