| From 9f8b248761db00ff85959d51258d963d1b8e5627 Mon Sep 17 00:00:00 2001 |
| From: fanfuqiang <feqin1023@gmail.com> |
| Date: Thu, 28 Feb 2019 21:18:04 +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 --------- |
| 3 files changed, 5668 deletions(-) |
| delete mode 100644 llvm/0001-capstone-riscv-patchs.patch |
| delete mode 100644 llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch |
| delete mode 100644 llvm/0003-clear-old-patchs.patch |
| |
| diff --git a/llvm/0001-capstone-riscv-patchs.patch b/llvm/0001-capstone-riscv-patchs.patch |
| deleted file mode 100644 |
| index eb3246814..000000000 |
| --- a/llvm/0001-capstone-riscv-patchs.patch |
| +++ /dev/null |
| @@ -1,3161 +0,0 @@ |
| -From 3373228170bbc2324d223bdeca761de3b4565508 Mon Sep 17 00:00:00 2001 |
| -From: fanfuqiang <feqin1023@gmail.com> |
| -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 <mephi42@gmail.com> |
| -+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 <aquynh@gmail.com>, 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<Record*> &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<const CodeGenRegister*> 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<std::string> 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 <mephi42@gmail.com> |
| -+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 <aquynh@gmail.com>, 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 <mephi42@gmail.com> |
| -+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<Record*> &Uses, |
| -+ unsigned Num, raw_ostream &OS) { |
| -+ OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; |
| -+@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector<Record*> &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 <aquynh@gmail.com>, 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 <mephi42@gmail.com> |
| -+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 <aquynh@gmail.com>, 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<typename InsnType>\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<typename InsnType>\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<typename InsnType>\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 <assert.h>\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 <mephi42@gmail.com> |
| -+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<std::string> 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<Record*> &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 <aquynh@gmail.com>, 2013-2015 */\n" |
| -++ "\n" |
| -++ "#include <stdio.h>\t// debug\n" |
| -++ "#include <capstone/platform.h>\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 <mephi42@gmail.com> |
| -+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 <aquynh@gmail.com>\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 <mephi42@gmail.com> |
| -+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 <aquynh@gmail.com>\n" |
| -++ "\n"; |
| -++ CodeGenTarget Target(RK); |
| -++ std::map<std::string, std::string> 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<std::string> 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<Record*> &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 <aquynh@gmail.com>, 2013-2015 */\n" |
| -+ "\n" |
| -+ "#include <stdio.h>\t// debug\n" |
| -+ "#include <capstone/platform.h>\n" |
| -+ "#include <assert.h>\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 <aquynh@gmail.com>, 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<typename InsnType>\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<typename InsnType>\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<typename InsnType>\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<InsnType>());\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<typename InsnType>\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 <assert.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"; |
| -@@ -2327,6 +2676,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { |
| - OS << "#include <assert.h>\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<Record*> &Uses, |
| - unsigned Num, raw_ostream &OS) { |
| - OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; |
| -@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector<Record*> &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 <aquynh@gmail.com>, 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 <aquynh@gmail.com>\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 <aquynh@gmail.com>\n" |
| -+ "\n"; |
| -+ CodeGenTarget Target(RK); |
| -+ std::map<std::string, std::string> 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 <aquynh@gmail.com>, 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<Record*> &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<const CodeGenRegister*> 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<std::string> 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 <aquynh@gmail.com>, 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 |
| deleted file mode 100644 |
| index a395c32a7..000000000 |
| --- a/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch |
| +++ /dev/null |
| @@ -1,905 +0,0 @@ |
| -From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001 |
| -From: fanfuqiang <feqin1023@gmail.com> |
| -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<Record *> 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<typename InsnType>\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<typename InsnType>\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<Record*> &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 |
| deleted file mode 100644 |
| index 720024662..000000000 |
| --- a/llvm/0003-clear-old-patchs.patch |
| +++ /dev/null |
| @@ -1,1602 +0,0 @@ |
| -From 02eecf3f85ad03f12babab3067f2c1bcfff35ed3 Mon Sep 17 00:00:00 2001 |
| -From: fanfuqiang <feqin1023@gmail.com> |
| -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 <mephi42@gmail.com> |
| --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 <aquynh@gmail.com>, 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<Record*> &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<const CodeGenRegister*> 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<std::string> 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 <mephi42@gmail.com> |
| --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 <aquynh@gmail.com>, 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 <mephi42@gmail.com> |
| --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<Record*> &Uses, |
| -- unsigned Num, raw_ostream &OS) { |
| -- OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; |
| --@@ -99,6 +100,7 @@ static void PrintDefList(const std::vector<Record*> &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 <aquynh@gmail.com>, 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 <mephi42@gmail.com> |
| --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 <aquynh@gmail.com>, 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<typename InsnType>\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<typename InsnType>\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<typename InsnType>\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 <assert.h>\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 <mephi42@gmail.com> |
| --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<std::string> 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<Record*> &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 <aquynh@gmail.com>, 2013-2015 */\n" |
| --+ "\n" |
| --+ "#include <stdio.h>\t// debug\n" |
| --+ "#include <capstone/platform.h>\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 <mephi42@gmail.com> |
| --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 <aquynh@gmail.com>\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 <mephi42@gmail.com> |
| --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 <aquynh@gmail.com>\n" |
| --+ "\n"; |
| --+ CodeGenTarget Target(RK); |
| --+ std::map<std::string, std::string> 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 |
| - |
| -- |
| 2.20.1 |
| |