void DisassemblerEmitter::run(raw_ostream &OS) { CodeGenTarget Target(Records); OS << "/*===- TableGen'erated file " << "---------------------------------------*- C -*-===*\n" << " *\n" << " * " << Target.getName() << " Disassembler\n" << " *\n" << " * Automatically generated file, do not edit!\n" << " *\n" << " *===---------------------------------------------------------------" << "-------===*/\n"; // X86 uses a custom disassembler. if (Target.getName() == "X86") { DisassemblerTables Tables; const std::vector<const CodeGenInstruction*> &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"); Tables.emit(OS); return; } // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses. 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); return; } FixedLenDecoderEmitter(Records, Target.getName()).run(OS); }
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<const CodeGenInstruction*> &numberedInstructions = Target.getInstructionsByEnumValue(); for (unsigned i = 0, e = numberedInstructions.size(); i != e; ++i) RecognizableInstr::processInstr(Tables, *numberedInstructions[i], i); if (Tables.hasConflicts()) { PrintError(Target.getTargetRecord()->getLoc(), "Primary decode conflict"); return; } Tables.emit(OS); return; } // 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; } EmitFixedLenDecoder(Records, OS, Target.getName(), "if (", " == MCDisassembler::Fail)" " return MCDisassembler::Fail;", "MCDisassembler::Success", "MCDisassembler::Fail", ""); }