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