From 66794c07a825d5149f72b5072d2de8ba95d5b284 Mon Sep 17 00:00:00 2001 From: fanfuqiang Date: Thu, 28 Feb 2019 21:17:27 +0800 Subject: [PATCH] fix riscv registerclass array of genregisterinfo --- llvm/0001-capstone-riscv-patchs.patch | 3161 +++++++++++++++++ ...for-generate-RISCV-port-inc-for-CAPS.patch | 905 +++++ llvm/0003-clear-old-patchs.patch | 1602 +++++++++ .../utils/TableGen/FixedLenDecoderEmitter.cpp | 1 - llvm/utils/TableGen/RegisterInfoEmitter.cpp | 8 +- 5 files changed, 5672 insertions(+), 5 deletions(-) create mode 100644 llvm/0001-capstone-riscv-patchs.patch create mode 100644 llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch create mode 100644 llvm/0003-clear-old-patchs.patch diff --git a/llvm/0001-capstone-riscv-patchs.patch b/llvm/0001-capstone-riscv-patchs.patch new file mode 100644 index 000000000..eb3246814 --- /dev/null +++ b/llvm/0001-capstone-riscv-patchs.patch @@ -0,0 +1,3161 @@ +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 + diff --git a/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch b/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch new file mode 100644 index 000000000..a395c32a7 --- /dev/null +++ b/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch @@ -0,0 +1,905 @@ +From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 28 Feb 2019 01:37:55 +0800 +Subject: [PATCH] update TableGen for generate RISCV port inc for CAPSTONE + +--- + llvm/lib/Target/RISCV/CMakeLists.txt | 2 +- + llvm/utils/TableGen/AsmWriterEmitter.cpp | 175 ++++++++++++++++-- + .../utils/TableGen/FixedLenDecoderEmitter.cpp | 122 ++++++------ + llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 +- + llvm/utils/TableGen/RegisterInfoEmitter.cpp | 20 +- + llvm/utils/TableGen/TableGen.cpp | 6 + + 6 files changed, 249 insertions(+), 90 deletions(-) + +diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt +index 1821f4b01..603aa3f54 100644 +--- a/llvm/lib/Target/RISCV/CMakeLists.txt ++++ b/llvm/lib/Target/RISCV/CMakeLists.txt +@@ -6,7 +6,7 @@ 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 RISCVMappingInsn.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) +diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp +index c24dc6052..ac82573fe 100644 +--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp ++++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp +@@ -270,12 +270,13 @@ static void UnescapeString(std::string &Str) { + /// implementation. Destroys all instances of AsmWriterInst information, by + /// clearing the Instructions vector. + void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { ++#ifdef CAPSTONE ++ bool PassSubtarget = false; ++#else + Record *AsmWriter = Target.getAsmWriter(); +-#ifndef CAPSTONE + StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); +-#endif + bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); +- ++#endif + O << + "/// printInstruction - This method is automatically generated by tablegen\n" + "/// from the instruction set description.\n" +@@ -434,7 +435,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + } + + // Emit the initial tab character. +-#ifndef CAPSTONE ++#ifdef CAPSTONE ++ O << "#ifndef CAPSTONE_DIET\n" ++ << " SStream_concat0(O, \"\\t\");\n" ++ << "#endif\n\n"; ++#else + O << " O << \"\\t\";\n\n"; + #endif + +@@ -493,10 +498,10 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { + << ((1 << NumBits)-1) << ") {\n" + << " default: " + #ifdef CAPSTONE +- << "assert(0);\n" +-#endif ++ << "assert(0 && \"Invalid command number.\");\n"; ++#else + << "llvm_unreachable(\"Invalid command number.\");\n"; +- ++#endif + // Print out all the cases. + for (unsigned j = 0, e = Commands.size(); j != e; ++j) { + O << " case " << j << ":\n"; +@@ -576,9 +581,7 @@ 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"; +@@ -625,7 +628,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + O << " " + << "assert(RegNo && RegNo < " << (Registers.size()+1) + << " && \"Invalid register number!\");\n" +- << "\n"; ++ << "\n" ++ << "#ifndef CAPSTONE_DIET\n"; + + if (hasAltNames) { + for (const Record *R : AltNameIndices) +@@ -636,7 +640,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { + if (hasAltNames) { + O << " switch(AltIdx) {\n" + #ifdef CAPSTONE +- << " default: assert(0);\n"; ++ << " default: assert(0 && \"Invalid register alt name index!\");\n"; + #else + << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; + #endif +@@ -886,7 +890,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + IAPrinter IAP(CGA.Result->getAsString(), FlatAliasAsmString); + ++#ifndef CAPSTONE // Silence the compiler waring. + StringRef Namespace = Target.getName(); ++#endif + std::vector ReqFeatures; + if (PassSubtarget) { + // We only consider ReqFeatures predicates if PassSubtarget +@@ -902,7 +908,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + NumMIOps += ResultInstOpnd.MINumOperands; + + std::string Cond; ++#ifdef CAPSTONE ++ Cond = std::string("MCInst_getNumOperands(MI) == ") + utostr(NumMIOps); ++#else + Cond = std::string("MI->getNumOperands() == ") + utostr(NumMIOps); ++#endif + IAP.addCond(Cond); + + bool CantHandle = false; +@@ -926,9 +936,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + } + break; + } +- ++#ifdef CAPSTONE ++ std::string Op = "MCInst_getOperand(MI, " + utostr(MIOpNum) + ")"; ++#else + std::string Op = "MI->getOperand(" + utostr(MIOpNum) + ")"; +- ++#endif + const CodeGenInstAlias::ResultOperand &RO = CGA.ResultOperands[i]; + + switch (RO.Kind) { +@@ -954,19 +966,39 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + if (Rec->isSubClassOf("RegisterOperand")) + Rec = Rec->getValueAsDef("RegClass"); + if (Rec->isSubClassOf("RegisterClass")) { ++#ifdef CAPSTONE ++ IAP.addCond("MCOperand_isReg(" + Op + ")"); ++#else + IAP.addCond(Op + ".isReg()"); ++#endif + + if (!IAP.isOpMapped(ROName)) { + IAP.addOperand(ROName, MIOpNum, PrintMethodIdx); + Record *R = CGA.ResultOperands[i].getRecord(); + if (R->isSubClassOf("RegisterOperand")) + R = R->getValueAsDef("RegClass"); ++ ++#ifdef CAPSTONE ++ Cond = std::string("MCRegisterClass_contains(") + ++ "MCRegisterInfo_getRegClass(" + "MRI, " + ++ Target.getName().str() + "_" + R->getName().str() + "RegClassID)" + ++ ", " + ++ "MCOperand_getReg(" + Op + "))"; ++#else + Cond = std::string("MRI.getRegClass(") + Target.getName().str() + + "::" + R->getName().str() + "RegClassID).contains(" + Op + + ".getReg())"; ++#endif ++ + } else { ++#ifdef CAPSTONE ++ Cond = std::string("MCOperand_getReg(") + Op + ") == " + ++ "MCOperand_getReg(MCInst_getOperand(MI, " + ++ utostr(IAP.getOpIndex(ROName)) + "))"; ++#else + Cond = Op + ".getReg() == MI->getOperand(" + + utostr(IAP.getOpIndex(ROName)) + ").getReg()"; ++#endif + } + } else { + // Assume all printable operands are desired for now. This can be +@@ -984,8 +1016,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + break; // No conditions on this operand at all + } + Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op + ++ #ifdef CAPSTONE ++ ", " + utostr(Entry) + ")").str(); ++ #else + ", STI, " + utostr(Entry) + ")") + .str(); ++ #endif + } + // for all subcases of ResultOperand::K_Record: + IAP.addCond(Cond); +@@ -994,9 +1030,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + case CodeGenInstAlias::ResultOperand::K_Imm: { + // Just because the alias has an immediate result, doesn't mean the + // MCInst will. An MCExpr could be present, for example. ++#ifdef CAPSTONE ++ IAP.addCond("MCOperand_isImm(" + Op + ")"); ++ Cond = "MCOperand_getImm(" + Op + ") == " + ++ itostr(CGA.ResultOperands[i].getImm()); ++#else + IAP.addCond(Op + ".isImm()"); +- + Cond = Op + ".getImm() == " + itostr(CGA.ResultOperands[i].getImm()); ++#endif ++ + IAP.addCond(Cond); + break; + } +@@ -1008,8 +1050,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + break; + } + ++#ifdef CAPSTONE ++ Cond = "MCOperand_getReg(" + Op + ") == " + Target.getName().str() + ++ "_" + CGA.ResultOperands[i].getRegister()->getName().str(); ++#else + Cond = Op + ".getReg() == " + Target.getName().str() + "::" + + CGA.ResultOperands[i].getRegister()->getName().str(); ++#endif ++ + IAP.addCond(Cond); + break; + } +@@ -1019,6 +1067,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (CantHandle) continue; + ++#ifndef CAPSTONE + for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) { + Record *R = *I; + StringRef AsmCondString = R->getValueAsString("AssemblerCondString"); +@@ -1040,6 +1089,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + IAP.addCond(Cond); + } + } ++#endif + + IAPrinterMap[Aliases.first].push_back(std::move(IAP)); + } +@@ -1052,10 +1102,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + std::string Header; + raw_string_ostream HeaderO(Header); + ++#ifdef CAPSTONE ++ HeaderO << "\nstatic bool printAliasInstr(MCInst *MI, SStream * OS, void *info)" ++ << "\n" ++ << "{\n" ++ << " MCRegisterInfo *MRI = (MCRegisterInfo *) info;\n"; ++#else + HeaderO << "bool " << Target.getName() << ClassName + << "::printAliasInstr(const MCInst" + << " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") + << "raw_ostream &OS) {\n"; ++#endif + + std::string Cases; + raw_string_ostream CasesO(Cases); +@@ -1079,7 +1136,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (UniqueIAPs.empty()) continue; + ++#ifdef CAPSTONE ++ // TODO: tricky. ++ const char* tmpCase = Entry.first.c_str(); ++ assert (Entry.first.size() > 7); ++ CasesO.indent(2) << "case " ++ << "RISCV_" << std::string(tmpCase + 7) // strlen("RISCV::) == 7 ++ << ":\n"; ++#else + CasesO.indent(2) << "case " << Entry.first << ":\n"; ++#endif + + for (IAPrinter *IAP : UniqueIAPs) { + CasesO.indent(4); +@@ -1100,13 +1166,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (!MCOpPredicates.empty()) + O << "static bool " << Target.getName() << ClassName ++#ifdef CAPSTONE ++ << "ValidateMCOperand(MCOperand *MCOp,\n" ++#else + << "ValidateMCOperand(const MCOperand &MCOp,\n" + << " const MCSubtargetInfo &STI,\n" ++#endif + << " unsigned PredicateIndex);\n"; + + O << HeaderO.str(); + O.indent(2) << "const char *AsmString;\n"; ++#ifdef CAPSTONE ++ O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n"; ++#else + O.indent(2) << "switch (MI->getOpcode()) {\n"; ++#endif + O.indent(2) << "default: return false;\n"; + O << CasesO.str(); + O.indent(2) << "}\n\n"; +@@ -1114,14 +1188,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + // Code that prints the alias, replacing the operands with the ones from the + // MCInst. + O << " unsigned I = 0;\n"; ++#ifdef CAPSTONE ++ O << " char *tmpString = cs_strdup(AsmString);\n"; ++#endif + O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n"; + O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n"; + O << " ++I;\n"; ++#ifdef CAPSTONE ++ O << " tmpString[I] = 0;\n"; ++ O << " SStream_concat0(OS, \"\\t\");\n"; ++ O << " SStream_concat0(OS, tmpString);\n"; ++ O << " SStream_concat0(OS, \"\\n\");\n"; ++#else + O << " OS << '\\t' << StringRef(AsmString, I);\n"; +- ++#endif + O << " if (AsmString[I] != '\\0') {\n"; + O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n"; ++#ifdef CAPSTONE ++ O << " SStream_concat0(OS, \"\\t\");\n"; ++#else + O << " OS << '\\t';\n"; ++#endif + O << " ++I;\n"; + O << " }\n"; + O << " do {\n"; +@@ -1131,15 +1218,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + O << " ++I;\n"; + O << " int OpIdx = AsmString[I++] - 1;\n"; + O << " int PrintMethodIdx = AsmString[I++] - 1;\n"; ++#ifdef CAPSTONE ++ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n"; ++#else + O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, "; + O << (PassSubtarget ? "STI, " : ""); + O << "OS);\n"; ++#endif + O << " } else\n"; ++ ++#ifdef CAPSTONE ++ O << " printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS);\n"; ++#else + O << " printOperand(MI, unsigned(AsmString[I++]) - 1, "; + O << (PassSubtarget ? "STI, " : ""); + O << "OS);\n"; ++#endif + O << " } else {\n"; ++#ifdef CAPSTONE ++ O << " SStream_concat0(OS, &AsmString[I++]);\n"; ++#else + O << " OS << AsmString[I++];\n"; ++#endif + O << " }\n"; + O << " } while (AsmString[I] != '\\0');\n"; + O << " }\n\n"; +@@ -1150,25 +1250,48 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + ////////////////////////////// + // Write out the printCustomAliasOperand function + ////////////////////////////// +- ++#ifdef CAPSTONE ++ O << "static void " ++#else + O << "void " << Target.getName() << ClassName << "::" ++#endif + << "printCustomAliasOperand(\n" ++#ifdef CAPSTONE ++ << " MCInst *MI, unsigned OpIdx,\n" ++#else + << " const MCInst *MI, unsigned OpIdx,\n" ++#endif + << " unsigned PrintMethodIdx,\n" ++#ifdef CAPSTONE ++ << " SStream *OS) {\n"; ++#else + << (PassSubtarget ? " const MCSubtargetInfo &STI,\n" : "") + << " raw_ostream &OS) {\n"; ++#endif + if (PrintMethods.empty()) ++#ifdef CAPSTONE ++ O << " assert(0 && \"Unknown PrintMethod kind\");\n"; ++#else + O << " llvm_unreachable(\"Unknown PrintMethod kind\");\n"; ++#endif + else { + O << " switch (PrintMethodIdx) {\n" + << " default:\n" ++#ifdef CAPSTONE ++ << " assert(0 && \"Unknown PrintMethod kind\");\n" ++#else + << " llvm_unreachable(\"Unknown PrintMethod kind\");\n" ++#endif + << " break;\n"; + + for (unsigned i = 0; i < PrintMethods.size(); ++i) { + O << " case " << i << ":\n" + << " " << PrintMethods[i] << "(MI, OpIdx, " ++#ifdef CAPSTONE ++ << "OS);\n" ++#else + << (PassSubtarget ? "STI, " : "") << "OS);\n" ++#endif + << " break;\n"; + } + O << " }\n"; +@@ -1177,9 +1300,20 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + + if (!MCOpPredicates.empty()) { + O << "static bool " << Target.getName() << ClassName ++#ifdef CAPSTONE ++ << "ValidateMCOperand(MCOperand *MCOp,\n" ++#else + << "ValidateMCOperand(const MCOperand &MCOp,\n" + << " const MCSubtargetInfo &STI,\n" +- << " unsigned PredicateIndex) {\n" ++#endif ++ << " unsigned PredicateIndex) {\n" ++#ifdef CAPSTONE ++ << " // TODO: need some constant untils operate the MCOperand,\n" ++ << " // but current CAPSTONE does't have.\n" ++ << " // So, We just return true\n" ++ << " return true;\n\n" ++ << "#if 0\n" ++#endif + << " switch (PredicateIndex) {\n" + << " default:\n" + << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" +@@ -1195,6 +1329,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { + llvm_unreachable("Unexpected MCOperandPredicate field!"); + } + O << " }\n" ++#ifdef CAPSTONE ++ << "#endif\n" ++#endif + << "}\n\n"; + } + +@@ -1228,7 +1365,7 @@ void AsmWriterEmitter::run(raw_ostream &O) { + #endif + EmitPrintInstruction(O); + EmitGetRegisterName(O); +-#ifndef CAPSTONE ++#ifdef CAPSTONE + EmitPrintAliasInstruction(O); + #endif + } +diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +index 3db428dfa..e1bfaa934 100644 +--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp ++++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +@@ -946,13 +946,6 @@ 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, " +@@ -966,26 +959,25 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, + OS.indent(Indentation) << "switch (Idx) {\n"; + OS.indent(Indentation) << "default: " + #ifdef CAPSTONE +- << "assert(0);\n" +-#endif ++ << "assert(0 && \"Invalid index!\");\n"; ++#else + << "llvm_unreachable(\"Invalid index!\");\n"; ++#endif + unsigned Index = 0; + for (const auto &Predicate : Predicates) { + OS.indent(Indentation) << "case " << Index++ << ":\n"; + OS.indent(Indentation+2) << "return " +-#ifdef CAPSTONE +- << "getbool" +-#endif +- << "(" << Predicate << ");\n"; ++ << Predicate << ";\n"; + } + OS.indent(Indentation) << "}\n"; + } else { + // No case statement to emit + OS.indent(Indentation) + #ifdef CAPSTONE +- << "assert(0);\n" +-#endif ++ << "assert(0 && \"Invalid index!\");\n"; ++#else + << "llvm_unreachable(\"Invalid index!\");\n"; ++#endif + } + Indentation -= 2; + OS.indent(Indentation) << "}\n\n"; +@@ -998,10 +990,11 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, + // 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"; ++ 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) << " bool *DecodeComplete) {\\\n"; + #else + #define EDF_EOL "\n" + OS.indent(Indentation) << "template\n"; +@@ -1011,16 +1004,18 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, + << "Address, const void *Decoder, bool &DecodeComplete) {\n"; + #endif + Indentation += 2; +-#ifndef CAPSTONE ++#ifdef CAPSTONE ++ OS.indent(Indentation) << "*DecodeComplete = true;\\\n"; ++#else + OS.indent(Indentation) << "DecodeComplete = true;\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"; ++#ifdef CAPSTONE ++ << " assert(0 && \"Invalid index!\");\\\n"; + #else +- << " assert(0);\\\n"; ++ << " llvm_unreachable(\"Invalid index!\");\n"; + #endif + unsigned Index = 0; + for (const auto &Decoder : Decoders) { +@@ -1174,8 +1169,27 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, + + if (Decoder != "") { + OpHasCompleteDecoder = OpInfo.HasCompleteDecoder; ++#ifdef CAPSTONE ++ std::string::size_type posOfLeftAngle = 0, posOfRightAngle = 0; ++ posOfLeftAngle = Decoder.find("<"); ++ posOfRightAngle = Decoder.find(">"); ++ std::string printDecoder = Decoder; ++ if (posOfLeftAngle != std::string::npos && ++ posOfRightAngle != std::string::npos) { ++ printDecoder = Decoder.substr(0, posOfLeftAngle); ++ o.indent(Indentation) << Emitter->GuardPrefix ++ << printDecoder ++ << "(MI, tmp, Address, Decoder, " ++ << Decoder.substr(posOfLeftAngle+1, posOfRightAngle-posOfLeftAngle-1); ++ } else ++ o.indent(Indentation) << Emitter->GuardPrefix << Decoder ++ << "(MI, tmp, Address, Decoder"; ++ // trick. ++ o << ")" ++#else + o.indent(Indentation) << Emitter->GuardPrefix << Decoder + << "(MI, tmp, Address, Decoder)" ++#endif + << Emitter->GuardPostfix + #ifdef CAPSTONE + << " return MCDisassembler_Fail; \\\n"; +@@ -1246,7 +1260,7 @@ static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, + const std::string &PredicateNamespace) { + if (str[0] == '!') + #ifdef CAPSTONE +- o << "~(Bits & " << PredicateNamespace << "_" ++ o << "!(Bits & " << PredicateNamespace << "_" + << str.slice(1,str.size()) << ")"; + #else + o << "!Bits[" << PredicateNamespace << "::" +@@ -2331,15 +2345,13 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + #endif + + #ifdef CAPSTONE +- OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +- ++ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n" ++ << "static DecodeStatus fname(const uint8_t DecodeTable[], " + "MCInst *MI,\\\n" +- << " InsnType insn, uint64_t " ++ << " 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" ++ << " const void *DisAsm, int feature) {\\\n" ++ << " uint64_t Bits = getFeatureBits(feature);\\\n" + << "\\\n" + << " const uint8_t *Ptr = DecodeTable;\\\n" + << " uint32_t CurFieldValue = 0;\\\n" +@@ -2353,52 +2365,42 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " unsigned Start = *++Ptr;\\\n" + << " unsigned Len = *++Ptr;\\\n" + << " ++Ptr;\\\n" +- << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n" ++ << " CurFieldValue = fieldname(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" ++ << " InsnType FieldValue = fieldname(insn, Start, Len);\\\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" +@@ -2407,7 +2409,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " }\\\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" +@@ -2416,47 +2417,39 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " MCInst_clear(MI);\\\n" + << " MCInst_setOpcode(MI, Opc);\\\n" + << " bool DecodeComplete;\\\n" +- << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, " +- "DecodeComplete);\\\n" ++ << " S = decoder(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" ++ << " bool DecodeComplete;\\\n" ++ << " S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, " ++ "&DecodeComplete);\\\n" ++ << "\\\n" + << " if (DecodeComplete) {\\\n" +- << " // Decoding complete.\\\n" +- << " MI = &TmpMI;\\\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" +@@ -2472,8 +2465,8 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { + << " }\\\n" + << " }\\\n" + << " }\\\n" +- << " assert(0);\\\n" +- ++ << " assert(0 && \"bogosity detected in disassembler state " ++ "machine!\");\\\n" + #else + OS << "template\n" + << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], " +@@ -2752,9 +2745,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { + 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"; ++ OS << "// For RISCV instruction is 32 bits.\n"; ++ OS << "FieldFromInstruction(fieldFromInstruction, uint32_t)\n"; ++ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t)\n"; ++ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t)\n"; + #else + OS << "\n} // End llvm namespace\n"; + #endif +diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp +index 01605184f..e59dace24 100644 +--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp ++++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp +@@ -769,6 +769,7 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { + #ifdef CAPSTONE + std::string GetPublicName(const CodeGenInstruction *Inst) { + std::string Name = Inst->TheDef->getName(); ++#if 0 + // Apply backward compatibility fixups. + // BRNLE -> BNLER. + if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") { +@@ -785,7 +786,7 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { + break; + } + Name = Name.substr(0, pos) + Name.substr(pos + 3); +- } ++ }f 0 + // CPSDRxx -> CPSDR. + if (Name.length() >= 2) { + std::string Suffix2 = Name.substr(Name.length() - 2, 2); +@@ -794,7 +795,8 @@ std::string GetPublicName(const CodeGenInstruction *Inst) { + Name = Name.substr(0, Name.length() - 2); + } + } +- return "SYSZ_INS_" + Name; ++#endif ++ return "RISCV_INS_" + Name; + } + + std::string GetRegisterName(Record *Reg) { +@@ -802,6 +804,7 @@ std::string GetRegisterName(Record *Reg) { + for (char& c : Name) { + c = toupper(c); + } ++#if 0 + // R0L, R0D -> R0. + if (Name.length() >= 3 && + Name[Name.length() - 3] == 'R' && +@@ -809,7 +812,8 @@ std::string GetRegisterName(Record *Reg) { + Name[Name.length() - 1] == 'D')) { + Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2]; + } +- return "SYSZ_REG_" + Name; ++#endif ++ return "RISCV_REG_" + Name; + } + + std::string GetGroupName(Record *Pred) { +@@ -817,10 +821,12 @@ std::string GetGroupName(Record *Pred) { + for (char& c : Name) { + c = toupper(c); + } ++#if 0 + if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") { + Name = Name.substr(7); + } +- return "SYSZ_GRP_" + Name; ++#endif ++ return "RISCV_GRP_" + Name; + } + + void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) { +diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +index 0df306680..cf9c352d7 100644 +--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp ++++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp +@@ -180,12 +180,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + #endif + } + +-#ifndef CAPSTONE + const std::vector &RegAltNameIndices = Target.getRegAltNameIndices(); + // If the only definition is the default NoRegAltName, we don't need to + // emit anything. + if (RegAltNameIndices.size() > 1) { + OS << "\n// Register alternate name indices\n\n"; ++#ifdef CAPSTONE ++ OS << "enum {\n"; ++ for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i) ++ OS << " " << NAME_PREFIX RegAltNameIndices[i]->getName() ++ << ",\t// " << i << "\n"; ++ OS << " " << NAME_PREFIX "NUM_TARGET_REG_ALT_NAMES = " ++ << RegAltNameIndices.size() << "\n"; ++ OS << "};\n"; ++#else + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n"; +@@ -195,11 +203,19 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + OS << "};\n"; + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n\n"; ++#endif + } + + auto &SubRegIndices = Bank.getSubRegIndices(); + if (!SubRegIndices.empty()) { + OS << "\n// Subregister indices\n\n"; ++#ifdef CAPSTONE ++ OS << "enum {\n" << " " << NAME_PREFIX "NoSubRegister,\n"; ++ unsigned i = 0; ++ for (const auto &Idx : SubRegIndices) ++ OS << " " << NAME_PREFIX Idx.getName() << ",\t// " << ++i << "\n"; ++ OS << " " << NAME_PREFIX "NUM_TARGET_SUBREGS\n};\n"; ++#else + std::string Namespace = SubRegIndices.front().getNamespace(); + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; +@@ -210,8 +226,8 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, + OS << " NUM_TARGET_SUBREGS\n};\n"; + if (!Namespace.empty()) + OS << "} // end namespace " << Namespace << "\n\n"; +- } + #endif ++ } + + #ifndef CAPSTONE + OS << "} // end namespace llvm\n\n"; +diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp +index 9e2a868be..7ec93c0e0 100644 +--- a/llvm/utils/TableGen/TableGen.cpp ++++ b/llvm/utils/TableGen/TableGen.cpp +@@ -27,8 +27,10 @@ enum ActionType { + GenEmitter, + GenRegisterInfo, + GenInstrInfo, ++#ifdef CAPSTONE + GenMappingInsn, + GenInsnNameMaps, ++#endif + GenInstrDocs, + GenAsmWriter, + GenAsmMatcher, +@@ -76,10 +78,12 @@ namespace { + "Generate registers and register classes info"), + clEnumValN(GenInstrInfo, "gen-instr-info", + "Generate instruction descriptions"), ++#ifdef CAPSTONE + clEnumValN(GenMappingInsn, "gen-mapping-insn", + ""), + clEnumValN(GenInsnNameMaps, "gen-insn-name-maps", + ""), ++#endif + clEnumValN(GenInstrDocs, "gen-instr-docs", + "Generate instruction documentation"), + clEnumValN(GenCallingConv, "gen-callingconv", +@@ -160,12 +164,14 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) { + case GenInstrInfo: + EmitInstrInfo(Records, OS); + break; ++#ifdef CAPSTONE + case GenMappingInsn: + EmitMappingInsn(Records, OS); + break; + case GenInsnNameMaps: + EmitInsnNameMaps(Records, OS); + break; ++#endif + case GenInstrDocs: + EmitInstrDocs(Records, OS); + break; +-- +2.20.1 + diff --git a/llvm/0003-clear-old-patchs.patch b/llvm/0003-clear-old-patchs.patch new file mode 100644 index 000000000..720024662 --- /dev/null +++ b/llvm/0003-clear-old-patchs.patch @@ -0,0 +1,1602 @@ +From 02eecf3f85ad03f12babab3067f2c1bcfff35ed3 Mon Sep 17 00:00:00 2001 +From: fanfuqiang +Date: Thu, 28 Feb 2019 01:50:13 +0800 +Subject: [PATCH] clear old 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 ---- + 7 files changed, 1535 deletions(-) + delete mode 100644 llvm/0001-capstone-generate-GenRegisterInfo.inc.patch + delete mode 100644 llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch + delete mode 100644 llvm/0003-capstone-generate-GenInstrInfo.inc.patch + delete mode 100644 llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch + delete mode 100644 llvm/0005-capstone-generate-GenAsmWriter.inc.patch + delete mode 100644 llvm/0006-capstone-generate-MappingInsn.inc.patch + delete 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 +deleted file mode 100644 +index b51aa515a..000000000 +--- a/llvm/0001-capstone-generate-GenRegisterInfo.inc.patch ++++ /dev/null +@@ -1,338 +0,0 @@ +-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 +deleted file mode 100644 +index 56ad28256..000000000 +--- a/llvm/0002-capstone-generate-GenSubtargetInfo.inc.patch ++++ /dev/null +@@ -1,86 +0,0 @@ +-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 +deleted file mode 100644 +index 2baa59fc9..000000000 +--- a/llvm/0003-capstone-generate-GenInstrInfo.inc.patch ++++ /dev/null +@@ -1,130 +0,0 @@ +-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 +deleted file mode 100644 +index 0002b81b4..000000000 +--- a/llvm/0004-capstone-generate-GenDisassemblerTables.inc.patch ++++ /dev/null +@@ -1,472 +0,0 @@ +-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 +deleted file mode 100644 +index cd1353eb7..000000000 +--- a/llvm/0005-capstone-generate-GenAsmWriter.inc.patch ++++ /dev/null +@@ -1,225 +0,0 @@ +-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 +deleted file mode 100644 +index 7ee22d787..000000000 +--- a/llvm/0006-capstone-generate-MappingInsn.inc.patch ++++ /dev/null +@@ -1,174 +0,0 @@ +-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 +deleted file mode 100644 +index 019540d65..000000000 +--- a/llvm/0007-capstone-generate-GenInsnNameMaps.inc.patch ++++ /dev/null +@@ -1,110 +0,0 @@ +-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 +- +-- +2.20.1 + diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp index e1bfaa934..bf352f717 100644 --- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -2357,7 +2357,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) { << " 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" diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index cf9c352d7..6064a20cd 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1175,17 +1175,17 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, for (const auto &RC : RegisterClasses) { assert(isInt<8>(RC.CopyCost) && "Copy cost too large."); OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, " - << RegClassStrings.get(RC.getName()) << ", " - << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), " #ifdef CAPSTONE - << NAME_PREFIX RC.getName() + << "sizeof(" << RC.getName() << "Bits) },\n"; #else + << RegClassStrings.get(RC.getName()) << ", " + << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), " << RC.getQualifiedName() -#endif << "RegClassID" << ", " //<< RegSize/8 << ", " << RC.CopyCost << ", " << ( RC.Allocatable ? "true" : "false" ) << " },\n"; +#endif } OS << "};\n\n"; -- 2.20.1