mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-07-23 21:43:55 +00:00
5704 lines
205 KiB
Diff
5704 lines
205 KiB
Diff
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
|
|
|