1*9a0e4156SSadaf EbrahimiFrom 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001
2*9a0e4156SSadaf EbrahimiFrom: mephi42 <[email protected]>
3*9a0e4156SSadaf EbrahimiDate: Tue, 7 Aug 2018 18:20:17 +0200
4*9a0e4156SSadaf EbrahimiSubject: [PATCH 4/7] capstone: generate *GenDisassemblerTables.inc
5*9a0e4156SSadaf Ebrahimi
6*9a0e4156SSadaf Ebrahimi---
7*9a0e4156SSadaf Ebrahimi utils/TableGen/DisassemblerEmitter.cpp    |  12 +-
8*9a0e4156SSadaf Ebrahimi utils/TableGen/FixedLenDecoderEmitter.cpp | 248 ++++++++++++++++++++--
9*9a0e4156SSadaf Ebrahimi 2 files changed, 239 insertions(+), 21 deletions(-)
10*9a0e4156SSadaf Ebrahimi
11*9a0e4156SSadaf Ebrahimidiff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp
12*9a0e4156SSadaf Ebrahimiindex b99a0a973a2..2ac6d89645c 100644
13*9a0e4156SSadaf Ebrahimi--- a/utils/TableGen/DisassemblerEmitter.cpp
14*9a0e4156SSadaf Ebrahimi+++ b/utils/TableGen/DisassemblerEmitter.cpp
15*9a0e4156SSadaf Ebrahimi@@ -106,6 +106,11 @@ extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS,
16*9a0e4156SSadaf Ebrahimi void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
17*9a0e4156SSadaf Ebrahimi   CodeGenTarget Target(Records);
18*9a0e4156SSadaf Ebrahimi   emitSourceFileHeader(" * " + Target.getName().str() + " Disassembler", OS);
19*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
20*9a0e4156SSadaf Ebrahimi+  OS << "/* Capstone Disassembly Engine */\n"
21*9a0e4156SSadaf Ebrahimi+        "/* By Nguyen Anh Quynh <[email protected]>, 2013-2015 */\n"
22*9a0e4156SSadaf Ebrahimi+        "\n";
23*9a0e4156SSadaf Ebrahimi+#endif
24*9a0e4156SSadaf Ebrahimi
25*9a0e4156SSadaf Ebrahimi   // X86 uses a custom disassembler.
26*9a0e4156SSadaf Ebrahimi   if (Target.getName() == "X86") {
27*9a0e4156SSadaf Ebrahimi@@ -150,7 +155,12 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
28*9a0e4156SSadaf Ebrahimi   }
29*9a0e4156SSadaf Ebrahimi
30*9a0e4156SSadaf Ebrahimi   EmitFixedLenDecoder(Records, OS, Target.getName(),
31*9a0e4156SSadaf Ebrahimi-                      "if (", " == MCDisassembler::Fail)",
32*9a0e4156SSadaf Ebrahimi+                      "if (",
33*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
34*9a0e4156SSadaf Ebrahimi+                      " == MCDisassembler_Fail)",
35*9a0e4156SSadaf Ebrahimi+#else
36*9a0e4156SSadaf Ebrahimi+                      " == MCDisassembler::Fail)",
37*9a0e4156SSadaf Ebrahimi+#endif
38*9a0e4156SSadaf Ebrahimi                       "MCDisassembler::Success", "MCDisassembler::Fail", "");
39*9a0e4156SSadaf Ebrahimi }
40*9a0e4156SSadaf Ebrahimi
41*9a0e4156SSadaf Ebrahimidiff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
42*9a0e4156SSadaf Ebrahimiindex fcecc764d44..36845d960d8 100644
43*9a0e4156SSadaf Ebrahimi--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
44*9a0e4156SSadaf Ebrahimi+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
45*9a0e4156SSadaf Ebrahimi@@ -730,7 +730,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
46*9a0e4156SSadaf Ebrahimi       ++I;
47*9a0e4156SSadaf Ebrahimi       unsigned Start = *I++;
48*9a0e4156SSadaf Ebrahimi       unsigned Len = *I++;
49*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", "
50*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
51*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
52*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_ExtractField"
53*9a0e4156SSadaf Ebrahimi+#else
54*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_ExtractField"
55*9a0e4156SSadaf Ebrahimi+#endif
56*9a0e4156SSadaf Ebrahimi+        << ", " << Start << ", "
57*9a0e4156SSadaf Ebrahimi         << Len << ",  // Inst{";
58*9a0e4156SSadaf Ebrahimi       if (Len > 1)
59*9a0e4156SSadaf Ebrahimi         OS << (Start + Len - 1) << "-";
60*9a0e4156SSadaf Ebrahimi@@ -739,7 +745,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
61*9a0e4156SSadaf Ebrahimi     }
62*9a0e4156SSadaf Ebrahimi     case MCD::OPC_FilterValue: {
63*9a0e4156SSadaf Ebrahimi       ++I;
64*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
65*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
66*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
67*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_FilterValue"
68*9a0e4156SSadaf Ebrahimi+#else
69*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_FilterValue"
70*9a0e4156SSadaf Ebrahimi+#endif
71*9a0e4156SSadaf Ebrahimi+        << ", ";
72*9a0e4156SSadaf Ebrahimi       // The filter value is ULEB128 encoded.
73*9a0e4156SSadaf Ebrahimi       while (*I >= 128)
74*9a0e4156SSadaf Ebrahimi         OS << (unsigned)*I++ << ", ";
75*9a0e4156SSadaf Ebrahimi@@ -759,7 +771,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
76*9a0e4156SSadaf Ebrahimi       ++I;
77*9a0e4156SSadaf Ebrahimi       unsigned Start = *I++;
78*9a0e4156SSadaf Ebrahimi       unsigned Len = *I++;
79*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", "
80*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
81*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
82*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_CheckField"
83*9a0e4156SSadaf Ebrahimi+#else
84*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_CheckField"
85*9a0e4156SSadaf Ebrahimi+#endif
86*9a0e4156SSadaf Ebrahimi+        << ", " << Start << ", "
87*9a0e4156SSadaf Ebrahimi         << Len << ", ";// << Val << ", " << NumToSkip << ",\n";
88*9a0e4156SSadaf Ebrahimi       // ULEB128 encoded field value.
89*9a0e4156SSadaf Ebrahimi       for (; *I >= 128; ++I)
90*9a0e4156SSadaf Ebrahimi@@ -777,7 +795,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
91*9a0e4156SSadaf Ebrahimi     }
92*9a0e4156SSadaf Ebrahimi     case MCD::OPC_CheckPredicate: {
93*9a0e4156SSadaf Ebrahimi       ++I;
94*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
95*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
96*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
97*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_CheckPredicate"
98*9a0e4156SSadaf Ebrahimi+#else
99*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_CheckPredicate"
100*9a0e4156SSadaf Ebrahimi+#endif
101*9a0e4156SSadaf Ebrahimi+        << ", ";
102*9a0e4156SSadaf Ebrahimi       for (; *I >= 128; ++I)
103*9a0e4156SSadaf Ebrahimi         OS << (unsigned)*I << ", ";
104*9a0e4156SSadaf Ebrahimi       OS << (unsigned)*I++ << ", ";
105*9a0e4156SSadaf Ebrahimi@@ -803,7 +827,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
106*9a0e4156SSadaf Ebrahimi                && "ULEB128 value too large!");
107*9a0e4156SSadaf Ebrahimi       // Decode the Opcode value.
108*9a0e4156SSadaf Ebrahimi       unsigned Opc = decodeULEB128(Buffer);
109*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_" << (IsTry ? "Try" : "")
110*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
111*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
112*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_"
113*9a0e4156SSadaf Ebrahimi+#else
114*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_"
115*9a0e4156SSadaf Ebrahimi+#endif
116*9a0e4156SSadaf Ebrahimi+        << (IsTry ? "Try" : "")
117*9a0e4156SSadaf Ebrahimi         << "Decode, ";
118*9a0e4156SSadaf Ebrahimi       for (p = Buffer; *p >= 128; ++p)
119*9a0e4156SSadaf Ebrahimi         OS << (unsigned)*p << ", ";
120*9a0e4156SSadaf Ebrahimi@@ -837,7 +867,12 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
121*9a0e4156SSadaf Ebrahimi     }
122*9a0e4156SSadaf Ebrahimi     case MCD::OPC_SoftFail: {
123*9a0e4156SSadaf Ebrahimi       ++I;
124*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_SoftFail";
125*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
126*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
127*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_SoftFail";
128*9a0e4156SSadaf Ebrahimi+#else
129*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_SoftFail";
130*9a0e4156SSadaf Ebrahimi+#endif
131*9a0e4156SSadaf Ebrahimi       // Positive mask
132*9a0e4156SSadaf Ebrahimi       uint64_t Value = 0;
133*9a0e4156SSadaf Ebrahimi       unsigned Shift = 0;
134*9a0e4156SSadaf Ebrahimi@@ -869,7 +904,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
135*9a0e4156SSadaf Ebrahimi     }
136*9a0e4156SSadaf Ebrahimi     case MCD::OPC_Fail: {
137*9a0e4156SSadaf Ebrahimi       ++I;
138*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation) << "MCD::OPC_Fail,\n";
139*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation)
140*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
141*9a0e4156SSadaf Ebrahimi+        << "MCD_OPC_Fail"
142*9a0e4156SSadaf Ebrahimi+#else
143*9a0e4156SSadaf Ebrahimi+        << "MCD::OPC_Fail"
144*9a0e4156SSadaf Ebrahimi+#endif
145*9a0e4156SSadaf Ebrahimi+        << ",\n";
146*9a0e4156SSadaf Ebrahimi       break;
147*9a0e4156SSadaf Ebrahimi     }
148*9a0e4156SSadaf Ebrahimi     }
149*9a0e4156SSadaf Ebrahimi@@ -884,23 +925,46 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
150*9a0e4156SSadaf Ebrahimi void FixedLenDecoderEmitter::
151*9a0e4156SSadaf Ebrahimi emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
152*9a0e4156SSadaf Ebrahimi                       unsigned Indentation) const {
153*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
154*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "static bool getbool(uint64_t b)\n";
155*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "{\n";
156*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "\treturn b != 0;\n";
157*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "}\n\n";
158*9a0e4156SSadaf Ebrahimi+#endif
159*9a0e4156SSadaf Ebrahimi+
160*9a0e4156SSadaf Ebrahimi   // The predicate function is just a big switch statement based on the
161*9a0e4156SSadaf Ebrahimi   // input predicate index.
162*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
163*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
164*9a0e4156SSadaf Ebrahimi+    << "uint64_t Bits)\n{\n";
165*9a0e4156SSadaf Ebrahimi+#else
166*9a0e4156SSadaf Ebrahimi     << "const FeatureBitset& Bits) {\n";
167*9a0e4156SSadaf Ebrahimi+#endif
168*9a0e4156SSadaf Ebrahimi   Indentation += 2;
169*9a0e4156SSadaf Ebrahimi   if (!Predicates.empty()) {
170*9a0e4156SSadaf Ebrahimi     OS.indent(Indentation) << "switch (Idx) {\n";
171*9a0e4156SSadaf Ebrahimi-    OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
172*9a0e4156SSadaf Ebrahimi+    OS.indent(Indentation) << "default: "
173*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
174*9a0e4156SSadaf Ebrahimi+      << "// "
175*9a0e4156SSadaf Ebrahimi+#endif
176*9a0e4156SSadaf Ebrahimi+      << "llvm_unreachable(\"Invalid index!\");\n";
177*9a0e4156SSadaf Ebrahimi     unsigned Index = 0;
178*9a0e4156SSadaf Ebrahimi     for (const auto &Predicate : Predicates) {
179*9a0e4156SSadaf Ebrahimi       OS.indent(Indentation) << "case " << Index++ << ":\n";
180*9a0e4156SSadaf Ebrahimi-      OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
181*9a0e4156SSadaf Ebrahimi+      OS.indent(Indentation+2) << "return "
182*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
183*9a0e4156SSadaf Ebrahimi+        << "getbool"
184*9a0e4156SSadaf Ebrahimi+#endif
185*9a0e4156SSadaf Ebrahimi+        << "(" << Predicate << ");\n";
186*9a0e4156SSadaf Ebrahimi     }
187*9a0e4156SSadaf Ebrahimi     OS.indent(Indentation) << "}\n";
188*9a0e4156SSadaf Ebrahimi   } else {
189*9a0e4156SSadaf Ebrahimi     // No case statement to emit
190*9a0e4156SSadaf Ebrahimi-    OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
191*9a0e4156SSadaf Ebrahimi+    OS.indent(Indentation)
192*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
193*9a0e4156SSadaf Ebrahimi+      << "// "
194*9a0e4156SSadaf Ebrahimi+#endif
195*9a0e4156SSadaf Ebrahimi+      << "llvm_unreachable(\"Invalid index!\");\n";
196*9a0e4156SSadaf Ebrahimi   }
197*9a0e4156SSadaf Ebrahimi   Indentation -= 2;
198*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "}\n\n";
199*9a0e4156SSadaf Ebrahimi@@ -911,23 +975,39 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
200*9a0e4156SSadaf Ebrahimi                     unsigned Indentation) const {
201*9a0e4156SSadaf Ebrahimi   // The decoder function is just a big switch statement based on the
202*9a0e4156SSadaf Ebrahimi   // input decoder index.
203*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
204*9a0e4156SSadaf Ebrahimi+#define EDF_EOL " \\\n"
205*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "#define DecodeToMCInst(fname,fieldname, InsnType) \\\n";
206*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n";
207*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "                uint64_t Address, const void *Decoder) \\\n";
208*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "{ \\\n";
209*9a0e4156SSadaf Ebrahimi+#else
210*9a0e4156SSadaf Ebrahimi+#define EDF_EOL "\n"
211*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "template<typename InsnType>\n";
212*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
213*9a0e4156SSadaf Ebrahimi     << " unsigned Idx, InsnType insn, MCInst &MI,\n";
214*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "                                   uint64_t "
215*9a0e4156SSadaf Ebrahimi     << "Address, const void *Decoder, bool &DecodeComplete) {\n";
216*9a0e4156SSadaf Ebrahimi+#endif
217*9a0e4156SSadaf Ebrahimi   Indentation += 2;
218*9a0e4156SSadaf Ebrahimi+#ifndef CAPSTONE
219*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "DecodeComplete = true;\n";
220*9a0e4156SSadaf Ebrahimi-  OS.indent(Indentation) << "InsnType tmp;\n";
221*9a0e4156SSadaf Ebrahimi-  OS.indent(Indentation) << "switch (Idx) {\n";
222*9a0e4156SSadaf Ebrahimi-  OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
223*9a0e4156SSadaf Ebrahimi+#endif
224*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "InsnType tmp;" EDF_EOL;
225*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "switch (Idx) {" EDF_EOL;
226*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "default:"
227*9a0e4156SSadaf Ebrahimi+#ifndef CAPSTONE
228*9a0e4156SSadaf Ebrahimi+    << " llvm_unreachable(\"Invalid index!\");\n";
229*9a0e4156SSadaf Ebrahimi+#else
230*9a0e4156SSadaf Ebrahimi+    << " \\\n";
231*9a0e4156SSadaf Ebrahimi+#endif
232*9a0e4156SSadaf Ebrahimi   unsigned Index = 0;
233*9a0e4156SSadaf Ebrahimi   for (const auto &Decoder : Decoders) {
234*9a0e4156SSadaf Ebrahimi-    OS.indent(Indentation) << "case " << Index++ << ":\n";
235*9a0e4156SSadaf Ebrahimi+    OS.indent(Indentation) << "case " << Index++ << ":" EDF_EOL;
236*9a0e4156SSadaf Ebrahimi     OS << Decoder;
237*9a0e4156SSadaf Ebrahimi-    OS.indent(Indentation+2) << "return S;\n";
238*9a0e4156SSadaf Ebrahimi+    OS.indent(Indentation+2) << "return S;" EDF_EOL;
239*9a0e4156SSadaf Ebrahimi   }
240*9a0e4156SSadaf Ebrahimi-  OS.indent(Indentation) << "}\n";
241*9a0e4156SSadaf Ebrahimi+  OS.indent(Indentation) << "}" EDF_EOL;
242*9a0e4156SSadaf Ebrahimi   Indentation -= 2;
243*9a0e4156SSadaf Ebrahimi   OS.indent(Indentation) << "}\n\n";
244*9a0e4156SSadaf Ebrahimi }
245*9a0e4156SSadaf Ebrahimi@@ -1054,16 +1134,21 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
246*9a0e4156SSadaf Ebrahimi   const std::string &Decoder = OpInfo.Decoder;
247*9a0e4156SSadaf Ebrahimi
248*9a0e4156SSadaf Ebrahimi   if (OpInfo.numFields() != 1)
249*9a0e4156SSadaf Ebrahimi-    o.indent(Indentation) << "tmp = 0;\n";
250*9a0e4156SSadaf Ebrahimi+    o.indent(Indentation) << "tmp = 0;" EDF_EOL;
251*9a0e4156SSadaf Ebrahimi
252*9a0e4156SSadaf Ebrahimi   for (const EncodingField &EF : OpInfo) {
253*9a0e4156SSadaf Ebrahimi     o.indent(Indentation) << "tmp ";
254*9a0e4156SSadaf Ebrahimi     if (OpInfo.numFields() != 1) o << '|';
255*9a0e4156SSadaf Ebrahimi-    o << "= fieldFromInstruction"
256*9a0e4156SSadaf Ebrahimi+    o << "= "
257*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
258*9a0e4156SSadaf Ebrahimi+      << "fieldname"
259*9a0e4156SSadaf Ebrahimi+#else
260*9a0e4156SSadaf Ebrahimi+      << "fieldFromInstruction"
261*9a0e4156SSadaf Ebrahimi+#endif
262*9a0e4156SSadaf Ebrahimi       << "(insn, " << EF.Base << ", " << EF.Width << ')';
263*9a0e4156SSadaf Ebrahimi     if (OpInfo.numFields() != 1 || EF.Offset != 0)
264*9a0e4156SSadaf Ebrahimi       o << " << " << EF.Offset;
265*9a0e4156SSadaf Ebrahimi-    o << ";\n";
266*9a0e4156SSadaf Ebrahimi+    o << ";" EDF_EOL;
267*9a0e4156SSadaf Ebrahimi   }
268*9a0e4156SSadaf Ebrahimi
269*9a0e4156SSadaf Ebrahimi   if (Decoder != "") {
270*9a0e4156SSadaf Ebrahimi@@ -1071,8 +1156,12 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
271*9a0e4156SSadaf Ebrahimi     o.indent(Indentation) << Emitter->GuardPrefix << Decoder
272*9a0e4156SSadaf Ebrahimi       << "(MI, tmp, Address, Decoder)"
273*9a0e4156SSadaf Ebrahimi       << Emitter->GuardPostfix
274*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
275*9a0e4156SSadaf Ebrahimi+      << " return MCDisassembler_Fail; \\\n";
276*9a0e4156SSadaf Ebrahimi+#else
277*9a0e4156SSadaf Ebrahimi       << " { " << (OpHasCompleteDecoder ? "" : "DecodeComplete = false; ")
278*9a0e4156SSadaf Ebrahimi       << "return MCDisassembler::Fail; }\n";
279*9a0e4156SSadaf Ebrahimi+#endif
280*9a0e4156SSadaf Ebrahimi   } else {
281*9a0e4156SSadaf Ebrahimi     OpHasCompleteDecoder = true;
282*9a0e4156SSadaf Ebrahimi     o.indent(Indentation) << "MI.addOperand(MCOperand::createImm(tmp));\n";
283*9a0e4156SSadaf Ebrahimi@@ -1091,7 +1180,13 @@ void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
284*9a0e4156SSadaf Ebrahimi         << "(MI, insn, Address, Decoder)"
285*9a0e4156SSadaf Ebrahimi         << Emitter->GuardPostfix
286*9a0e4156SSadaf Ebrahimi         << " { " << (HasCompleteDecoder ? "" : "DecodeComplete = false; ")
287*9a0e4156SSadaf Ebrahimi-        << "return MCDisassembler::Fail; }\n";
288*9a0e4156SSadaf Ebrahimi+        << "return "
289*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
290*9a0e4156SSadaf Ebrahimi+        << "MCDisassembler_Fail"
291*9a0e4156SSadaf Ebrahimi+#else
292*9a0e4156SSadaf Ebrahimi+        << "MCDisassembler::Fail"
293*9a0e4156SSadaf Ebrahimi+#endif
294*9a0e4156SSadaf Ebrahimi+        << "; }\n";
295*9a0e4156SSadaf Ebrahimi       break;
296*9a0e4156SSadaf Ebrahimi     }
297*9a0e4156SSadaf Ebrahimi
298*9a0e4156SSadaf Ebrahimi@@ -1129,10 +1224,19 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
299*9a0e4156SSadaf Ebrahimi static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
300*9a0e4156SSadaf Ebrahimi                                      const std::string &PredicateNamespace) {
301*9a0e4156SSadaf Ebrahimi   if (str[0] == '!')
302*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
303*9a0e4156SSadaf Ebrahimi+    o << "~(Bits & " << PredicateNamespace << "_"
304*9a0e4156SSadaf Ebrahimi+      << str.slice(1,str.size()) << ")";
305*9a0e4156SSadaf Ebrahimi+#else
306*9a0e4156SSadaf Ebrahimi     o << "!Bits[" << PredicateNamespace << "::"
307*9a0e4156SSadaf Ebrahimi       << str.slice(1,str.size()) << "]";
308*9a0e4156SSadaf Ebrahimi+#endif
309*9a0e4156SSadaf Ebrahimi   else
310*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
311*9a0e4156SSadaf Ebrahimi+    o << "(Bits & " << PredicateNamespace << "_" << str << ")";
312*9a0e4156SSadaf Ebrahimi+#else
313*9a0e4156SSadaf Ebrahimi     o << "Bits[" << PredicateNamespace << "::" << str << "]";
314*9a0e4156SSadaf Ebrahimi+#endif
315*9a0e4156SSadaf Ebrahimi }
316*9a0e4156SSadaf Ebrahimi
317*9a0e4156SSadaf Ebrahimi bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
318*9a0e4156SSadaf Ebrahimi@@ -2047,6 +2151,17 @@ static bool populateInstruction(CodeGenTarget &Target,
319*9a0e4156SSadaf Ebrahimi // fieldFromInstruction().
320*9a0e4156SSadaf Ebrahimi static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
321*9a0e4156SSadaf Ebrahimi   OS << "// Helper function for extracting fields from encoded instructions.\n"
322*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
323*9a0e4156SSadaf Ebrahimi+     << "#define FieldFromInstruction(fname, InsnType) \\\n"
324*9a0e4156SSadaf Ebrahimi+     << "static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \\\n"
325*9a0e4156SSadaf Ebrahimi+     << "{ \\\n"
326*9a0e4156SSadaf Ebrahimi+     << "  InsnType fieldMask; \\\n"
327*9a0e4156SSadaf Ebrahimi+     << "  if (numBits == sizeof(InsnType)*8) \\\n"
328*9a0e4156SSadaf Ebrahimi+     << "    fieldMask = (InsnType)(-1LL); \\\n"
329*9a0e4156SSadaf Ebrahimi+     << "  else \\\n"
330*9a0e4156SSadaf Ebrahimi+     << "    fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \\\n"
331*9a0e4156SSadaf Ebrahimi+     << "  return (insn & fieldMask) >> startBit; \\\n"
332*9a0e4156SSadaf Ebrahimi+#else
333*9a0e4156SSadaf Ebrahimi      << "template<typename InsnType>\n"
334*9a0e4156SSadaf Ebrahimi    << "static InsnType fieldFromInstruction(InsnType insn, unsigned startBit,\n"
335*9a0e4156SSadaf Ebrahimi      << "                                     unsigned numBits) {\n"
336*9a0e4156SSadaf Ebrahimi@@ -2058,12 +2173,92 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
337*9a0e4156SSadaf Ebrahimi      << "    else\n"
338*9a0e4156SSadaf Ebrahimi      << "      fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n"
339*9a0e4156SSadaf Ebrahimi      << "    return (insn & fieldMask) >> startBit;\n"
340*9a0e4156SSadaf Ebrahimi+#endif
341*9a0e4156SSadaf Ebrahimi      << "}\n\n";
342*9a0e4156SSadaf Ebrahimi }
343*9a0e4156SSadaf Ebrahimi
344*9a0e4156SSadaf Ebrahimi // emitDecodeInstruction - Emit the templated helper function
345*9a0e4156SSadaf Ebrahimi // decodeInstruction().
346*9a0e4156SSadaf Ebrahimi static void emitDecodeInstruction(formatted_raw_ostream &OS) {
347*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
348*9a0e4156SSadaf Ebrahimi+  OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n"
349*9a0e4156SSadaf Ebrahimi+     << "static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \\\n"
350*9a0e4156SSadaf Ebrahimi+     << "           InsnType insn, uint64_t Address, const MCRegisterInfo *MRI, int feature) \\\n"
351*9a0e4156SSadaf Ebrahimi+     << "{ \\\n"
352*9a0e4156SSadaf Ebrahimi+     << "  uint64_t Bits = getFeatureBits(feature); \\\n"
353*9a0e4156SSadaf Ebrahimi+     << "  const uint8_t *Ptr = DecodeTable; \\\n"
354*9a0e4156SSadaf Ebrahimi+     << "  uint32_t CurFieldValue = 0, ExpectedValue; \\\n"
355*9a0e4156SSadaf Ebrahimi+     << "  DecodeStatus S = MCDisassembler_Success; \\\n"
356*9a0e4156SSadaf Ebrahimi+     << "  unsigned Start, Len, NumToSkip, PIdx, Opc, DecodeIdx; \\\n"
357*9a0e4156SSadaf Ebrahimi+     << "  InsnType Val, FieldValue, PositiveMask, NegativeMask; \\\n"
358*9a0e4156SSadaf Ebrahimi+     << "  bool Pred, Fail; \\\n"
359*9a0e4156SSadaf Ebrahimi+     << "  for (;;) { \\\n"
360*9a0e4156SSadaf Ebrahimi+     << "    switch (*Ptr) { \\\n"
361*9a0e4156SSadaf Ebrahimi+     << "    default: \\\n"
362*9a0e4156SSadaf Ebrahimi+     << "      return MCDisassembler_Fail; \\\n"
363*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_ExtractField: { \\\n"
364*9a0e4156SSadaf Ebrahimi+     << "      Start = *++Ptr; \\\n"
365*9a0e4156SSadaf Ebrahimi+     << "      Len = *++Ptr; \\\n"
366*9a0e4156SSadaf Ebrahimi+     << "      ++Ptr; \\\n"
367*9a0e4156SSadaf Ebrahimi+     << "      CurFieldValue = (uint32_t)fieldname(insn, Start, Len); \\\n"
368*9a0e4156SSadaf Ebrahimi+     << "      break; \\\n"
369*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
370*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_FilterValue: { \\\n"
371*9a0e4156SSadaf Ebrahimi+     << "      Val = (InsnType)decodeULEB128(++Ptr, &Len); \\\n"
372*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
373*9a0e4156SSadaf Ebrahimi+     << "      NumToSkip = *Ptr++; \\\n"
374*9a0e4156SSadaf Ebrahimi+     << "      NumToSkip |= (*Ptr++) << 8; \\\n"
375*9a0e4156SSadaf Ebrahimi+     << "      if (Val != CurFieldValue) \\\n"
376*9a0e4156SSadaf Ebrahimi+     << "        Ptr += NumToSkip; \\\n"
377*9a0e4156SSadaf Ebrahimi+     << "      break; \\\n"
378*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
379*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_CheckField: { \\\n"
380*9a0e4156SSadaf Ebrahimi+     << "      Start = *++Ptr; \\\n"
381*9a0e4156SSadaf Ebrahimi+     << "      Len = *++Ptr; \\\n"
382*9a0e4156SSadaf Ebrahimi+     << "      FieldValue = fieldname(insn, Start, Len); \\\n"
383*9a0e4156SSadaf Ebrahimi+     << "      ExpectedValue = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n"
384*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
385*9a0e4156SSadaf Ebrahimi+     << "      NumToSkip = *Ptr++; \\\n"
386*9a0e4156SSadaf Ebrahimi+     << "      NumToSkip |= (*Ptr++) << 8; \\\n"
387*9a0e4156SSadaf Ebrahimi+     << "      if (ExpectedValue != FieldValue) \\\n"
388*9a0e4156SSadaf Ebrahimi+     << "        Ptr += NumToSkip; \\\n"
389*9a0e4156SSadaf Ebrahimi+     << "      break; \\\n"
390*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
391*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_CheckPredicate: { \\\n"
392*9a0e4156SSadaf Ebrahimi+     << "      PIdx = (uint32_t)decodeULEB128(++Ptr, &Len); \\\n"
393*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
394*9a0e4156SSadaf Ebrahimi+     << "      NumToSkip = *Ptr++; \\\n"
395*9a0e4156SSadaf Ebrahimi+     << "      NumToSkip |= (*Ptr++) << 8; \\\n"
396*9a0e4156SSadaf Ebrahimi+     << "      Pred = checkDecoderPredicate(PIdx, Bits); \\\n"
397*9a0e4156SSadaf Ebrahimi+     << "      if (!Pred) \\\n"
398*9a0e4156SSadaf Ebrahimi+     << "        Ptr += NumToSkip; \\\n"
399*9a0e4156SSadaf Ebrahimi+     << "      (void)Pred; \\\n"
400*9a0e4156SSadaf Ebrahimi+     << "      break; \\\n"
401*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
402*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_Decode: { \\\n"
403*9a0e4156SSadaf Ebrahimi+     << "      Opc = (unsigned)decodeULEB128(++Ptr, &Len); \\\n"
404*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
405*9a0e4156SSadaf Ebrahimi+     << "      DecodeIdx = (unsigned)decodeULEB128(Ptr, &Len); \\\n"
406*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
407*9a0e4156SSadaf Ebrahimi+     << "      MCInst_setOpcode(MI, Opc); \\\n"
408*9a0e4156SSadaf Ebrahimi+     << "      return decoder(S, DecodeIdx, insn, MI, Address, MRI); \\\n"
409*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
410*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_SoftFail: { \\\n"
411*9a0e4156SSadaf Ebrahimi+     << "      PositiveMask = (InsnType)decodeULEB128(++Ptr, &Len); \\\n"
412*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
413*9a0e4156SSadaf Ebrahimi+     << "      NegativeMask = (InsnType)decodeULEB128(Ptr, &Len); \\\n"
414*9a0e4156SSadaf Ebrahimi+     << "      Ptr += Len; \\\n"
415*9a0e4156SSadaf Ebrahimi+     << "      Fail = (insn & PositiveMask) || (~insn & NegativeMask); \\\n"
416*9a0e4156SSadaf Ebrahimi+     << "      if (Fail) \\\n"
417*9a0e4156SSadaf Ebrahimi+     << "        S = MCDisassembler_SoftFail; \\\n"
418*9a0e4156SSadaf Ebrahimi+     << "      break; \\\n"
419*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
420*9a0e4156SSadaf Ebrahimi+     << "    case MCD_OPC_Fail: { \\\n"
421*9a0e4156SSadaf Ebrahimi+     << "      return MCDisassembler_Fail; \\\n"
422*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
423*9a0e4156SSadaf Ebrahimi+     << "    } \\\n"
424*9a0e4156SSadaf Ebrahimi+     << "  } \\\n"
425*9a0e4156SSadaf Ebrahimi+#else
426*9a0e4156SSadaf Ebrahimi   OS << "template<typename InsnType>\n"
427*9a0e4156SSadaf Ebrahimi      << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
428*9a0e4156SSadaf Ebrahimi         "MCInst &MI,\n"
429*9a0e4156SSadaf Ebrahimi@@ -2240,12 +2435,18 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
430*9a0e4156SSadaf Ebrahimi      << "  }\n"
431*9a0e4156SSadaf Ebrahimi      << "  llvm_unreachable(\"bogosity detected in disassembler state "
432*9a0e4156SSadaf Ebrahimi         "machine!\");\n"
433*9a0e4156SSadaf Ebrahimi+#endif
434*9a0e4156SSadaf Ebrahimi      << "}\n\n";
435*9a0e4156SSadaf Ebrahimi }
436*9a0e4156SSadaf Ebrahimi
437*9a0e4156SSadaf Ebrahimi // Emits disassembler code for instruction decoding.
438*9a0e4156SSadaf Ebrahimi void FixedLenDecoderEmitter::run(raw_ostream &o) {
439*9a0e4156SSadaf Ebrahimi   formatted_raw_ostream OS(o);
440*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
441*9a0e4156SSadaf Ebrahimi+  OS << "#include \"../../MCInst.h\"\n";
442*9a0e4156SSadaf Ebrahimi+  OS << "#include \"../../LEB128.h\"\n";
443*9a0e4156SSadaf Ebrahimi+  OS << "\n";
444*9a0e4156SSadaf Ebrahimi+#else
445*9a0e4156SSadaf Ebrahimi   OS << "#include \"llvm/MC/MCInst.h\"\n";
446*9a0e4156SSadaf Ebrahimi   OS << "#include \"llvm/Support/Debug.h\"\n";
447*9a0e4156SSadaf Ebrahimi   OS << "#include \"llvm/Support/DataTypes.h\"\n";
448*9a0e4156SSadaf Ebrahimi@@ -2254,6 +2455,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
449*9a0e4156SSadaf Ebrahimi   OS << "#include <assert.h>\n";
450*9a0e4156SSadaf Ebrahimi   OS << '\n';
451*9a0e4156SSadaf Ebrahimi   OS << "namespace llvm {\n\n";
452*9a0e4156SSadaf Ebrahimi+#endif
453*9a0e4156SSadaf Ebrahimi
454*9a0e4156SSadaf Ebrahimi   emitFieldFromInstruction(OS);
455*9a0e4156SSadaf Ebrahimi
456*9a0e4156SSadaf Ebrahimi@@ -2322,7 +2524,13 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
457*9a0e4156SSadaf Ebrahimi   // Emit the main entry point for the decoder, decodeInstruction().
458*9a0e4156SSadaf Ebrahimi   emitDecodeInstruction(OS);
459*9a0e4156SSadaf Ebrahimi
460*9a0e4156SSadaf Ebrahimi+#ifdef CAPSTONE
461*9a0e4156SSadaf Ebrahimi+  OS << "FieldFromInstruction(fieldFromInstruction, uint64_t)\n";
462*9a0e4156SSadaf Ebrahimi+  OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint64_t)\n";
463*9a0e4156SSadaf Ebrahimi+  OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint64_t)\n";
464*9a0e4156SSadaf Ebrahimi+#else
465*9a0e4156SSadaf Ebrahimi   OS << "\n} // End llvm namespace\n";
466*9a0e4156SSadaf Ebrahimi+#endif
467*9a0e4156SSadaf Ebrahimi }
468*9a0e4156SSadaf Ebrahimi
469*9a0e4156SSadaf Ebrahimi namespace llvm {
470*9a0e4156SSadaf Ebrahimi--
471*9a0e4156SSadaf Ebrahimi2.19.1
472*9a0e4156SSadaf Ebrahimi
473