X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FDisassemblerEmitter.cpp;h=e8595271bccef863180eec7ab7630fc1c71ecebb;hb=47f0e3f434e2e43f951c3a826c40906cb15b7285;hp=126925369c5fc51d3ed391748a33e6e7a0415b3d;hpb=8d7d2e1238fac58c01ccfb719d0cc5680a079561;p=oota-llvm.git diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp index 126925369c5..e8595271bcc 100644 --- a/utils/TableGen/DisassemblerEmitter.cpp +++ b/utils/TableGen/DisassemblerEmitter.cpp @@ -7,14 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "DisassemblerEmitter.h" #include "CodeGenTarget.h" -#include "Error.h" -#include "Record.h" #include "X86DisassemblerTables.h" #include "X86RecognizableInstr.h" -#include "ARMDecoderEmitter.h" -#include "FixedLenDecoderEmitter.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" using namespace llvm; using namespace llvm::X86Disassembler; @@ -95,38 +93,57 @@ using namespace llvm::X86Disassembler; /// X86RecognizableInstr.cpp contains the implementation for a single /// instruction. -void DisassemblerEmitter::run(raw_ostream &OS) { - CodeGenTarget Target(Records); +namespace llvm { + +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); - OS << "/*===- TableGen'erated file " - << "---------------------------------------*- C -*-===*\n" - << " *\n" - << " * " << Target.getName() << " Disassembler\n" - << " *\n" - << " * Automatically generated file, do not edit!\n" - << " *\n" - << " *===---------------------------------------------------------------" - << "-------===*/\n"; +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; } - FixedLenDecoderEmitter(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, ", "))", + "S", "MCDisassembler::Fail", + " MCDisassembler::DecodeStatus S = " + "MCDisassembler::Success;\n(void)S;"); + return; + } + + EmitFixedLenDecoder(Records, OS, Target.getName(), + "if (", " == MCDisassembler::Fail)", + "MCDisassembler::Success", "MCDisassembler::Fail", ""); } + +} // End llvm namespace