00cc9309cb
de6e324bdseparate emu thread10d3daf86Roms List improvements95d202f37Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.fc306967fWow the ROM Header was just completely busted. Game list view works nowbad1691eefuck this shit2b59e5f46game list in progressd26417b83remappable inputs in progressac4af8106inpute72abc240update readme430139dc9Qt6 frontend3080d4d45Fix this small bug too08cd13b85Cop0 unused functions do not actually pose a threat (as per manual). They don't do anything, so shall we.61bb4fb44make idle loop detection a little more specific with where the load goesb037de4c3SAZDFsdff12e81e73eneed to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)204f0e13bidle skipping seems to work!cb8bb634asdkfjlasdf58e5c89c1Fix compilation issue on my machine (no idea)24fb2898eattempting more serious idle skipping214719577Place rsp.Step inside cached interpreter. Gains about 3 more fpsbb97dcc23mmmmm920b77d38wjkhasdfjhkasdf430ccdab4it's a start...4f42a673aCached interpreter plays Mario 64. Start looking into RSP as wellc9a030787idle skipping works!5fbda03cenew idea366637abaIdle skipping... maybe?609fa2fb0Cache instructions implemented but broken lmao. Commented out for nowe140a6d12- Stop using inheritance for CPU, instead use composition. - Introduce KAIZEN_JIT_ENABLED optional define instead of relying on __aarch64__ and the like. - More cache work68e613057prep cache impl811b4d809fix clang formatfda755f7didkd5024ebbfsmall MI refactor in preparation of (eventually) implementing the RDRAM interface properly694b45341Merge commit '206dcdedf195fb320913584180edb12c7731e396' as 'external/SDL'206dcdedfSquashed 'external/SDL/' content from commit 4d17b99d0a4d16e1cb4need to update sdl848b19920Fix compilation errordb61b5299Merge commit 'e94a94559f28e49678fbcf72199a5258137b0fe9' as 'external/imgui'e94a94559Squashed 'external/imgui/' content from commit 02e9b8cac52edb3757need to update imguic1a705e86Emulate weird JALR behaviour4b4c32f4bFix exception for "unusable COP1" in 4 instructions i missed accidentally (again)df5828142Bug putting 0s in the log everywheref8b580048Make isviewer a sink to file8241e9735Fix exception for "unusable COP1" in 4 instructions i missed accidentallyb29715f20small changesd9a620bc1make use of my new small utility library0d1aa938eAdd 'external/ircolib/' from commit 'ce3cd726c8df8388d554abf8bb55d55020eb4450'e64eb40b3Fuck git git-subtree-dir: external/ircolib git-subtree-split:de6e324bde
5744 lines
207 KiB
Diff
5744 lines
207 KiB
Diff
From 66794c07a825d5149f72b5072d2de8ba95d5b284 Mon Sep 17 00:00:00 2001
|
|
From: fanfuqiang <feqin1023@gmail.com>
|
|
Date: Thu, 28 Feb 2019 21:17:27 +0800
|
|
Subject: [PATCH] fix riscv registerclass array of genregisterinfo
|
|
|
|
---
|
|
llvm/0001-capstone-riscv-patchs.patch | 3161 +++++++++++++++++
|
|
...for-generate-RISCV-port-inc-for-CAPS.patch | 905 +++++
|
|
llvm/0003-clear-old-patchs.patch | 1602 +++++++++
|
|
.../utils/TableGen/FixedLenDecoderEmitter.cpp | 1 -
|
|
llvm/utils/TableGen/RegisterInfoEmitter.cpp | 8 +-
|
|
5 files changed, 5672 insertions(+), 5 deletions(-)
|
|
create mode 100644 llvm/0001-capstone-riscv-patchs.patch
|
|
create mode 100644 llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch
|
|
create mode 100644 llvm/0003-clear-old-patchs.patch
|
|
|
|
diff --git a/llvm/0001-capstone-riscv-patchs.patch b/llvm/0001-capstone-riscv-patchs.patch
|
|
new file mode 100644
|
|
index 000000000..eb3246814
|
|
--- /dev/null
|
|
+++ b/llvm/0001-capstone-riscv-patchs.patch
|
|
@@ -0,0 +1,3161 @@
|
|
+From 3373228170bbc2324d223bdeca761de3b4565508 Mon Sep 17 00:00:00 2001
|
|
+From: fanfuqiang <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
|
|
new file mode 100644
|
|
index 000000000..a395c32a7
|
|
--- /dev/null
|
|
+++ b/llvm/0002-update-TableGen-for-generate-RISCV-port-inc-for-CAPS.patch
|
|
@@ -0,0 +1,905 @@
|
|
+From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001
|
|
+From: fanfuqiang <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
|
|
new file mode 100644
|
|
index 000000000..720024662
|
|
--- /dev/null
|
|
+++ b/llvm/0003-clear-old-patchs.patch
|
|
@@ -0,0 +1,1602 @@
|
|
+From 02eecf3f85ad03f12babab3067f2c1bcfff35ed3 Mon Sep 17 00:00:00 2001
|
|
+From: fanfuqiang <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
|
|
+
|
|
diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
|
|
index e1bfaa934..bf352f717 100644
|
|
--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
|
|
+++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
|
|
@@ -2357,7 +2357,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
|
|
<< " uint32_t CurFieldValue = 0;\\\n"
|
|
<< " DecodeStatus S = MCDisassembler_Success;\\\n"
|
|
<< " while (true) {\\\n"
|
|
- << " ptrdiff_t Loc = Ptr - DecodeTable;\\\n"
|
|
<< " switch (*Ptr) {\\\n"
|
|
<< " default:\\\n"
|
|
<< " return MCDisassembler_Fail;\\\n"
|
|
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
|
|
index cf9c352d7..6064a20cd 100644
|
|
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
|
|
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
|
|
@@ -1175,17 +1175,17 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|
for (const auto &RC : RegisterClasses) {
|
|
assert(isInt<8>(RC.CopyCost) && "Copy cost too large.");
|
|
OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
|
|
- << RegClassStrings.get(RC.getName()) << ", "
|
|
- << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
|
|
#ifdef CAPSTONE
|
|
- << NAME_PREFIX RC.getName()
|
|
+ << "sizeof(" << RC.getName() << "Bits) },\n";
|
|
#else
|
|
+ << RegClassStrings.get(RC.getName()) << ", "
|
|
+ << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
|
|
<< RC.getQualifiedName()
|
|
-#endif
|
|
<< "RegClassID" << ", "
|
|
//<< RegSize/8 << ", "
|
|
<< RC.CopyCost << ", "
|
|
<< ( RC.Allocatable ? "true" : "false" ) << " },\n";
|
|
+#endif
|
|
}
|
|
|
|
OS << "};\n\n";
|
|
--
|
|
2.20.1
|
|
|