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