From 3373228170bbc2324d223bdeca761de3b4565508 Mon Sep 17 00:00:00 2001 From: fanfuqiang Date: Sun, 17 Feb 2019 06:08:44 +0800 Subject: [PATCH] capstone riscv patchs --- ...apstone-generate-GenRegisterInfo.inc.patch | 338 +++++++++++++ ...pstone-generate-GenSubtargetInfo.inc.patch | 86 ++++ ...3-capstone-generate-GenInstrInfo.inc.patch | 130 +++++ ...e-generate-GenDisassemblerTables.inc.patch | 472 ++++++++++++++++++ ...5-capstone-generate-GenAsmWriter.inc.patch | 225 +++++++++ ...06-capstone-generate-MappingInsn.inc.patch | 174 +++++++ ...apstone-generate-GenInsnNameMaps.inc.patch | 110 ++++ llvm/lib/Target/RISCV/CMakeLists.txt | 2 + llvm/utils/TableGen/AsmWriterEmitter.cpp | 103 +++- llvm/utils/TableGen/AsmWriterInst.cpp | 4 + llvm/utils/TableGen/DisassemblerEmitter.cpp | 12 +- .../utils/TableGen/FixedLenDecoderEmitter.cpp | 398 ++++++++++++++- llvm/utils/TableGen/InstrInfoEmitter.cpp | 173 ++++++- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 130 ++++- llvm/utils/TableGen/SubtargetEmitter.cpp | 28 +- llvm/utils/TableGen/TableGen.cpp | 12 + llvm/utils/TableGen/TableGenBackends.h | 2 + 17 files changed, 2349 insertions(+), 50 deletions(-) create mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch create mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch create mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch create mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch create mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch create mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch create mode 100644 llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch diff --git a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch new file mode 100644 index 000000000..b51aa515a --- /dev/null +++ b/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch @@ -0,0 +1,338 @@ +From 5d631cb16e7ba5dd0380ff1ee9dda192b1cdad18 Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Tue, 7 Aug 2018 17:02:40 +0200 +Subject: [PATCH 1/7] capstone: generate *GenRegisterInfo.inc + +--- + utils/TableGen/RegisterInfoEmitter.cpp | 130 ++++++++++++++++++++++--- + 1 file changed, 115 insertions(+), 15 deletions(-) + +diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp +index 49016cca799..6ebb7148b1b 100644 +--- a/utils/TableGen/RegisterInfoEmitter.cpp ++++ b/utils/TableGen/RegisterInfoEmitter.cpp +@@ -99,6 +99,12 @@ private: + + } // end anonymous namespace + ++#ifdef CAPSTONE ++#define NAME_PREFIX Target.getName() << "_" << ++#else ++#define NAME_PREFIX ++#endif ++ + // runEnums - Print out enum values for all of the registers. + void RegisterInfoEmitter::runEnums(raw_ostream &OS, + CodeGenTarget &Target, CodeGenRegBank &Bank) { +@@ -107,13 +113,22 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + // Register enums are stored as uint16_t in the tables. Make sure we'll fit. + assert(Registers.size() <= 0xffff && "Too many regs to fit in tables"); + ++#ifndef CAPSTONE + StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace"); ++#endif + + emitSourceFileHeader("Target Register Enum Values", OS); + ++#ifdef CAPSTONE ++ OS << "/* Capstone Disassembly Engine */\n" ++ "/* By Nguyen Anh Quynh , 2013-2015 */\n" ++ "\n"; ++#endif ++ + OS << "\n#ifdef GET_REGINFO_ENUM\n"; + OS << "#undef GET_REGINFO_ENUM\n\n"; + ++#ifndef CAPSTONE + OS << "namespace llvm {\n\n"; + + OS << "class MCRegisterClass;\n" +@@ -122,16 +137,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; +- OS << "enum {\n NoRegister,\n"; ++#endif ++ ++ OS << "enum {\n " << NAME_PREFIX "NoRegister,\n"; + + for (const auto &Reg : Registers) +- OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n"; ++ OS << " " << NAME_PREFIX Reg.getName() << " = " << Reg.EnumValue << ",\n"; + assert(Registers.size() == Registers.back().EnumValue && + "Register enum value mismatch!"); +- OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; ++ OS << " " << NAME_PREFIX "NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; + OS << "};\n"; ++#ifndef CAPSTONE + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n"; ++#endif + + const auto &RegisterClasses = Bank.getRegClasses(); + if (!RegisterClasses.empty()) { +@@ -140,18 +159,29 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + assert(RegisterClasses.size() <= 0xffff && + "Too many register classes to fit in tables"); + +- OS << "\n// Register classes\n\n"; ++ OS << "\n// Register classes\n"; ++#ifndef CAPSTONE ++ OS << "\n"; + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; ++#endif + OS << "enum {\n"; + for (const auto &RC : RegisterClasses) +- OS << " " << RC.getName() << "RegClassID" ++ OS << " " << NAME_PREFIX RC.getName() << "RegClassID" + << " = " << RC.EnumValue << ",\n"; +- OS << "\n };\n"; ++#ifdef CAPSTONE ++ OS ++#else ++ OS << "\n " ++#endif ++ << "};\n"; ++#ifndef CAPSTONE + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n\n"; ++#endif + } + ++#ifndef CAPSTONE + const std::vector &RegAltNameIndices = Target.getRegAltNameIndices(); + // If the only definition is the default NoRegAltName, we don't need to + // emit anything. +@@ -182,8 +212,11 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n\n"; + } ++#endif + ++#ifndef CAPSTONE + OS << "} // end namespace llvm\n\n"; ++#endif + OS << "#endif // GET_REGINFO_ENUM\n\n"; + } + +@@ -830,7 +863,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + + const auto &Regs = RegBank.getRegisters(); + ++#ifndef CAPSTONE + auto &SubRegIndices = RegBank.getSubRegIndices(); ++#endif + // The lists of sub-registers and super-registers go in the same array. That + // allows us to share suffixes. + typedef std::vector RegVec; +@@ -922,25 +957,40 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + LaneMaskSeqs.layout(); + SubRegIdxSeqs.layout(); + ++#ifndef CAPSTONE + OS << "namespace llvm {\n\n"; ++#endif + + const std::string &TargetName = Target.getName(); + + // Emit the shared table of differential lists. +- OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n"; ++#ifdef CAPSTONE ++ OS << "static" ++#else ++ OS << "extern" ++#endif ++ << " const MCPhysReg " << TargetName << "RegDiffLists[] = {\n"; + DiffSeqs.emit(OS, printDiff16); + OS << "};\n\n"; + ++#ifndef CAPSTONE + // Emit the shared table of regunit lane mask sequences. + OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n"; + LaneMaskSeqs.emit(OS, printMask, "LaneBitmask::getAll()"); + OS << "};\n\n"; ++#endif + + // Emit the table of sub-register indexes. +- OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; ++#ifdef CAPSTONE ++ OS << "static" ++#else ++ OS << "extern" ++#endif ++ << " const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; + SubRegIdxSeqs.emit(OS, printSubRegIndex); + OS << "};\n\n"; + ++#ifndef CAPSTONE + // Emit the table of sub-register index sizes. + OS << "extern const MCRegisterInfo::SubRegCoveredBits " + << TargetName << "SubRegIdxRanges[] = {\n"; +@@ -950,14 +1000,22 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + << Idx.getName() << "\n"; + } + OS << "};\n\n"; ++#endif + + // Emit the string table. + RegStrings.layout(); ++#ifndef CAPSTONE + OS << "extern const char " << TargetName << "RegStrings[] = {\n"; + RegStrings.emit(OS, printChar); + OS << "};\n\n"; ++#endif + +- OS << "extern const MCRegisterDesc " << TargetName ++#ifdef CAPSTONE ++ OS << "static" ++#else ++ OS << "extern" ++#endif ++ << " const MCRegisterDesc " << TargetName + << "RegDesc[] = { // Descriptors\n"; + OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n"; + +@@ -973,6 +1031,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + } + OS << "};\n\n"; // End of register descriptors... + ++#ifndef CAPSTONE + // Emit the table of register unit roots. Each regunit has one or two root + // registers. + OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n"; +@@ -986,11 +1045,14 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + OS << " },\n"; + } + OS << "};\n\n"; ++#endif + + const auto &RegisterClasses = RegBank.getRegClasses(); + + // Loop over all of the register classes... emitting each one. ++#ifndef CAPSTONE + OS << "namespace { // Register classes...\n"; ++#endif + + SequenceToOffsetTable RegClassStrings; + +@@ -1005,15 +1067,28 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + + // Emit the register list now. + OS << " // " << Name << " Register Class...\n" +- << " const MCPhysReg " << Name ++ << " " ++#ifdef CAPSTONE ++ << "static " ++#endif ++ << "const MCPhysReg " << Name + << "[] = {\n "; + for (Record *Reg : Order) { +- OS << getQualifiedName(Reg) << ", "; ++#ifdef CAPSTONE ++ OS << NAME_PREFIX Reg->getName() ++#else ++ OS << getQualifiedName(Reg) ++#endif ++ << ", "; + } + OS << "\n };\n\n"; + + OS << " // " << Name << " Bit set.\n" +- << " const uint8_t " << Name ++ << " " ++#ifdef CAPSTONE ++ << "static " ++#endif ++ << "const uint8_t " << Name + << "Bits[] = {\n "; + BitVectorEmitter BVE; + for (Record *Reg : Order) { +@@ -1023,14 +1098,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + OS << "\n };\n\n"; + + } ++#ifndef CAPSTONE + OS << "} // end anonymous namespace\n\n"; ++#endif + + RegClassStrings.layout(); ++#ifndef CAPSTONE + OS << "extern const char " << TargetName << "RegClassStrings[] = {\n"; + RegClassStrings.emit(OS, printChar); + OS << "};\n\n"; ++#endif + +- OS << "extern const MCRegisterClass " << TargetName ++#ifdef CAPSTONE ++ OS << "static" ++#else ++ OS << "extern" ++#endif ++ << " const MCRegisterClass " << TargetName + << "MCRegisterClasses[] = {\n"; + + for (const auto &RC : RegisterClasses) { +@@ -1041,7 +1125,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, " + << RegClassStrings.get(RC.getName()) << ", " + << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), " +- << RC.getQualifiedName() + "RegClassID" << ", " ++#ifdef CAPSTONE ++ << NAME_PREFIX RC.getName() ++#else ++ << RC.getQualifiedName() ++#endif ++ << "RegClassID" << ", " + << RegSize/8 << ", " + << RC.CopyCost << ", " + << ( RC.Allocatable ? "true" : "false" ) << " },\n"; +@@ -1049,6 +1138,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + + OS << "};\n\n"; + ++#ifndef CAPSTONE + EmitRegMappingTables(OS, Regs, false); + + // Emit Reg encoding table +@@ -1067,7 +1157,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + OS << " " << Value << ",\n"; + } + OS << "};\n"; // End of HW encoding table ++#endif + ++#ifndef CAPSTONE + // MCRegisterInfo initialization routine. + OS << "static inline void Init" << TargetName + << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " +@@ -1088,7 +1180,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + OS << "}\n\n"; + + OS << "} // end namespace llvm\n\n"; +- OS << "#endif // GET_REGINFO_MC_DESC\n\n"; ++#endif ++ OS << "#endif // GET_REGINFO_MC_DESC\n" ++#ifndef CAPSTONE ++ << "\n" ++#endif ++ ; + } + + void +@@ -1568,10 +1665,13 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, + + void RegisterInfoEmitter::run(raw_ostream &OS) { + CodeGenRegBank &RegBank = Target.getRegBank(); ++ + runEnums(OS, Target, RegBank); + runMCDesc(OS, Target, RegBank); ++#ifndef CAPSTONE + runTargetHeader(OS, Target, RegBank); + runTargetDesc(OS, Target, RegBank); ++#endif + + if (RegisterInfoDebug) + debugDump(errs()); +-- +2.19.1 + diff --git a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch new file mode 100644 index 000000000..56ad28256 --- /dev/null +++ b/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch @@ -0,0 +1,86 @@ +From 46ca491e1bbbc9ace2a91fe6a7b112c83b9b88cc Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Tue, 7 Aug 2018 17:42:59 +0200 +Subject: [PATCH 2/7] capstone: generate *GenSubtargetInfo.inc + +--- + utils/TableGen/SubtargetEmitter.cpp | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp +index c5da8d8142f..98ab3240472 100644 +--- a/utils/TableGen/SubtargetEmitter.cpp ++++ b/utils/TableGen/SubtargetEmitter.cpp +@@ -147,7 +147,9 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS) { + if (N > MAX_SUBTARGET_FEATURES) + PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES."); + ++#ifndef CAPSTONE + OS << "namespace " << Target << " {\n"; ++#endif + + // Open enumeration. + OS << "enum {\n"; +@@ -158,12 +160,22 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS) { + Record *Def = DefList[i]; + + // Get and emit name +- OS << " " << Def->getName() << " = " << i << ",\n"; ++ OS << " " ++#ifdef CAPSTONE ++ << Target << "_" ++#endif ++ << Def->getName() << " = " ++#ifdef CAPSTONE ++ << "1ULL << " ++#endif ++ << i << ",\n"; + } + + // Close enumeration and namespace + OS << "};\n"; ++#ifndef CAPSTONE + OS << "} // end namespace " << Target << "\n"; ++#endif + } + + // +@@ -1709,14 +1721,27 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { + void SubtargetEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); + ++#ifdef CAPSTONE ++ OS << "/* Capstone Disassembly Engine, http://www.capstone-engine.org */\n" ++ "/* By Nguyen Anh Quynh , 2013-2015 */\n" ++ "\n"; ++#endif ++ + OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; + OS << "#undef GET_SUBTARGETINFO_ENUM\n\n"; + ++#ifndef CAPSTONE + OS << "namespace llvm {\n"; ++#endif + Enumeration(OS); ++#ifdef CAPSTONE ++ OS << "\n"; ++#else + OS << "} // end namespace llvm\n\n"; ++#endif + OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; + ++#ifndef CAPSTONE + OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; + OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n"; + +@@ -1857,6 +1882,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { + OS << "} // end namespace llvm\n\n"; + + OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; ++#endif + } + + namespace llvm { +-- +2.19.1 + diff --git a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch new file mode 100644 index 000000000..2baa59fc9 --- /dev/null +++ b/llvm/0003-capstone-generate-GenInstrInfo.inc.patch @@ -0,0 +1,130 @@ +From a73fe8ac18d3ca81fa7a8d8c404cd7e0faf92ddc Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Tue, 7 Aug 2018 17:59:43 +0200 +Subject: [PATCH 3/7] capstone: generate *GenInstrInfo.inc + +--- + utils/TableGen/InstrInfoEmitter.cpp | 49 ++++++++++++++++++++++++++--- + 1 file changed, 44 insertions(+), 5 deletions(-) + +diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp +index 0aff1aa6f94..2f3a2729262 100644 +--- a/utils/TableGen/InstrInfoEmitter.cpp ++++ b/utils/TableGen/InstrInfoEmitter.cpp +@@ -92,6 +92,7 @@ private: + + } // end anonymous namespace + ++#ifndef CAPSTONE + static void PrintDefList(const std::vector &Uses, + unsigned Num, raw_ostream &OS) { + OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; +@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &Uses, + OS << getQualifiedName(U) << ", "; + OS << "0 };\n"; + } ++#endif + + //===----------------------------------------------------------------------===// + // Operand Info Emission. +@@ -426,8 +428,17 @@ void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS) { + // run - Emit the main instruction description records for the target... + void InstrInfoEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS); ++ ++#ifdef CAPSTONE ++ OS << "/* Capstone Disassembly Engine */\n" ++ "/* By Nguyen Anh Quynh , 2013-2015 */\n" ++ "\n" ++ "\n"; ++#endif ++ + emitEnums(OS); + ++#ifndef CAPSTONE + OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; + OS << "#undef GET_INSTRINFO_MC_DESC\n"; + +@@ -545,6 +556,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { + emitOperandTypesEnum(OS, Target); + + emitMCIIHelperMethods(OS); ++#endif + } + + void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, +@@ -659,7 +671,9 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { + OS << "#ifdef GET_INSTRINFO_ENUM\n"; + OS << "#undef GET_INSTRINFO_ENUM\n"; + ++#ifndef CAPSTONE + OS << "namespace llvm {\n\n"; ++#endif + + CodeGenTarget Target(Records); + +@@ -669,17 +683,39 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { + if (Namespace.empty()) + PrintFatalError("No instructions defined!"); + ++#ifndef CAPSTONE + OS << "namespace " << Namespace << " {\n"; +- OS << " enum {\n"; ++#endif ++#ifdef CAPSTONE ++ OS << "\n" ++#else ++ OS << " " ++#endif ++ << "enum {\n"; + unsigned Num = 0; + for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) +- OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; +- OS << " INSTRUCTION_LIST_END = " << Num << "\n"; ++ OS << " " ++#ifdef CAPSTONE ++ << Target.getName() << "_" ++#endif ++ << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; ++ OS << " " ++#ifdef CAPSTONE ++ << Target.getName() << "_" ++#endif ++ << "INSTRUCTION_LIST_END = " << Num << "\n"; + OS << " };\n\n"; ++#ifndef CAPSTONE + OS << "} // end " << Namespace << " namespace\n"; + OS << "} // end llvm namespace\n"; +- OS << "#endif // GET_INSTRINFO_ENUM\n\n"; +- ++#endif ++ OS << "#endif // GET_INSTRINFO_ENUM\n" ++#ifndef CAPSTONE ++ << "\n" ++#endif ++ ; ++ ++#ifndef CAPSTONE + OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n"; + OS << "#undef GET_INSTRINFO_SCHED_ENUM\n"; + OS << "namespace llvm {\n\n"; +@@ -696,13 +732,16 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { + OS << "} // end llvm namespace\n"; + + OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n"; ++#endif + } + + namespace llvm { + + void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { + InstrInfoEmitter(RK).run(OS); ++#ifndef CAPSTONE + EmitMapTable(RK, OS); ++#endif + } + + } // end llvm namespace +-- +2.19.1 + diff --git a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch new file mode 100644 index 000000000..0002b81b4 --- /dev/null +++ b/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch @@ -0,0 +1,472 @@ +From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Tue, 7 Aug 2018 18:20:17 +0200 +Subject: [PATCH 4/7] capstone: generate *GenDisassemblerTables.inc + +--- + utils/TableGen/DisassemblerEmitter.cpp | 12 +- + utils/TableGen/FixedLenDecoderEmitter.cpp | 248 ++++++++++++++++++++-- + 2 files changed, 239 insertions(+), 21 deletions(-) + +diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp +index b99a0a973a2..2ac6d89645c 100644 +--- a/utils/TableGen/DisassemblerEmitter.cpp ++++ b/utils/TableGen/DisassemblerEmitter.cpp +@@ -106,6 +106,11 @@ extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, + void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { + CodeGenTarget Target(Records); + emitSourceFileHeader(" * " + Target.getName().str() + " Disassembler", OS); ++#ifdef CAPSTONE ++ OS << "/* Capstone Disassembly Engine */\n" ++ "/* By Nguyen Anh Quynh , 2013-2015 */\n" ++ "\n"; ++#endif + + // X86 uses a custom disassembler. + if (Target.getName() == "X86") { +@@ -150,7 +155,12 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { + } + + EmitFixedLenDecoder(Records, OS, Target.getName(), +- "if (", " == MCDisassembler::Fail)", ++ "if (", ++#ifdef CAPSTONE ++ " == MCDisassembler_Fail)", ++#else ++ " == MCDisassembler::Fail)", ++#endif + "MCDisassembler::Success", "MCDisassembler::Fail", ""); + } + +diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp +index fcecc764d44..36845d960d8 100644 +--- a/utils/TableGen/FixedLenDecoderEmitter.cpp ++++ b/utils/TableGen/FixedLenDecoderEmitter.cpp +@@ -730,7 +730,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + ++I; + unsigned Start = *I++; + unsigned Len = *I++; +- OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", " ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_ExtractField" ++#else ++ << "MCD::OPC_ExtractField" ++#endif ++ << ", " << Start << ", " + << Len << ", // Inst{"; + if (Len > 1) + OS << (Start + Len - 1) << "-"; +@@ -739,7 +745,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + } + case MCD::OPC_FilterValue: { + ++I; +- OS.indent(Indentation) << "MCD::OPC_FilterValue, "; ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_FilterValue" ++#else ++ << "MCD::OPC_FilterValue" ++#endif ++ << ", "; + // The filter value is ULEB128 encoded. + while (*I >= 128) + OS << (unsigned)*I++ << ", "; +@@ -759,7 +771,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + ++I; + unsigned Start = *I++; + unsigned Len = *I++; +- OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", " ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_CheckField" ++#else ++ << "MCD::OPC_CheckField" ++#endif ++ << ", " << Start << ", " + << Len << ", ";// << Val << ", " << NumToSkip << ",\n"; + // ULEB128 encoded field value. + for (; *I >= 128; ++I) +@@ -777,7 +795,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + } + case MCD::OPC_CheckPredicate: { + ++I; +- OS.indent(Indentation) << "MCD::OPC_CheckPredicate, "; ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_CheckPredicate" ++#else ++ << "MCD::OPC_CheckPredicate" ++#endif ++ << ", "; + for (; *I >= 128; ++I) + OS << (unsigned)*I << ", "; + OS << (unsigned)*I++ << ", "; +@@ -803,7 +827,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + && "ULEB128 value too large!"); + // Decode the Opcode value. + unsigned Opc = decodeULEB128(Buffer); +- OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "") ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_" ++#else ++ << "MCD::OPC_" ++#endif ++ << (IsTry ? "Try" : "") + << "Decode, "; + for (p = Buffer; *p >= 128; ++p) + OS << (unsigned)*p << ", "; +@@ -837,7 +867,12 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + } + case MCD::OPC_SoftFail: { + ++I; +- OS.indent(Indentation) << "MCD::OPC_SoftFail"; ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_SoftFail"; ++#else ++ << "MCD::OPC_SoftFail"; ++#endif + // Positive mask + uint64_t Value = 0; + unsigned Shift = 0; +@@ -869,7 +904,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + } + case MCD::OPC_Fail: { + ++I; +- OS.indent(Indentation) << "MCD::OPC_Fail,\n"; ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "MCD_OPC_Fail" ++#else ++ << "MCD::OPC_Fail" ++#endif ++ << ",\n"; + break; + } + } +@@ -884,23 +925,46 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, + void FixedLenDecoderEmitter:: + emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, + unsigned Indentation) const { ++#ifdef CAPSTONE ++ OS.indent(Indentation) << "static bool getbool(uint64_t b)\n"; ++ OS.indent(Indentation) << "{\n"; ++ OS.indent(Indentation) << "\treturn b != 0;\n"; ++ OS.indent(Indentation) << "}\n\n"; ++#endif ++ + // The predicate function is just a big switch statement based on the + // input predicate index. + OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, " ++#ifdef CAPSTONE ++ << "uint64_t Bits)\n{\n"; ++#else + << "const FeatureBitset& Bits) {\n"; ++#endif + Indentation += 2; + if (!Predicates.empty()) { + OS.indent(Indentation) << "switch (Idx) {\n"; +- OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; ++ OS.indent(Indentation) << "default: " ++#ifdef CAPSTONE ++ << "// " ++#endif ++ << "llvm_unreachable(\"Invalid index!\");\n"; + unsigned Index = 0; + for (const auto &Predicate : Predicates) { + OS.indent(Indentation) << "case " << Index++ << ":\n"; +- OS.indent(Indentation+2) << "return (" << Predicate << ");\n"; ++ OS.indent(Indentation+2) << "return " ++#ifdef CAPSTONE ++ << "getbool" ++#endif ++ << "(" << Predicate << ");\n"; + } + OS.indent(Indentation) << "}\n"; + } else { + // No case statement to emit +- OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n"; ++ OS.indent(Indentation) ++#ifdef CAPSTONE ++ << "// " ++#endif ++ << "llvm_unreachable(\"Invalid index!\");\n"; + } + Indentation -= 2; + OS.indent(Indentation) << "}\n\n"; +@@ -911,23 +975,39 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, + unsigned Indentation) const { + // The decoder function is just a big switch statement based on the + // input decoder index. ++#ifdef CAPSTONE ++#define EDF_EOL " \\\n" ++ OS.indent(Indentation) << "#define DecodeToMCInst(fname,fieldname, InsnType) \\\n"; ++ OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n"; ++ OS.indent(Indentation) << " uint64_t Address, const void *Decoder) \\\n"; ++ OS.indent(Indentation) << "{ \\\n"; ++#else ++#define EDF_EOL "\n" + OS.indent(Indentation) << "template\n"; + OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," + << " unsigned Idx, InsnType insn, MCInst &MI,\n"; + OS.indent(Indentation) << " uint64_t " + << "Address, const void *Decoder, bool &DecodeComplete) {\n"; ++#endif + Indentation += 2; ++#ifndef CAPSTONE + OS.indent(Indentation) << "DecodeComplete = true;\n"; +- OS.indent(Indentation) << "InsnType tmp;\n"; +- OS.indent(Indentation) << "switch (Idx) {\n"; +- OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; ++#endif ++ OS.indent(Indentation) << "InsnType tmp;" EDF_EOL; ++ OS.indent(Indentation) << "switch (Idx) {" EDF_EOL; ++ OS.indent(Indentation) << "default:" ++#ifndef CAPSTONE ++ << " llvm_unreachable(\"Invalid index!\");\n"; ++#else ++ << " \\\n"; ++#endif + unsigned Index = 0; + for (const auto &Decoder : Decoders) { +- OS.indent(Indentation) << "case " << Index++ << ":\n"; ++ OS.indent(Indentation) << "case " << Index++ << ":" EDF_EOL; + OS << Decoder; +- OS.indent(Indentation+2) << "return S;\n"; ++ OS.indent(Indentation+2) << "return S;" EDF_EOL; + } +- OS.indent(Indentation) << "}\n"; ++ OS.indent(Indentation) << "}" EDF_EOL; + Indentation -= 2; + OS.indent(Indentation) << "}\n\n"; + } +@@ -1054,16 +1134,21 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, + const std::string &Decoder = OpInfo.Decoder; + + if (OpInfo.numFields() != 1) +- o.indent(Indentation) << "tmp = 0;\n"; ++ o.indent(Indentation) << "tmp = 0;" EDF_EOL; + + for (const EncodingField &EF : OpInfo) { + o.indent(Indentation) << "tmp "; + if (OpInfo.numFields() != 1) o << '|'; +- o << "= fieldFromInstruction" ++ o << "= " ++#ifdef CAPSTONE ++ << "fieldname" ++#else ++ << "fieldFromInstruction" ++#endif + << "(insn, " << EF.Base << ", " << EF.Width << ')'; + if (OpInfo.numFields() != 1 || EF.Offset != 0) + o << " << " << EF.Offset; +- o << ";\n"; ++ o << ";" EDF_EOL; + } + + if (Decoder != "") { +@@ -1071,8 +1156,12 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, + o.indent(Indentation) << Emitter->GuardPrefix << Decoder + << "(MI, tmp, Address, Decoder)" + << Emitter->GuardPostfix ++#ifdef CAPSTONE ++ << " return MCDisassembler_Fail; \\\n"; ++#else + << " { " << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ") + << "return MCDisassembler::Fail; }\n"; ++#endif + } else { + OpHasCompleteDecoder = true; + o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n"; +@@ -1091,7 +1180,13 @@ void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation, + << "(MI, insn, Address, Decoder)" + << Emitter->GuardPostfix + << " { " << (HasCompleteDecoder ? "" : "DecodeComplete = false; ") +- << "return MCDisassembler::Fail; }\n"; ++ << "return " ++#ifdef CAPSTONE ++ << "MCDisassembler_Fail" ++#else ++ << "MCDisassembler::Fail" ++#endif ++ << "; }\n"; + break; + } + +@@ -1129,10 +1224,19 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, + static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, + const std::string &PredicateNamespace) { + if (str[0] == '!') ++#ifdef CAPSTONE ++ o << "~(Bits & " << PredicateNamespace << "_" ++ << str.slice(1,str.size()) << ")"; ++#else + o << "!Bits[" << PredicateNamespace << "::" + << str.slice(1,str.size()) << "]"; ++#endif + else ++#ifdef CAPSTONE ++ o << "(Bits & " << PredicateNamespace << "_" << str << ")"; ++#else + o << "Bits[" << PredicateNamespace << "::" << str << "]"; ++#endif + } + + bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, +@@ -2047,6 +2151,17 @@ static bool populateInstruction(CodeGenTarget &Target, + // fieldFromInstruction(). + static void emitFieldFromInstruction(formatted_raw_ostream &OS) { + OS << "// Helper function for extracting fields from encoded instructions.\n" ++#ifdef CAPSTONE ++ << "#define FieldFromInstruction(fname, InsnType) \\\n" ++ << "static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \\\n" ++ << "{ \\\n" ++ << " InsnType fieldMask; \\\n" ++ << " if (numBits == sizeof(InsnType)*8) \\\n" ++ << " fieldMask = (InsnType)(-1LL); \\\n" ++ << " else \\\n" ++ << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \\\n" ++ << " return (insn & fieldMask) >> startBit; \\\n" ++#else + << "template\n" + << "static InsnType fieldFromInstruction(InsnType insn, unsigned startBit,\n" + << " unsigned numBits) {\n" +@@ -2058,12 +2173,92 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { + << " else\n" + << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n" + << " return (insn & fieldMask) >> startBit;\n" ++#endif + << "}\n\n"; + } + + // emitDecodeInstruction - Emit the templated helper function + // decodeInstruction(). + static void emitDecodeInstruction(formatted_raw_ostream &OS) { ++#ifdef CAPSTONE ++ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n" ++ << "static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \\\n" ++ << " InsnType insn, uint64_t Address, const MCRegisterInfo *MRI, int feature) \\\n" ++ << "{ \\\n" ++ << " uint64_t Bits = getFeatureBits(feature); \\\n" ++ << " const uint8_t *Ptr = DecodeTable; \\\n" ++ << " uint32_t CurFieldValue = 0, ExpectedValue; \\\n" ++ << " DecodeStatus S = MCDisassembler_Success; \\\n" ++ << " unsigned Start, Len, NumToSkip, PIdx, Opc, DecodeIdx; \\\n" ++ << " InsnType Val, FieldValue, PositiveMask, NegativeMask; \\\n" ++ << " bool Pred, Fail; \\\n" ++ << " for (;;) { \\\n" ++ << " switch (*Ptr) { \\\n" ++ << " default: \\\n" ++ << " return MCDisassembler_Fail; \\\n" ++ << " case MCD_OPC_ExtractField: { \\\n" ++ << " Start = *++Ptr; \\\n" ++ << " Len = *++Ptr; \\\n" ++ << " ++Ptr; \\\n" ++ << " CurFieldValue = (uint32_t)fieldname(insn, Start, Len); \\\n" ++ << " break; \\\n" ++ << " } \\\n" ++ << " case MCD_OPC_FilterValue: { \\\n" ++ << " Val = (InsnType)decodeULEB128(++Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " NumToSkip = *Ptr++; \\\n" ++ << " NumToSkip |= (*Ptr++) << 8; \\\n" ++ << " if (Val != CurFieldValue) \\\n" ++ << " Ptr += NumToSkip; \\\n" ++ << " break; \\\n" ++ << " } \\\n" ++ << " case MCD_OPC_CheckField: { \\\n" ++ << " Start = *++Ptr; \\\n" ++ << " Len = *++Ptr; \\\n" ++ << " FieldValue = fieldname(insn, Start, Len); \\\n" ++ << " ExpectedValue = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " NumToSkip = *Ptr++; \\\n" ++ << " NumToSkip |= (*Ptr++) << 8; \\\n" ++ << " if (ExpectedValue != FieldValue) \\\n" ++ << " Ptr += NumToSkip; \\\n" ++ << " break; \\\n" ++ << " } \\\n" ++ << " case MCD_OPC_CheckPredicate: { \\\n" ++ << " PIdx = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " NumToSkip = *Ptr++; \\\n" ++ << " NumToSkip |= (*Ptr++) << 8; \\\n" ++ << " Pred = checkDecoderPredicate(PIdx, Bits); \\\n" ++ << " if (!Pred) \\\n" ++ << " Ptr += NumToSkip; \\\n" ++ << " (void)Pred; \\\n" ++ << " break; \\\n" ++ << " } \\\n" ++ << " case MCD_OPC_Decode: { \\\n" ++ << " Opc = (unsigned)decodeULEB128(++Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " DecodeIdx = (unsigned)decodeULEB128(Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " MCInst_setOpcode(MI, Opc); \\\n" ++ << " return decoder(S, DecodeIdx, insn, MI, Address, MRI); \\\n" ++ << " } \\\n" ++ << " case MCD_OPC_SoftFail: { \\\n" ++ << " PositiveMask = (InsnType)decodeULEB128(++Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " NegativeMask = (InsnType)decodeULEB128(Ptr, &Len); \\\n" ++ << " Ptr += Len; \\\n" ++ << " Fail = (insn & PositiveMask) || (~insn & NegativeMask); \\\n" ++ << " if (Fail) \\\n" ++ << " S = MCDisassembler_SoftFail; \\\n" ++ << " break; \\\n" ++ << " } \\\n" ++ << " case MCD_OPC_Fail: { \\\n" ++ << " return MCDisassembler_Fail; \\\n" ++ << " } \\\n" ++ << " } \\\n" ++ << " } \\\n" ++#else + OS << "template\n" + << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " + "MCInst &MI,\n" +@@ -2240,12 +2435,18 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " }\n" + << " llvm_unreachable(\"bogosity detected in disassembler state " + "machine!\");\n" ++#endif + << "}\n\n"; + } + + // Emits disassembler code for instruction decoding. + void FixedLenDecoderEmitter::run(raw_ostream &o) { + formatted_raw_ostream OS(o); ++#ifdef CAPSTONE ++ OS << "#include \"../../MCInst.h\"\n"; ++ OS << "#include \"../../LEB128.h\"\n"; ++ OS << "\n"; ++#else + OS << "#include \"llvm/MC/MCInst.h\"\n"; + OS << "#include \"llvm/Support/Debug.h\"\n"; + OS << "#include \"llvm/Support/DataTypes.h\"\n"; +@@ -2254,6 +2455,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { + OS << "#include \n"; + OS << '\n'; + OS << "namespace llvm {\n\n"; ++#endif + + emitFieldFromInstruction(OS); + +@@ -2322,7 +2524,13 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { + // Emit the main entry point for the decoder, decodeInstruction(). + emitDecodeInstruction(OS); + ++#ifdef CAPSTONE ++ OS << "FieldFromInstruction(fieldFromInstruction, uint64_t)\n"; ++ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint64_t)\n"; ++ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint64_t)\n"; ++#else + OS << "\n} // End llvm namespace\n"; ++#endif + } + + namespace llvm { +-- +2.19.1 + diff --git a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch new file mode 100644 index 000000000..cd1353eb7 --- /dev/null +++ b/llvm/0005-capstone-generate-GenAsmWriter.inc.patch @@ -0,0 +1,225 @@ +From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Tue, 7 Aug 2018 20:00:08 +0200 +Subject: [PATCH 5/7] capstone: generate *GenAsmWriter.inc + +--- + utils/TableGen/AsmWriterEmitter.cpp | 89 +++++++++++++++++++++++++++-- + utils/TableGen/AsmWriterInst.cpp | 4 ++ + 2 files changed, 87 insertions(+), 6 deletions(-) + +diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp +index 3c4c9c8e5c6..133800d217c 100644 +--- a/utils/TableGen/AsmWriterEmitter.cpp ++++ b/utils/TableGen/AsmWriterEmitter.cpp +@@ -272,16 +272,22 @@ static void UnescapeString(std::string &Str) { + /// clearing the Instructions vector. + void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + Record *AsmWriter = Target.getAsmWriter(); ++#ifndef CAPSTONE + StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); ++#endif + bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); + + O << + "/// printInstruction - This method is automatically generated by tablegen\n" + "/// from the instruction set description.\n" ++#ifdef CAPSTONE ++ "static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{\n"; ++#else + "void " << Target.getName() << ClassName + << "::printInstruction(const MCInst *MI, " + << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") + << "raw_ostream &O) {\n"; ++#endif + + // Build an aggregate string, and build a table of offsets into it. + SequenceToOffsetTable StringTable; +@@ -379,9 +385,16 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + } + + // Emit the string table itself. ++#ifdef CAPSTONE ++ O << "#ifndef CAPSTONE_DIET\n"; ++#endif + O << " static const char AsmStrs[] = {\n"; + StringTable.emit(O, printChar); +- O << " };\n\n"; ++ O << " };\n" ++#ifdef CAPSTONE ++ << "#endif\n" ++#endif ++ << "\n"; + + // Emit the lookup tables in pieces to minimize wasted bytes. + unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8; +@@ -409,21 +422,45 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + // If the total bits is more than 32-bits we need to use a 64-bit type. + if (BitsLeft < (OpcodeInfoBits - 32)) + BitsOS << "(uint64_t)"; +- BitsOS << "OpInfo" << Table << "[MI->getOpcode()] << " << Shift << ";\n"; ++ BitsOS << "OpInfo" << Table << "[" ++#ifdef CAPSTONE ++ << "MCInst_getOpcode(MI)" ++#else ++ << "MI->getOpcode()" ++#endif ++ << "] << " << Shift << ";\n"; + // Prepare the shift for the next iteration and increment the table count. + Shift += TableSize; + ++Table; + } + + // Emit the initial tab character. ++#ifndef CAPSTONE + O << " O << \"\\t\";\n\n"; ++#endif + + O << " // Emit the opcode for the instruction.\n"; + O << BitsString; + + // Emit the starting string. +- O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" +- << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; ++ O << " " ++#ifdef CAPSTONE ++ << "// " ++#endif ++ << "assert(Bits != 0 && \"Cannot print this instruction.\");\n" ++#ifdef CAPSTONE ++ << "#ifndef CAPSTONE_DIET\n" ++ << " SStream_concat0(O, " ++#else ++ << " O << " ++#endif ++ << "AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1" ++#ifdef CAPSTONE ++ << ");\n" ++ << "#endif\n\n"; ++#else ++ << ");\n\n"; ++#endif + + // Output the table driven operand information. + BitsLeft = OpcodeInfoBits-AsmStrBits; +@@ -455,7 +492,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + O << " switch ((Bits >> " + << (OpcodeInfoBits-BitsLeft) << ") & " + << ((1 << NumBits)-1) << ") {\n" +- << " default: llvm_unreachable(\"Invalid command number.\");\n"; ++ << " default: " ++#ifdef CAPSTONE ++ << "// " ++#endif ++ << "llvm_unreachable(\"Invalid command number.\");\n"; + + // Print out all the cases. + for (unsigned j = 0, e = Commands.size(); j != e; ++j) { +@@ -536,6 +577,9 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, + } + + StringTable.layout(); ++#ifdef CAPSTONE ++ O << "#ifndef CAPSTONE_DIET\n"; ++#endif + O << " static const char AsmStrs" << AltName << "[] = {\n"; + StringTable.emit(O, printChar); + O << " };\n\n"; +@@ -552,8 +596,10 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, + } + + void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { ++#ifndef CAPSTONE + Record *AsmWriter = Target.getAsmWriter(); + StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); ++#endif + const auto &Registers = Target.getRegBank().getRegisters(); + const std::vector &AltNameIndices = Target.getRegAltNameIndices(); + bool hasAltNames = AltNameIndices.size() > 1; +@@ -563,12 +609,20 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" + "/// from the register set description. This returns the assembler name\n" + "/// for the specified register.\n" ++#ifdef CAPSTONE ++ "static const char *getRegisterName(unsigned RegNo)\n{\n"; ++#else + "const char *" << Target.getName() << ClassName << "::"; + if (hasAltNames) + O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; + else + O << "getRegisterName(unsigned RegNo) {\n"; +- O << " assert(RegNo && RegNo < " << (Registers.size()+1) ++#endif ++ O << " " ++#ifdef CAPSTONE ++ << "// " ++#endif ++ << "assert(RegNo && RegNo < " << (Registers.size()+1) + << " && \"Invalid register number!\");\n" + << "\n"; + +@@ -595,10 +649,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + } + O << " }\n"; + } else { ++#ifdef CAPSTONE ++ O << " //int i;\n" ++ << " //for (i = 0; i < sizeof(RegAsmOffset); i++)\n" ++ << " // printf(\"%s = %u\\n\", AsmStrs+RegAsmOffset[i], i + 1);\n" ++ << " //printf(\"*************************\\n\");\n" ++#else + O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" + << " \"Invalid alt name index for register!\");\n" ++#endif + << " return AsmStrs+RegAsmOffset[RegNo-1];\n"; + } ++#ifdef CAPSTONE ++ O << "#else\n" ++ << " return NULL;\n" ++ << "#endif\n"; ++#endif + O << "}\n"; + } + +@@ -1135,9 +1201,20 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { + } + + void AsmWriterEmitter::run(raw_ostream &O) { ++#ifdef CAPSTONE ++ O << "/* Capstone Disassembly Engine */\n" ++ "/* By Nguyen Anh Quynh , 2013-2015 */\n" ++ "\n" ++ "#include \t// debug\n" ++ "#include \n" ++ "\n" ++ "\n"; ++#endif + EmitPrintInstruction(O); + EmitGetRegisterName(O); ++#ifndef CAPSTONE + EmitPrintAliasInstruction(O); ++#endif + } + + namespace llvm { +diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp +index 2c19e5d663d..6fa751e50df 100644 +--- a/utils/TableGen/AsmWriterInst.cpp ++++ b/utils/TableGen/AsmWriterInst.cpp +@@ -28,9 +28,13 @@ static bool isIdentChar(char C) { + + std::string AsmWriterOperand::getCode(bool PassSubtarget) const { + if (OperandType == isLiteralTextOperand) { ++#ifdef CAPSTONE ++ return "SStream_concat0(O, \"" + Str + "\");"; ++#else + if (Str.size() == 1) + return "O << '" + Str + "';"; + return "O << \"" + Str + "\";"; ++#endif + } + + if (OperandType == isLiteralStatementOperand) +-- +2.19.1 + diff --git a/llvm/0006-capstone-generate-MappingInsn.inc.patch b/llvm/0006-capstone-generate-MappingInsn.inc.patch new file mode 100644 index 000000000..7ee22d787 --- /dev/null +++ b/llvm/0006-capstone-generate-MappingInsn.inc.patch @@ -0,0 +1,174 @@ +From 7a436110ef15c803dc8524af2fb5612bcacbb126 Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Tue, 7 Aug 2018 20:55:32 +0200 +Subject: [PATCH 6/7] capstone: generate *MappingInsn.inc + +--- + lib/Target/SystemZ/CMakeLists.txt | 1 + + utils/TableGen/InstrInfoEmitter.cpp | 95 +++++++++++++++++++++++++++++ + utils/TableGen/TableGen.cpp | 6 ++ + utils/TableGen/TableGenBackends.h | 1 + + 4 files changed, 103 insertions(+) + +diff --git a/lib/Target/SystemZ/CMakeLists.txt b/lib/Target/SystemZ/CMakeLists.txt +index f83b4242fb4..4b5d9c4a3b2 100644 +--- a/lib/Target/SystemZ/CMakeLists.txt ++++ b/lib/Target/SystemZ/CMakeLists.txt +@@ -6,6 +6,7 @@ tablegen(LLVM SystemZGenCallingConv.inc -gen-callingconv) + tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel) + tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler) + tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info) ++tablegen(LLVM SystemZMappingInsn.inc -mapping-insn) + tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter) + tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM SystemZGenSubtargetInfo.inc -gen-subtarget) +diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp +index 2f3a2729262..14ab1ea8a72 100644 +--- a/utils/TableGen/InstrInfoEmitter.cpp ++++ b/utils/TableGen/InstrInfoEmitter.cpp +@@ -744,4 +744,99 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { + #endif + } + ++#ifdef CAPSTONE ++std::string GetPublicName(const CodeGenInstruction *Inst) { ++ std::string Name = Inst->TheDef->getName(); ++ // Apply backward compatibility fixups. ++ // BRNLE -> BNLER. ++ if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") { ++ Name = "B" + Name.substr(5, Name.length() - 5) + "R"; ++ } ++ // SSKEOpt -> SSKE. ++ while (Name.length() >= 3 && Name.substr(Name.length() - 3, 3) == "Opt") { ++ Name = Name.substr(0, Name.length() - 3); ++ } ++ // BRCLAsm -> BRCL. ++ while (true) { ++ size_t pos = Name.find("Asm"); ++ if (pos == std::string::npos) { ++ break; ++ } ++ Name = Name.substr(0, pos) + Name.substr(pos + 3); ++ } ++ // CPSDRxx -> CPSDR. ++ if (Name.length() >= 2) { ++ std::string Suffix2 = Name.substr(Name.length() - 2, 2); ++ if (Suffix2 == "dd" || Suffix2 == "ds" || ++ Suffix2 == "sd" || Suffix2 == "ss") { ++ Name = Name.substr(0, Name.length() - 2); ++ } ++ } ++ return "SYSZ_INS_" + Name; ++} ++ ++std::string GetRegisterName(Record *Reg) { ++ std::string Name = Reg->getName(); ++ for (char& c : Name) { ++ c = toupper(c); ++ } ++ // R0L, R0D -> R0. ++ if (Name.length() >= 3 && ++ Name[Name.length() - 3] == 'R' && ++ (Name[Name.length() - 1] == 'L' || ++ Name[Name.length() - 1] == 'D')) { ++ Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2]; ++ } ++ return "SYSZ_REG_" + Name; ++} ++ ++std::string GetGroupName(Record *Pred) { ++ std::string Name = Pred->getName(); ++ for (char& c : Name) { ++ c = toupper(c); ++ } ++ if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") { ++ Name = Name.substr(7); ++ } ++ return "SYSZ_GRP_" + Name; ++} ++ ++void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { ++ OS << "// This is auto-gen data for Capstone engine (www.capstone-engine.org)\n" ++ "// By Nguyen Anh Quynh \n" ++ "\n"; ++ CodeGenTarget Target(RK); ++ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { ++ if (Inst->TheDef->getValueAsBit("isPseudo") || ++ Inst->TheDef->getValueAsBit("isCodeGenOnly")) { ++ continue; ++ } ++ OS << "{\n" ++ << "\t" << Target.getName() << "_" << Inst->TheDef->getName() << ", " ++ << GetPublicName(Inst) << ",\n" ++ << "#ifndef CAPSTONE_DIET\n" ++ << "\t{ "; ++ for (Record *Use : Inst->TheDef->getValueAsListOfDefs("Uses")) { ++ OS << GetRegisterName(Use) << ", "; ++ } ++ OS << "0 }, { "; ++ for (Record *Def : Inst->TheDef->getValueAsListOfDefs("Defs")) { ++ OS << GetRegisterName(Def) << ", "; ++ } ++ OS << "0 }, { "; ++ ListInit *Predicates = Inst->TheDef->getValueAsListInit("Predicates"); ++ for (unsigned i = 0; i < Predicates->size(); ++i) { ++ OS << GetGroupName(Predicates->getElementAsRecord(i)) << ", "; ++ } ++ OS << "0 }, " ++ << Inst->TheDef->getValueAsBit("isBranch") ++ << ", " ++ << Inst->TheDef->getValueAsBit("isIndirectBranch") ++ << "\n" ++ << "#endif\n" ++ << "},\n"; ++ } ++} ++#endif ++ + } // end llvm namespace +diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp +index cf1404d8769..bbb4e860536 100644 +--- a/utils/TableGen/TableGen.cpp ++++ b/utils/TableGen/TableGen.cpp +@@ -27,6 +27,7 @@ enum ActionType { + GenEmitter, + GenRegisterInfo, + GenInstrInfo, ++ MappingInsn, + GenInstrDocs, + GenAsmWriter, + GenAsmMatcher, +@@ -65,6 +66,8 @@ namespace { + "Generate registers and register classes info"), + clEnumValN(GenInstrInfo, "gen-instr-info", + "Generate instruction descriptions"), ++ clEnumValN(MappingInsn, "mapping-insn", ++ ""), + clEnumValN(GenInstrDocs, "gen-instr-docs", + "Generate instruction documentation"), + clEnumValN(GenCallingConv, "gen-callingconv", +@@ -135,6 +138,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { + case GenInstrInfo: + EmitInstrInfo(Records, OS); + break; ++ case MappingInsn: ++ EmitMappingInsn(Records, OS); ++ break; + case GenInstrDocs: + EmitInstrDocs(Records, OS); + break; +diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h +index 1329a6d833f..a41e46b1db0 100644 +--- a/utils/TableGen/TableGenBackends.h ++++ b/utils/TableGen/TableGenBackends.h +@@ -75,6 +75,7 @@ void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS); + void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS); + void EmitFastISel(RecordKeeper &RK, raw_ostream &OS); + void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS); ++void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS); + void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS); + void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS); + void EmitCompressInst(RecordKeeper &RK, raw_ostream &OS); +-- +2.19.1 + diff --git a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch new file mode 100644 index 000000000..019540d65 --- /dev/null +++ b/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch @@ -0,0 +1,110 @@ +From b42f9f2014ec49a22077b6610863d9341a74e142 Mon Sep 17 00:00:00 2001 +From: mephi42 +Date: Fri, 17 Aug 2018 11:07:39 +0200 +Subject: [PATCH 7/7] capstone: generate *GenInsnNameMaps.inc + +--- + lib/Target/SystemZ/CMakeLists.txt | 1 + + utils/TableGen/InstrInfoEmitter.cpp | 29 +++++++++++++++++++++++++++++ + utils/TableGen/TableGen.cpp | 6 ++++++ + utils/TableGen/TableGenBackends.h | 1 + + 4 files changed, 37 insertions(+) + +diff --git a/lib/Target/SystemZ/CMakeLists.txt b/lib/Target/SystemZ/CMakeLists.txt +index 4b5d9c4a3b2..2c64e0a94b8 100644 +--- a/lib/Target/SystemZ/CMakeLists.txt ++++ b/lib/Target/SystemZ/CMakeLists.txt +@@ -7,6 +7,7 @@ tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel) + tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler) + tablegen(LLVM SystemZGenInstrInfo.inc -gen-instr-info) + tablegen(LLVM SystemZMappingInsn.inc -mapping-insn) ++tablegen(LLVM SystemZGenInsnNameMaps.inc -gen-insn-name-maps) + tablegen(LLVM SystemZGenMCCodeEmitter.inc -gen-emitter) + tablegen(LLVM SystemZGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM SystemZGenSubtargetInfo.inc -gen-subtarget) +diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp +index 14ab1ea8a72..ccf8170ca62 100644 +--- a/utils/TableGen/InstrInfoEmitter.cpp ++++ b/utils/TableGen/InstrInfoEmitter.cpp +@@ -837,6 +837,35 @@ void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { + << "},\n"; + } + } ++ ++std::string GetMnemonic(const CodeGenInstruction *Inst) { ++ std::string Mnemonic = Inst->AsmString; ++ ++ for (size_t i = 0; i < Mnemonic.length(); i++) { ++ if (Mnemonic[i] == '\t') { ++ return Mnemonic.substr(0, i); ++ } ++ } ++ return Mnemonic; ++} ++ ++void EmitInsnNameMaps(RecordKeeper &RK, raw_ostream &OS) { ++ OS << "// This is auto-gen data for Capstone engine (www.capstone-engine.org)\n" ++ "// By Nguyen Anh Quynh \n" ++ "\n"; ++ CodeGenTarget Target(RK); ++ std::map M; ++ for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { ++ if (Inst->TheDef->getValueAsBit("isPseudo") || ++ Inst->TheDef->getValueAsBit("isCodeGenOnly")) { ++ continue; ++ } ++ M[GetPublicName(Inst)] = GetMnemonic(Inst); ++ } ++ for (auto &P : M) { ++ OS << "\t{ " << P.first << ", \"" << P.second << "\" },\n"; ++ } ++} + #endif + + } // end llvm namespace +diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp +index bbb4e860536..27c6603de5a 100644 +--- a/utils/TableGen/TableGen.cpp ++++ b/utils/TableGen/TableGen.cpp +@@ -28,6 +28,7 @@ enum ActionType { + GenRegisterInfo, + GenInstrInfo, + MappingInsn, ++ GenInsnNameMaps, + GenInstrDocs, + GenAsmWriter, + GenAsmMatcher, +@@ -68,6 +69,8 @@ namespace { + "Generate instruction descriptions"), + clEnumValN(MappingInsn, "mapping-insn", + ""), ++ clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", ++ ""), + clEnumValN(GenInstrDocs, "gen-instr-docs", + "Generate instruction documentation"), + clEnumValN(GenCallingConv, "gen-callingconv", +@@ -141,6 +144,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { + case MappingInsn: + EmitMappingInsn(Records, OS); + break; ++ case GenInsnNameMaps: ++ EmitInsnNameMaps(Records, OS); ++ break; + case GenInstrDocs: + EmitInstrDocs(Records, OS); + break; +diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h +index a41e46b1db0..5656e5be849 100644 +--- a/utils/TableGen/TableGenBackends.h ++++ b/utils/TableGen/TableGenBackends.h +@@ -76,6 +76,7 @@ void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS); + void EmitFastISel(RecordKeeper &RK, raw_ostream &OS); + void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS); + void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS); ++void EmitInsnNameMaps(RecordKeeper &RK, raw_ostream &OS); + void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS); + void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS); + void EmitCompressInst(RecordKeeper &RK, raw_ostream &OS); +-- +2.19.1 + diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt index 07c32cb31..1821f4b01 100644 --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -6,6 +6,8 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter) tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel) tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn) +tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps) tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp index 24e16f9c4..c24dc6052 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -271,16 +271,22 @@ static void UnescapeString(std::string &Str) { /// clearing the Instructions vector. void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { Record *AsmWriter = Target.getAsmWriter(); +#ifndef CAPSTONE StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); +#endif bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); O << "/// printInstruction - This method is automatically generated by tablegen\n" "/// from the instruction set description.\n" +#ifdef CAPSTONE + "static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{\n"; +#else "void " << Target.getName() << ClassName << "::printInstruction(const MCInst *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") << "raw_ostream &O) {\n"; +#endif // Build an aggregate string, and build a table of offsets into it. SequenceToOffsetTable StringTable; @@ -378,9 +384,16 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { } // Emit the string table itself. +#ifdef CAPSTONE + O << "#ifndef CAPSTONE_DIET\n"; +#endif O << " static const char AsmStrs[] = {\n"; StringTable.emit(O, printChar); - O << " };\n\n"; + O << " };\n" +#ifdef CAPSTONE + << "#endif\n" +#endif + << "\n"; // Emit the lookup tables in pieces to minimize wasted bytes. unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8; @@ -408,21 +421,45 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { // If the total bits is more than 32-bits we need to use a 64-bit type. if (BitsLeft < (OpcodeInfoBits - 32)) BitsOS << "(uint64_t)"; - BitsOS << "OpInfo" << Table << "[MI->getOpcode()] << " << Shift << ";\n"; + BitsOS << "OpInfo" << Table << "[" +#ifdef CAPSTONE + << "MCInst_getOpcode(MI)" +#else + << "MI->getOpcode()" +#endif + << "] << " << Shift << ";\n"; // Prepare the shift for the next iteration and increment the table count. Shift += TableSize; ++Table; } // Emit the initial tab character. +#ifndef CAPSTONE O << " O << \"\\t\";\n\n"; +#endif O << " // Emit the opcode for the instruction.\n"; O << BitsString; // Emit the starting string. - O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" - << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; + O << " " +#ifdef CAPSTONE + << "// " +#endif + << "assert(Bits != 0 && \"Cannot print this instruction.\");\n" +#ifdef CAPSTONE + << "#ifndef CAPSTONE_DIET\n" + << " SStream_concat0(O, " +#else + << " O << " +#endif + << "AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1" +#ifdef CAPSTONE + << ");\n" + << "#endif\n\n"; +#else + << ");\n\n"; +#endif // Output the table driven operand information. BitsLeft = OpcodeInfoBits-AsmStrBits; @@ -454,7 +491,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { O << " switch ((Bits >> " << (OpcodeInfoBits-BitsLeft) << ") & " << ((1 << NumBits)-1) << ") {\n" - << " default: llvm_unreachable(\"Invalid command number.\");\n"; + << " default: " +#ifdef CAPSTONE + << "assert(0);\n" +#endif + << "llvm_unreachable(\"Invalid command number.\");\n"; // Print out all the cases. for (unsigned j = 0, e = Commands.size(); j != e; ++j) { @@ -535,6 +576,9 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, } StringTable.layout(); +#ifdef CAPSTONE + O << "#ifndef CAPSTONE_DIET\n"; +#endif O << " static const char AsmStrs" << AltName << "[] = {\n"; StringTable.emit(O, printChar); O << " };\n\n"; @@ -551,8 +595,10 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, } void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { +#ifndef CAPSTONE Record *AsmWriter = Target.getAsmWriter(); StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); +#endif const auto &Registers = Target.getRegBank().getRegisters(); const std::vector &AltNameIndices = Target.getRegAltNameIndices(); bool hasAltNames = AltNameIndices.size() > 1; @@ -562,12 +608,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" "/// from the register set description. This returns the assembler name\n" "/// for the specified register.\n" +#ifdef CAPSTONE + //"static const char *getRegisterName(unsigned RegNo)\n{\n"; + "static const char *"; + if (hasAltNames) + O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx)\n{\n"; + else + O << "\ngetRegisterName(unsigned RegNo)\n{\n"; +#else "const char *" << Target.getName() << ClassName << "::"; if (hasAltNames) O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; else O << "getRegisterName(unsigned RegNo) {\n"; - O << " assert(RegNo && RegNo < " << (Registers.size()+1) +#endif + O << " " + << "assert(RegNo && RegNo < " << (Registers.size()+1) << " && \"Invalid register number!\");\n" << "\n"; @@ -579,12 +635,21 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { if (hasAltNames) { O << " switch(AltIdx) {\n" +#ifdef CAPSTONE + << " default: assert(0);\n"; +#else << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; +#endif for (const Record *R : AltNameIndices) { StringRef AltName = R->getName(); O << " case "; if (!Namespace.empty()) - O << Namespace << "::"; + O << Namespace +#ifndef CAPSTONE + << "::"; +#else + << "_"; +#endif O << AltName << ":\n" << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName << "[RegNo-1]) &&\n" @@ -594,10 +659,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { } O << " }\n"; } else { +#ifdef CAPSTONE + O << " //int i;\n" + << " //for (i = 0; i < sizeof(RegAsmOffset); i++)\n" + << " // printf(\"%s = %u\\n\", AsmStrs+RegAsmOffset[i], i + 1);\n" + << " //printf(\"*************************\\n\");\n" +#else O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" << " \"Invalid alt name index for register!\");\n" +#endif << " return AsmStrs+RegAsmOffset[RegNo-1];\n"; } +#ifdef CAPSTONE + O << "#else\n" + << " return NULL;\n" + << "#endif\n"; +#endif O << "}\n"; } @@ -1139,9 +1216,21 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { } void AsmWriterEmitter::run(raw_ostream &O) { +#ifdef CAPSTONE + O << "/* Capstone Disassembly Engine */\n" + "/* By Nguyen Anh Quynh , 2013-2015 */\n" + "\n" + "#include \t// debug\n" + "#include \n" + "#include \n" + "\n" + "\n"; +#endif EmitPrintInstruction(O); EmitGetRegisterName(O); +#ifndef CAPSTONE EmitPrintAliasInstruction(O); +#endif } namespace llvm { diff --git a/llvm/utils/TableGen/AsmWriterInst.cpp b/llvm/utils/TableGen/AsmWriterInst.cpp index d065a4209..7266d1eda 100644 --- a/llvm/utils/TableGen/AsmWriterInst.cpp +++ b/llvm/utils/TableGen/AsmWriterInst.cpp @@ -27,9 +27,13 @@ static bool isIdentChar(char C) { std::string AsmWriterOperand::getCode(bool PassSubtarget) const { if (OperandType == isLiteralTextOperand) { +#ifdef CAPSTONE + return "SStream_concat0(O, \"" + Str + "\");"; +#else if (Str.size() == 1) return "O << '" + Str + "';"; return "O << \"" + Str + "\";"; +#endif } if (OperandType == isLiteralStatementOperand) diff --git a/llvm/utils/TableGen/DisassemblerEmitter.cpp b/llvm/utils/TableGen/DisassemblerEmitter.cpp index 9e75c7fba..1bc0cfa0d 100644 --- a/llvm/utils/TableGen/DisassemblerEmitter.cpp +++ b/llvm/utils/TableGen/DisassemblerEmitter.cpp @@ -105,6 +105,11 @@ extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS, void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { CodeGenTarget Target(Records); emitSourceFileHeader(" * " + Target.getName().str() + " Disassembler", OS); +#ifdef CAPSTONE + OS << "/* Capstone Disassembly Engine */\n" + "/* By Nguyen Anh Quynh , 2013-2015 */\n" + "\n"; +#endif // X86 uses a custom disassembler. if (Target.getName() == "X86") { @@ -149,7 +154,12 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { } EmitFixedLenDecoder(Records, OS, Target.getName(), - "if (", " == MCDisassembler::Fail)", + "if (", +#ifdef CAPSTONE + " == MCDisassembler_Fail)", +#else + " == MCDisassembler::Fail)", +#endif "MCDisassembler::Success", "MCDisassembler::Fail", ""); } diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp index ea28e06cc..3db428dfa 100644 --- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -741,7 +741,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, ++I; unsigned Start = *I++; unsigned Len = *I++; - OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", " + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_ExtractField" +#else + << "MCD::OPC_ExtractField" +#endif + << ", " << Start << ", " << Len << ", // Inst{"; if (Len > 1) OS << (Start + Len - 1) << "-"; @@ -750,7 +756,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, } case MCD::OPC_FilterValue: { ++I; - OS.indent(Indentation) << "MCD::OPC_FilterValue, "; + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_FilterValue" +#else + << "MCD::OPC_FilterValue" +#endif + << ", "; // The filter value is ULEB128 encoded. while (*I >= 128) OS << (unsigned)*I++ << ", "; @@ -773,7 +785,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, ++I; unsigned Start = *I++; unsigned Len = *I++; - OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", " + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_CheckField" +#else + << "MCD::OPC_CheckField" +#endif + << ", " << Start << ", " << Len << ", ";// << Val << ", " << NumToSkip << ",\n"; // ULEB128 encoded field value. for (; *I >= 128; ++I) @@ -794,7 +812,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, } case MCD::OPC_CheckPredicate: { ++I; - OS.indent(Indentation) << "MCD::OPC_CheckPredicate, "; + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_CheckPredicate" +#else + << "MCD::OPC_CheckPredicate" +#endif + << ", "; for (; *I >= 128; ++I) OS << (unsigned)*I << ", "; OS << (unsigned)*I++ << ", "; @@ -823,7 +847,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, && "ULEB128 value too large!"); // Decode the Opcode value. unsigned Opc = decodeULEB128(Buffer); - OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "") + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_" +#else + << "MCD::OPC_" +#endif + << (IsTry ? "Try" : "") << "Decode, "; for (p = Buffer; *p >= 128; ++p) OS << (unsigned)*p << ", "; @@ -858,7 +888,12 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, } case MCD::OPC_SoftFail: { ++I; - OS.indent(Indentation) << "MCD::OPC_SoftFail"; + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_SoftFail"; +#else + << "MCD::OPC_SoftFail"; +#endif // Positive mask uint64_t Value = 0; unsigned Shift = 0; @@ -890,7 +925,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, } case MCD::OPC_Fail: { ++I; - OS.indent(Indentation) << "MCD::OPC_Fail,\n"; + OS.indent(Indentation) +#ifdef CAPSTONE + << "MCD_OPC_Fail" +#else + << "MCD::OPC_Fail" +#endif + << ",\n"; break; } } @@ -905,23 +946,46 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, void FixedLenDecoderEmitter:: emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, unsigned Indentation) const { +#ifdef CAPSTONE + OS.indent(Indentation) << "static bool getbool(uint64_t b)\n"; + OS.indent(Indentation) << "{\n"; + OS.indent(Indentation) << "\treturn b != 0;\n"; + OS.indent(Indentation) << "}\n\n"; +#endif + // The predicate function is just a big switch statement based on the // input predicate index. OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, " +#ifdef CAPSTONE + << "uint64_t Bits)\n{\n"; +#else << "const FeatureBitset& Bits) {\n"; +#endif Indentation += 2; if (!Predicates.empty()) { OS.indent(Indentation) << "switch (Idx) {\n"; - OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; + OS.indent(Indentation) << "default: " +#ifdef CAPSTONE + << "assert(0);\n" +#endif + << "llvm_unreachable(\"Invalid index!\");\n"; unsigned Index = 0; for (const auto &Predicate : Predicates) { OS.indent(Indentation) << "case " << Index++ << ":\n"; - OS.indent(Indentation+2) << "return (" << Predicate << ");\n"; + OS.indent(Indentation+2) << "return " +#ifdef CAPSTONE + << "getbool" +#endif + << "(" << Predicate << ");\n"; } OS.indent(Indentation) << "}\n"; } else { // No case statement to emit - OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n"; + OS.indent(Indentation) +#ifdef CAPSTONE + << "assert(0);\n" +#endif + << "llvm_unreachable(\"Invalid index!\");\n"; } Indentation -= 2; OS.indent(Indentation) << "}\n\n"; @@ -932,23 +996,39 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, unsigned Indentation) const { // The decoder function is just a big switch statement based on the // input decoder index. +#ifdef CAPSTONE +#define EDF_EOL " \\\n" + OS.indent(Indentation) << "#define DecodeToMCInst(fname,fieldname, InsnType) \\\n"; + OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n"; + OS.indent(Indentation) << " uint64_t Address, const void *Decoder) \\\n"; + OS.indent(Indentation) << "{ \\\n"; +#else +#define EDF_EOL "\n" OS.indent(Indentation) << "template\n"; OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," << " unsigned Idx, InsnType insn, MCInst &MI,\n"; OS.indent(Indentation) << " uint64_t " << "Address, const void *Decoder, bool &DecodeComplete) {\n"; +#endif Indentation += 2; +#ifndef CAPSTONE OS.indent(Indentation) << "DecodeComplete = true;\n"; - OS.indent(Indentation) << "InsnType tmp;\n"; - OS.indent(Indentation) << "switch (Idx) {\n"; - OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n"; +#endif + OS.indent(Indentation) << "InsnType tmp;" EDF_EOL; + OS.indent(Indentation) << "switch (Idx) {" EDF_EOL; + OS.indent(Indentation) << "default:" +#ifndef CAPSTONE + << " llvm_unreachable(\"Invalid index!\");\n"; +#else + << " assert(0);\\\n"; +#endif unsigned Index = 0; for (const auto &Decoder : Decoders) { - OS.indent(Indentation) << "case " << Index++ << ":\n"; + OS.indent(Indentation) << "case " << Index++ << ":" EDF_EOL; OS << Decoder; - OS.indent(Indentation+2) << "return S;\n"; + OS.indent(Indentation+2) << "return S;" EDF_EOL; } - OS.indent(Indentation) << "}\n"; + OS.indent(Indentation) << "}" EDF_EOL; Indentation -= 2; OS.indent(Indentation) << "}\n\n"; } @@ -1075,16 +1155,21 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, const std::string &Decoder = OpInfo.Decoder; if (OpInfo.numFields() != 1) - o.indent(Indentation) << "tmp = 0;\n"; + o.indent(Indentation) << "tmp = 0;" EDF_EOL; for (const EncodingField &EF : OpInfo) { o.indent(Indentation) << "tmp "; if (OpInfo.numFields() != 1) o << '|'; - o << "= fieldFromInstruction" + o << "= " +#ifdef CAPSTONE + << "fieldname" +#else + << "fieldFromInstruction" +#endif << "(insn, " << EF.Base << ", " << EF.Width << ')'; if (OpInfo.numFields() != 1 || EF.Offset != 0) o << " << " << EF.Offset; - o << ";\n"; + o << ";" EDF_EOL; } if (Decoder != "") { @@ -1092,8 +1177,12 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, o.indent(Indentation) << Emitter->GuardPrefix << Decoder << "(MI, tmp, Address, Decoder)" << Emitter->GuardPostfix +#ifdef CAPSTONE + << " return MCDisassembler_Fail; \\\n"; +#else << " { " << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ") << "return MCDisassembler::Fail; }\n"; +#endif } else { OpHasCompleteDecoder = true; o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n"; @@ -1112,7 +1201,13 @@ void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation, << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << " { " << (HasCompleteDecoder ? "" : "DecodeComplete = false; ") - << "return MCDisassembler::Fail; }\n"; + << "return " +#ifdef CAPSTONE + << "MCDisassembler_Fail" +#else + << "MCDisassembler::Fail" +#endif + << "; }\n"; break; } @@ -1150,10 +1245,19 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, const std::string &PredicateNamespace) { if (str[0] == '!') +#ifdef CAPSTONE + o << "~(Bits & " << PredicateNamespace << "_" + << str.slice(1,str.size()) << ")"; +#else o << "!Bits[" << PredicateNamespace << "::" << str.slice(1,str.size()) << "]"; +#endif else +#ifdef CAPSTONE + o << "(Bits & " << PredicateNamespace << "_" << str << ")"; +#else o << "Bits[" << PredicateNamespace << "::" << str << "]"; +#endif } bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, @@ -2090,7 +2194,18 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { << "// * Support shift (<<, >>) with signed and unsigned integers on the " "RHS\n" << "// * Support put (<<) to raw_ostream&\n" - << "template\n" +#ifdef CAPSTONE + << "#define FieldFromInstruction(fname, InsnType) \\\n" + << "static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \\\n" + << "{ \\\n" + << " InsnType fieldMask; \\\n" + << " if (numBits == sizeof(InsnType)*8) \\\n" + << " fieldMask = (InsnType)(-1LL); \\\n" + << " else \\\n" + << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \\\n" + << " return (insn & fieldMask) >> startBit; \\\n" +#else + << "template\n" << "#if defined(_MSC_VER) && !defined(__clang__)\n" << "__declspec(noinline)\n" << "#endif\n" @@ -2127,12 +2242,239 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) { << " unsigned numBits) {\n" << " return fieldFromInstruction(insn, startBit, numBits, " "std::is_integral());\n" +#endif << "}\n\n"; } // emitDecodeInstruction - Emit the templated helper function // decodeInstruction(). static void emitDecodeInstruction(formatted_raw_ostream &OS) { + +#if 0 + OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n" + << "static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \\\n" + << " InsnType insn, uint64_t Address, const MCRegisterInfo *MRI, int feature) \\\n" + << "{ \\\n" + << " uint64_t Bits = getFeatureBits(feature); \\\n" + << " const uint8_t *Ptr = DecodeTable; \\\n" + << " uint32_t CurFieldValue = 0, ExpectedValue; \\\n" + << " DecodeStatus S = MCDisassembler_Success; \\\n" + << " unsigned Start, Len, NumToSkip, PIdx, Opc, DecodeIdx; \\\n" + << " InsnType Val, FieldValue, PositiveMask, NegativeMask; \\\n" + << " bool Pred, Fail; \\\n" + << " for (;;) { \\\n" + << " switch (*Ptr) { \\\n" + << " default: \\\n" + << " return MCDisassembler_Fail; \\\n" + << " case MCD_OPC_ExtractField: { \\\n" + << " Start = *++Ptr; \\\n" + << " Len = *++Ptr; \\\n" + << " ++Ptr; \\\n" + << " CurFieldValue = (uint32_t)fieldname(insn, Start, Len); \\\n" + << " break; \\\n" + << " } \\\n" + << " case MCD_OPC_FilterValue: { \\\n" + << " Val = (InsnType)decodeULEB128(++Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " NumToSkip = *Ptr++; \\\n" + << " NumToSkip |= (*Ptr++) << 8; \\\n" + << " if (Val != CurFieldValue) \\\n" + << " Ptr += NumToSkip; \\\n" + << " break; \\\n" + << " } \\\n" + << " case MCD_OPC_CheckField: { \\\n" + << " Start = *++Ptr; \\\n" + << " Len = *++Ptr; \\\n" + << " FieldValue = fieldname(insn, Start, Len); \\\n" + << " ExpectedValue = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " NumToSkip = *Ptr++; \\\n" + << " NumToSkip |= (*Ptr++) << 8; \\\n" + << " if (ExpectedValue != FieldValue) \\\n" + << " Ptr += NumToSkip; \\\n" + << " break; \\\n" + << " } \\\n" + << " case MCD_OPC_CheckPredicate: { \\\n" + << " PIdx = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " NumToSkip = *Ptr++; \\\n" + << " NumToSkip |= (*Ptr++) << 8; \\\n" + << " Pred = checkDecoderPredicate(PIdx, Bits); \\\n" + << " if (!Pred) \\\n" + << " Ptr += NumToSkip; \\\n" + << " (void)Pred; \\\n" + << " break; \\\n" + << " } \\\n" + << " case MCD_OPC_Decode: { \\\n" + << " Opc = (unsigned)decodeULEB128(++Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " DecodeIdx = (unsigned)decodeULEB128(Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " MCInst_setOpcode(MI, Opc); \\\n" + << " return decoder(S, DecodeIdx, insn, MI, Address, MRI); \\\n" + << " } \\\n" + << " case MCD_OPC_SoftFail: { \\\n" + << " PositiveMask = (InsnType)decodeULEB128(++Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " NegativeMask = (InsnType)decodeULEB128(Ptr, &Len); \\\n" + << " Ptr += Len; \\\n" + << " Fail = (insn & PositiveMask) || (~insn & NegativeMask); \\\n" + << " if (Fail) \\\n" + << " S = MCDisassembler_SoftFail; \\\n" + << " break; \\\n" + << " } \\\n" + << " case MCD_OPC_Fail: { \\\n" + << " return MCDisassembler_Fail; \\\n" + << " } \\\n" + << " } \\\n" + << " } \\\n" +#endif + +#ifdef CAPSTONE + OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " + + "MCInst *MI,\\\n" + << " InsnType insn, uint64_t " + "Address,\\\n" + << " const void *DisAsm,\\\n" + << " int feature) {\\\n" + << " uint64_t Bits = getFeatureBits(feature); \\\n" + //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n" + << "\\\n" + << " const uint8_t *Ptr = DecodeTable;\\\n" + << " uint32_t CurFieldValue = 0;\\\n" + << " DecodeStatus S = MCDisassembler_Success;\\\n" + << " while (true) {\\\n" + << " ptrdiff_t Loc = Ptr - DecodeTable;\\\n" + << " switch (*Ptr) {\\\n" + << " default:\\\n" + << " return MCDisassembler_Fail;\\\n" + << " case MCD_OPC_ExtractField: {\\\n" + << " unsigned Start = *++Ptr;\\\n" + << " unsigned Len = *++Ptr;\\\n" + << " ++Ptr;\\\n" + << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_FilterValue: {\\\n" + << " // Decode the field value.\\\n" + << " unsigned Len;\\\n" + << " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << "\\\n" + << " // Perform the filter operation.\\\n" + << " if (Val != CurFieldValue)\\\n" + << " Ptr += NumToSkip;\\\n" + << "\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_CheckField: {\\\n" + << " unsigned Start = *++Ptr;\\\n" + << " unsigned Len = *++Ptr;\\\n" + << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n" + << " // Decode the field value.\\\n" + << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << "\\\n" + << " // If the actual and expected values don't match, skip.\\\n" + << " if (ExpectedValue != FieldValue)\\\n" + << " Ptr += NumToSkip;\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_CheckPredicate: {\\\n" + << " unsigned Len;\\\n" + << " // Decode the Predicate Index value.\\\n" + << " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << " // Check the predicate.\\\n" + << " bool Pred;\\\n" + << " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n" + << " Ptr += NumToSkip;\\\n" + << " (void)Pred;\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_Decode: {\\\n" + << " unsigned Len;\\\n" + << " // Decode the Opcode value.\\\n" + << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << "\\\n" + << " MCInst_clear(MI);\\\n" + << " MCInst_setOpcode(MI, Opc);\\\n" + << " bool DecodeComplete;\\\n" + << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " + "DecodeComplete);\\\n" + << " assert(DecodeComplete);\\\n" + << "\\\n" + << " return S;\\\n" + << " }\\\n" + << " case MCD_OPC_TryDecode: {\\\n" + << " unsigned Len;\\\n" + << " // Decode the Opcode value.\\\n" + << " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " // NumToSkip is a plain 24-bit integer.\\\n" + << " unsigned NumToSkip = *Ptr++;\\\n" + << " NumToSkip |= (*Ptr++) << 8;\\\n" + << " NumToSkip |= (*Ptr++) << 16;\\\n" + << "\\\n" + << " // Perform the decode operation.\\\n" + << " MCInst TmpMI;\\\n" + << " MCInst_setOpcode(&TmpMI, Opc);\\\n" + << " bool DecodeComplete;\n" + << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " + "DecodeComplete);\\\n" + << " if (DecodeComplete) {\\\n" + << " // Decoding complete.\\\n" + << " MI = &TmpMI;\\\n" + << " return S;\\\n" + << " } else {\\\n" + << " assert(S == MCDisassembler_Fail);\\\n" + << " // If the decoding was incomplete, skip.\\\n" + << " Ptr += NumToSkip;\\\n" + << " // Reset decode status. This also drops a SoftFail status " + "that could be\\\n" + << " // set before the decode attempt.\\\n" + << " S = MCDisassembler_Success;\\\n" + << " }\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_SoftFail: {\\\n" + << " // Decode the mask values.\\\n" + << " unsigned Len;\\\n" + << " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " InsnType NegativeMask = decodeULEB128(Ptr, &Len);\\\n" + << " Ptr += Len;\\\n" + << " bool Fail = (insn & PositiveMask) || (~insn & NegativeMask);\\\n" + << " if (Fail)\\\n" + << " S = MCDisassembler_SoftFail;\\\n" + << " break;\\\n" + << " }\\\n" + << " case MCD_OPC_Fail: {\\\n" + << " return MCDisassembler_Fail;\\\n" + << " }\\\n" + << " }\\\n" + << " }\\\n" + << " assert(0);\\\n" + +#else OS << "template\n" << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " "MCInst &MI,\n" @@ -2313,12 +2655,19 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { << " }\n" << " llvm_unreachable(\"bogosity detected in disassembler state " "machine!\");\n" +#endif << "}\n\n"; } // Emits disassembler code for instruction decoding. void FixedLenDecoderEmitter::run(raw_ostream &o) { formatted_raw_ostream OS(o); +#ifdef CAPSTONE + OS << "#include \"../../MCInst.h\"\n"; + OS << "#include \"../../LEB128.h\"\n"; + OS << "#include \n"; + OS << "\n"; +#else OS << "#include \"llvm/MC/MCInst.h\"\n"; OS << "#include \"llvm/Support/Debug.h\"\n"; OS << "#include \"llvm/Support/DataTypes.h\"\n"; @@ -2327,6 +2676,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { OS << "#include \n"; OS << '\n'; OS << "namespace llvm {\n\n"; +#endif emitFieldFromInstruction(OS); @@ -2401,7 +2751,13 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { // Emit the main entry point for the decoder, decodeInstruction(). emitDecodeInstruction(OS); +#ifdef CAPSTONE + OS << "FieldFromInstruction(fieldFromInstruction, uint64_t)\n"; + OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint64_t)\n"; + OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint64_t)\n"; +#else OS << "\n} // End llvm namespace\n"; +#endif } namespace llvm { diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index fd8775023..797f42a50 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -92,6 +92,7 @@ private: } // end anonymous namespace +#ifndef CAPSTONE static void PrintDefList(const std::vector &Uses, unsigned Num, raw_ostream &OS) { OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; @@ -99,6 +100,7 @@ static void PrintDefList(const std::vector &Uses, OS << getQualifiedName(U) << ", "; OS << "0 };\n"; } +#endif //===----------------------------------------------------------------------===// // Operand Info Emission. @@ -434,8 +436,17 @@ void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, // run - Emit the main instruction description records for the target... void InstrInfoEmitter::run(raw_ostream &OS) { emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS); + +#ifdef CAPSTONE + OS << "/* Capstone Disassembly Engine */\n" + "/* By Nguyen Anh Quynh , 2013-2015 */\n" + "\n" + "\n"; +#endif + emitEnums(OS); +#ifndef CAPSTONE OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; OS << "#undef GET_INSTRINFO_MC_DESC\n"; @@ -563,6 +574,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { emitOperandTypesEnum(OS, Target); emitMCIIHelperMethods(OS, TargetName); +#endif } void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, @@ -680,7 +692,9 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { OS << "#ifdef GET_INSTRINFO_ENUM\n"; OS << "#undef GET_INSTRINFO_ENUM\n"; +#ifndef CAPSTONE OS << "namespace llvm {\n\n"; +#endif CodeGenTarget Target(Records); @@ -690,17 +704,39 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { if (Namespace.empty()) PrintFatalError("No instructions defined!"); +#ifndef CAPSTONE OS << "namespace " << Namespace << " {\n"; - OS << " enum {\n"; +#endif +#ifdef CAPSTONE + OS << "\n" +#else + OS << " " +#endif + << "enum {\n"; unsigned Num = 0; for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) - OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; - OS << " INSTRUCTION_LIST_END = " << Num << "\n"; + OS << " " +#ifdef CAPSTONE + << Target.getName() << "_" +#endif + << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; + OS << " " +#ifdef CAPSTONE + << Target.getName() << "_" +#endif + << "INSTRUCTION_LIST_END = " << Num << "\n"; OS << " };\n\n"; +#ifndef CAPSTONE OS << "} // end " << Namespace << " namespace\n"; OS << "} // end llvm namespace\n"; - OS << "#endif // GET_INSTRINFO_ENUM\n\n"; - +#endif + OS << "#endif // GET_INSTRINFO_ENUM\n" +#ifndef CAPSTONE + << "\n" +#endif + ; + +#ifndef CAPSTONE OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n"; OS << "#undef GET_INSTRINFO_SCHED_ENUM\n"; OS << "namespace llvm {\n\n"; @@ -717,13 +753,140 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { OS << "} // end llvm namespace\n"; OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n"; +#endif } namespace llvm { void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { InstrInfoEmitter(RK).run(OS); +#ifndef CAPSTONE EmitMapTable(RK, OS); +#endif +} + +#ifdef CAPSTONE +std::string GetPublicName(const CodeGenInstruction *Inst) { + std::string Name = Inst->TheDef->getName(); + // Apply backward compatibility fixups. + // BRNLE -> BNLER. + if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") { + Name = "B" + Name.substr(5, Name.length() - 5) + "R"; + } + // SSKEOpt -> SSKE. + while (Name.length() >= 3 && Name.substr(Name.length() - 3, 3) == "Opt") { + Name = Name.substr(0, Name.length() - 3); + } + // BRCLAsm -> BRCL. + while (true) { + size_t pos = Name.find("Asm"); + if (pos == std::string::npos) { + break; + } + Name = Name.substr(0, pos) + Name.substr(pos + 3); + } + // CPSDRxx -> CPSDR. + if (Name.length() >= 2) { + std::string Suffix2 = Name.substr(Name.length() - 2, 2); + if (Suffix2 == "dd" || Suffix2 == "ds" || + Suffix2 == "sd" || Suffix2 == "ss") { + Name = Name.substr(0, Name.length() - 2); + } + } + return "SYSZ_INS_" + Name; +} + +std::string GetRegisterName(Record *Reg) { + std::string Name = Reg->getName(); + for (char& c : Name) { + c = toupper(c); + } + // R0L, R0D -> R0. + if (Name.length() >= 3 && + Name[Name.length() - 3] == 'R' && + (Name[Name.length() - 1] == 'L' || + Name[Name.length() - 1] == 'D')) { + Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2]; + } + return "SYSZ_REG_" + Name; +} + +std::string GetGroupName(Record *Pred) { + std::string Name = Pred->getName(); + for (char& c : Name) { + c = toupper(c); + } + if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") { + Name = Name.substr(7); + } + return "SYSZ_GRP_" + Name; +} + +void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { + OS << "// This is auto-gen data for Capstone engine (www.capstone-engine.org)\n" + "// By Nguyen Anh Quynh \n" + "\n"; + CodeGenTarget Target(RK); + for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { + if (Inst->TheDef->getValueAsBit("isPseudo") || + Inst->TheDef->getValueAsBit("isCodeGenOnly")) { + continue; + } + OS << "{\n" + << "\t" << Target.getName() << "_" << Inst->TheDef->getName() << ", " + << GetPublicName(Inst) << ",\n" + << "#ifndef CAPSTONE_DIET\n" + << "\t{ "; + for (Record *Use : Inst->TheDef->getValueAsListOfDefs("Uses")) { + OS << GetRegisterName(Use) << ", "; + } + OS << "0 }, { "; + for (Record *Def : Inst->TheDef->getValueAsListOfDefs("Defs")) { + OS << GetRegisterName(Def) << ", "; + } + OS << "0 }, { "; + ListInit *Predicates = Inst->TheDef->getValueAsListInit("Predicates"); + for (unsigned i = 0; i < Predicates->size(); ++i) { + OS << GetGroupName(Predicates->getElementAsRecord(i)) << ", "; + } + OS << "0 }, " + << Inst->TheDef->getValueAsBit("isBranch") + << ", " + << Inst->TheDef->getValueAsBit("isIndirectBranch") + << "\n" + << "#endif\n" + << "},\n"; + } +} + +std::string GetMnemonic(const CodeGenInstruction *Inst) { + std::string Mnemonic = Inst->AsmString; + + for (size_t i = 0; i < Mnemonic.length(); i++) { + if (Mnemonic[i] == '\t') { + return Mnemonic.substr(0, i); + } + } + return Mnemonic; +} + +void EmitInsnNameMaps(RecordKeeper &RK, raw_ostream &OS) { + OS << "// This is auto-gen data for Capstone engine (www.capstone-engine.org)\n" + "// By Nguyen Anh Quynh \n" + "\n"; + CodeGenTarget Target(RK); + std::map M; + for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { + if (Inst->TheDef->getValueAsBit("isPseudo") || + Inst->TheDef->getValueAsBit("isCodeGenOnly")) { + continue; + } + M[GetPublicName(Inst)] = GetMnemonic(Inst); + } + for (auto &P : M) { + OS << "\t{ " << P.first << ", \"" << P.second << "\" },\n"; + } } +#endif } // end llvm namespace diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index 1b619072c..0df306680 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -98,6 +98,12 @@ private: } // end anonymous namespace +#ifdef CAPSTONE +#define NAME_PREFIX Target.getName() << "_" << +#else +#define NAME_PREFIX +#endif + // runEnums - Print out enum values for all of the registers. void RegisterInfoEmitter::runEnums(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &Bank) { @@ -106,13 +112,22 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, // Register enums are stored as uint16_t in the tables. Make sure we'll fit. assert(Registers.size() <= 0xffff && "Too many regs to fit in tables"); +#ifndef CAPSTONE StringRef Namespace = Registers.front().TheDef->getValueAsString("Namespace"); +#endif emitSourceFileHeader("Target Register Enum Values", OS); +#ifdef CAPSTONE + OS << "/* Capstone Disassembly Engine */\n" + "/* By Nguyen Anh Quynh , 2013-2015 */\n" + "\n"; +#endif + OS << "\n#ifdef GET_REGINFO_ENUM\n"; OS << "#undef GET_REGINFO_ENUM\n\n"; +#ifndef CAPSTONE OS << "namespace llvm {\n\n"; OS << "class MCRegisterClass;\n" @@ -121,16 +136,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; - OS << "enum {\n NoRegister,\n"; +#endif + + OS << "enum {\n " << NAME_PREFIX "NoRegister,\n"; for (const auto &Reg : Registers) - OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n"; + OS << " " << NAME_PREFIX Reg.getName() << " = " << Reg.EnumValue << ",\n"; assert(Registers.size() == Registers.back().EnumValue && "Register enum value mismatch!"); - OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; + OS << " " << NAME_PREFIX "NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; OS << "};\n"; +#ifndef CAPSTONE if (!Namespace.empty()) OS << "} // end namespace " << Namespace << "\n"; +#endif const auto &RegisterClasses = Bank.getRegClasses(); if (!RegisterClasses.empty()) { @@ -139,18 +158,29 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, assert(RegisterClasses.size() <= 0xffff && "Too many register classes to fit in tables"); - OS << "\n// Register classes\n\n"; + OS << "\n// Register classes\n"; +#ifndef CAPSTONE + OS << "\n"; if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; +#endif OS << "enum {\n"; for (const auto &RC : RegisterClasses) - OS << " " << RC.getName() << "RegClassID" + OS << " " << NAME_PREFIX RC.getName() << "RegClassID" << " = " << RC.EnumValue << ",\n"; - OS << "\n };\n"; +#ifdef CAPSTONE + OS +#else + OS << "\n " +#endif + << "};\n"; +#ifndef CAPSTONE if (!Namespace.empty()) OS << "} // end namespace " << Namespace << "\n\n"; +#endif } +#ifndef CAPSTONE const std::vector &RegAltNameIndices = Target.getRegAltNameIndices(); // If the only definition is the default NoRegAltName, we don't need to // emit anything. @@ -181,8 +211,11 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, if (!Namespace.empty()) OS << "} // end namespace " << Namespace << "\n\n"; } +#endif +#ifndef CAPSTONE OS << "} // end namespace llvm\n\n"; +#endif OS << "#endif // GET_REGINFO_ENUM\n\n"; } @@ -869,7 +902,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, const auto &Regs = RegBank.getRegisters(); +#ifndef CAPSTONE auto &SubRegIndices = RegBank.getSubRegIndices(); +#endif // The lists of sub-registers and super-registers go in the same array. That // allows us to share suffixes. typedef std::vector RegVec; @@ -961,25 +996,40 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, LaneMaskSeqs.layout(); SubRegIdxSeqs.layout(); +#ifndef CAPSTONE OS << "namespace llvm {\n\n"; +#endif const std::string &TargetName = Target.getName(); // Emit the shared table of differential lists. - OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n"; +#ifdef CAPSTONE + OS << "static" +#else + OS << "extern" +#endif + << " const MCPhysReg " << TargetName << "RegDiffLists[] = {\n"; DiffSeqs.emit(OS, printDiff16); OS << "};\n\n"; +#ifndef CAPSTONE // Emit the shared table of regunit lane mask sequences. OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n"; LaneMaskSeqs.emit(OS, printMask, "LaneBitmask::getAll()"); OS << "};\n\n"; +#endif // Emit the table of sub-register indexes. - OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; +#ifdef CAPSTONE + OS << "static" +#else + OS << "extern" +#endif + << " const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; SubRegIdxSeqs.emit(OS, printSubRegIndex); OS << "};\n\n"; +#ifndef CAPSTONE // Emit the table of sub-register index sizes. OS << "extern const MCRegisterInfo::SubRegCoveredBits " << TargetName << "SubRegIdxRanges[] = {\n"; @@ -989,14 +1039,22 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << Idx.getName() << "\n"; } OS << "};\n\n"; +#endif // Emit the string table. RegStrings.layout(); +#ifndef CAPSTONE OS << "extern const char " << TargetName << "RegStrings[] = {\n"; RegStrings.emit(OS, printChar); OS << "};\n\n"; +#endif - OS << "extern const MCRegisterDesc " << TargetName +#ifdef CAPSTONE + OS << "static" +#else + OS << "extern" +#endif + << " const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n"; @@ -1012,6 +1070,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << "};\n\n"; // End of register descriptors... +#ifndef CAPSTONE // Emit the table of register unit roots. Each regunit has one or two root // registers. OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2] = {\n"; @@ -1025,11 +1084,14 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << " },\n"; } OS << "};\n\n"; +#endif const auto &RegisterClasses = RegBank.getRegClasses(); // Loop over all of the register classes... emitting each one. +#ifndef CAPSTONE OS << "namespace { // Register classes...\n"; +#endif SequenceToOffsetTable RegClassStrings; @@ -1044,15 +1106,28 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the register list now. OS << " // " << Name << " Register Class...\n" - << " const MCPhysReg " << Name + << " " +#ifdef CAPSTONE + << "static " +#endif + << "const MCPhysReg " << Name << "[] = {\n "; for (Record *Reg : Order) { - OS << getQualifiedName(Reg) << ", "; +#ifdef CAPSTONE + OS << NAME_PREFIX Reg->getName() +#else + OS << getQualifiedName(Reg) +#endif + << ", "; } OS << "\n };\n\n"; OS << " // " << Name << " Bit set.\n" - << " const uint8_t " << Name + << " " +#ifdef CAPSTONE + << "static " +#endif + << "const uint8_t " << Name << "Bits[] = {\n "; BitVectorEmitter BVE; for (Record *Reg : Order) { @@ -1062,14 +1137,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "\n };\n\n"; } +#ifndef CAPSTONE OS << "} // end anonymous namespace\n\n"; +#endif RegClassStrings.layout(); +#ifndef CAPSTONE OS << "extern const char " << TargetName << "RegClassStrings[] = {\n"; RegClassStrings.emit(OS, printChar); OS << "};\n\n"; +#endif - OS << "extern const MCRegisterClass " << TargetName +#ifdef CAPSTONE + OS << "static" +#else + OS << "extern" +#endif + << " const MCRegisterClass " << TargetName << "MCRegisterClasses[] = {\n"; for (const auto &RC : RegisterClasses) { @@ -1077,13 +1161,20 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, " << RegClassStrings.get(RC.getName()) << ", " << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), " - << RC.getQualifiedName() + "RegClassID" << ", " +#ifdef CAPSTONE + << NAME_PREFIX RC.getName() +#else + << RC.getQualifiedName() +#endif + << "RegClassID" << ", " + //<< RegSize/8 << ", " << RC.CopyCost << ", " << ( RC.Allocatable ? "true" : "false" ) << " },\n"; } OS << "};\n\n"; +#ifndef CAPSTONE EmitRegMappingTables(OS, Regs, false); // Emit Reg encoding table @@ -1102,7 +1193,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << " " << Value << ",\n"; } OS << "};\n"; // End of HW encoding table +#endif +#ifndef CAPSTONE // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " @@ -1123,7 +1216,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "}\n\n"; OS << "} // end namespace llvm\n\n"; - OS << "#endif // GET_REGINFO_MC_DESC\n\n"; +#endif + OS << "#endif // GET_REGINFO_MC_DESC\n" +#ifndef CAPSTONE + << "\n" +#endif + ; } void @@ -1605,8 +1703,10 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { CodeGenRegBank &RegBank = Target.getRegBank(); runEnums(OS, Target, RegBank); runMCDesc(OS, Target, RegBank); +#ifndef CAPSTONE runTargetHeader(OS, Target, RegBank); runTargetDesc(OS, Target, RegBank); +#endif if (RegisterInfoDebug) debugDump(errs()); diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 792c957ea..3ddfd1371 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -149,7 +149,9 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS) { if (N > MAX_SUBTARGET_FEATURES) PrintFatalError("Too many subtarget features! Bump MAX_SUBTARGET_FEATURES."); +#ifndef CAPSTONE OS << "namespace " << Target << " {\n"; +#endif // Open enumeration. OS << "enum {\n"; @@ -160,12 +162,22 @@ void SubtargetEmitter::Enumeration(raw_ostream &OS) { Record *Def = DefList[i]; // Get and emit name - OS << " " << Def->getName() << " = " << i << ",\n"; + OS << " " +#ifdef CAPSTONE + << Target << "_" +#endif + << Def->getName() << " = " +#ifdef CAPSTONE + << "1ULL << " +#endif + << i << ",\n"; } // Close enumeration and namespace OS << "};\n"; +#ifndef CAPSTONE OS << "} // end namespace " << Target << "\n"; +#endif } // @@ -1786,14 +1798,27 @@ void SubtargetEmitter::EmitMCInstrAnalysisPredicateFunctions(raw_ostream &OS) { void SubtargetEmitter::run(raw_ostream &OS) { emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); +#ifdef CAPSTONE + OS << "/* Capstone Disassembly Engine, http://www.capstone-engine.org */\n" + "/* By Nguyen Anh Quynh , 2013-2015 */\n" + "\n"; +#endif + OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; OS << "#undef GET_SUBTARGETINFO_ENUM\n\n"; +#ifndef CAPSTONE OS << "namespace llvm {\n"; +#endif Enumeration(OS); +#ifdef CAPSTONE + OS << "\n"; +#else OS << "} // end namespace llvm\n\n"; +#endif OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; +#ifndef CAPSTONE OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n"; @@ -1942,6 +1967,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; EmitMCInstrAnalysisPredicateFunctions(OS); +#endif } namespace llvm { diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp index 38f81dc39..abe172be2 100644 --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -27,6 +27,8 @@ enum ActionType { GenEmitter, GenRegisterInfo, GenInstrInfo, + GenMappingInsn, + GenInsnNameMaps, GenInstrDocs, GenAsmWriter, GenAsmMatcher, @@ -68,6 +70,10 @@ namespace { "Generate registers and register classes info"), clEnumValN(GenInstrInfo, "gen-instr-info", "Generate instruction descriptions"), + clEnumValN(GenMappingInsn, "gen-mapping-insn", + ""), + clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", + ""), clEnumValN(GenInstrDocs, "gen-instr-docs", "Generate instruction documentation"), clEnumValN(GenCallingConv, "gen-callingconv", @@ -143,6 +149,12 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenInstrInfo: EmitInstrInfo(Records, OS); break; + case GenMappingInsn: + EmitMappingInsn(Records, OS); + break; + case GenInsnNameMaps: + EmitInsnNameMaps(Records, OS); + break; case GenInstrDocs: EmitInstrDocs(Records, OS); break; diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h index 135ec65c0..82f787dba 100644 --- a/llvm/utils/TableGen/TableGenBackends.h +++ b/llvm/utils/TableGen/TableGenBackends.h @@ -74,6 +74,8 @@ void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS); void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS); void EmitFastISel(RecordKeeper &RK, raw_ostream &OS); void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS); +void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS); +void EmitInsnNameMaps(RecordKeeper &RK, raw_ostream &OS); void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS); void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS); void EmitCompressInst(RecordKeeper &RK, raw_ostream &OS); -- 2.20.1