capstone
224 строки · 7.3 Кб
1From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001
2From: mephi42 <mephi42@gmail.com>
3Date: Tue, 7 Aug 2018 20:00:08 +0200
4Subject: [PATCH 5/7] capstone: generate *GenAsmWriter.inc
5
6---
7utils/TableGen/AsmWriterEmitter.cpp | 89 +++++++++++++++++++++++++++--
8utils/TableGen/AsmWriterInst.cpp | 4 ++
92 files changed, 87 insertions(+), 6 deletions(-)
10
11diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
12index 3c4c9c8e5c6..133800d217c 100644
13--- a/utils/TableGen/AsmWriterEmitter.cpp
14+++ b/utils/TableGen/AsmWriterEmitter.cpp
15@@ -272,16 +272,22 @@ static void UnescapeString(std::string &Str) {
16/// clearing the Instructions vector.
17void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
18Record *AsmWriter = Target.getAsmWriter();
19+#ifndef CAPSTONE
20StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
21+#endif
22bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
23
24O <<
25"/// printInstruction - This method is automatically generated by tablegen\n"
26"/// from the instruction set description.\n"
27+#ifdef CAPSTONE
28+ "static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{\n";
29+#else
30"void " << Target.getName() << ClassName
31<< "::printInstruction(const MCInst *MI, "
32<< (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
33<< "raw_ostream &O) {\n";
34+#endif
35
36// Build an aggregate string, and build a table of offsets into it.
37SequenceToOffsetTable<std::string> StringTable;
38@@ -379,9 +385,16 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
39}
40
41// Emit the string table itself.
42+#ifdef CAPSTONE
43+ O << "#ifndef CAPSTONE_DIET\n";
44+#endif
45O << " static const char AsmStrs[] = {\n";
46StringTable.emit(O, printChar);
47- O << " };\n\n";
48+ O << " };\n"
49+#ifdef CAPSTONE
50+ << "#endif\n"
51+#endif
52+ << "\n";
53
54// Emit the lookup tables in pieces to minimize wasted bytes.
55unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8;
56@@ -409,21 +422,45 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
57// If the total bits is more than 32-bits we need to use a 64-bit type.
58if (BitsLeft < (OpcodeInfoBits - 32))
59BitsOS << "(uint64_t)";
60- BitsOS << "OpInfo" << Table << "[MI->getOpcode()] << " << Shift << ";\n";
61+ BitsOS << "OpInfo" << Table << "["
62+#ifdef CAPSTONE
63+ << "MCInst_getOpcode(MI)"
64+#else
65+ << "MI->getOpcode()"
66+#endif
67+ << "] << " << Shift << ";\n";
68// Prepare the shift for the next iteration and increment the table count.
69Shift += TableSize;
70++Table;
71}
72
73// Emit the initial tab character.
74+#ifndef CAPSTONE
75O << " O << \"\\t\";\n\n";
76+#endif
77
78O << " // Emit the opcode for the instruction.\n";
79O << BitsString;
80
81// Emit the starting string.
82- O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n"
83- << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
84+ O << " "
85+#ifdef CAPSTONE
86+ << "// "
87+#endif
88+ << "assert(Bits != 0 && \"Cannot print this instruction.\");\n"
89+#ifdef CAPSTONE
90+ << "#ifndef CAPSTONE_DIET\n"
91+ << " SStream_concat0(O, "
92+#else
93+ << " O << "
94+#endif
95+ << "AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1"
96+#ifdef CAPSTONE
97+ << ");\n"
98+ << "#endif\n\n";
99+#else
100+ << ");\n\n";
101+#endif
102
103// Output the table driven operand information.
104BitsLeft = OpcodeInfoBits-AsmStrBits;
105@@ -455,7 +492,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
106O << " switch ((Bits >> "
107<< (OpcodeInfoBits-BitsLeft) << ") & "
108<< ((1 << NumBits)-1) << ") {\n"
109- << " default: llvm_unreachable(\"Invalid command number.\");\n";
110+ << " default: "
111+#ifdef CAPSTONE
112+ << "// "
113+#endif
114+ << "llvm_unreachable(\"Invalid command number.\");\n";
115
116// Print out all the cases.
117for (unsigned j = 0, e = Commands.size(); j != e; ++j) {
118@@ -536,6 +577,9 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
119}
120
121StringTable.layout();
122+#ifdef CAPSTONE
123+ O << "#ifndef CAPSTONE_DIET\n";
124+#endif
125O << " static const char AsmStrs" << AltName << "[] = {\n";
126StringTable.emit(O, printChar);
127O << " };\n\n";
128@@ -552,8 +596,10 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
129}
130
131void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
132+#ifndef CAPSTONE
133Record *AsmWriter = Target.getAsmWriter();
134StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
135+#endif
136const auto &Registers = Target.getRegBank().getRegisters();
137const std::vector<Record*> &AltNameIndices = Target.getRegAltNameIndices();
138bool hasAltNames = AltNameIndices.size() > 1;
139@@ -563,12 +609,20 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
140"\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
141"/// from the register set description. This returns the assembler name\n"
142"/// for the specified register.\n"
143+#ifdef CAPSTONE
144+ "static const char *getRegisterName(unsigned RegNo)\n{\n";
145+#else
146"const char *" << Target.getName() << ClassName << "::";
147if (hasAltNames)
148O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n";
149else
150O << "getRegisterName(unsigned RegNo) {\n";
151- O << " assert(RegNo && RegNo < " << (Registers.size()+1)
152+#endif
153+ O << " "
154+#ifdef CAPSTONE
155+ << "// "
156+#endif
157+ << "assert(RegNo && RegNo < " << (Registers.size()+1)
158<< " && \"Invalid register number!\");\n"
159<< "\n";
160
161@@ -595,10 +649,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
162}
163O << " }\n";
164} else {
165+#ifdef CAPSTONE
166+ O << " //int i;\n"
167+ << " //for (i = 0; i < sizeof(RegAsmOffset); i++)\n"
168+ << " // printf(\"%s = %u\\n\", AsmStrs+RegAsmOffset[i], i + 1);\n"
169+ << " //printf(\"*************************\\n\");\n"
170+#else
171O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
172<< " \"Invalid alt name index for register!\");\n"
173+#endif
174<< " return AsmStrs+RegAsmOffset[RegNo-1];\n";
175}
176+#ifdef CAPSTONE
177+ O << "#else\n"
178+ << " return NULL;\n"
179+ << "#endif\n";
180+#endif
181O << "}\n";
182}
183
184@@ -1135,9 +1201,20 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
185}
186
187void AsmWriterEmitter::run(raw_ostream &O) {
188+#ifdef CAPSTONE
189+ O << "/* Capstone Disassembly Engine */\n"
190+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n"
191+ "\n"
192+ "#include <stdio.h>\t// debug\n"
193+ "#include <capstone/platform.h>\n"
194+ "\n"
195+ "\n";
196+#endif
197EmitPrintInstruction(O);
198EmitGetRegisterName(O);
199+#ifndef CAPSTONE
200EmitPrintAliasInstruction(O);
201+#endif
202}
203
204namespace llvm {
205diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp
206index 2c19e5d663d..6fa751e50df 100644
207--- a/utils/TableGen/AsmWriterInst.cpp
208+++ b/utils/TableGen/AsmWriterInst.cpp
209@@ -28,9 +28,13 @@ static bool isIdentChar(char C) {
210
211std::string AsmWriterOperand::getCode(bool PassSubtarget) const {
212if (OperandType == isLiteralTextOperand) {
213+#ifdef CAPSTONE
214+ return "SStream_concat0(O, \"" + Str + "\");";
215+#else
216if (Str.size() == 1)
217return "O << '" + Str + "';";
218return "O << \"" + Str + "\";";
219+#endif
220}
221
222if (OperandType == isLiteralStatementOperand)
223--
2242.19.1
225
226