1From 29da4c6929679b8ac4019767ab4ebcd83c9894b4 Mon Sep 17 00:00:00 2001 2From: mephi42 <[email protected]> 3Date: Tue, 7 Aug 2018 18:20:17 +0200 4Subject: [PATCH 4/7] capstone: generate *GenDisassemblerTables.inc 5 6--- 7 utils/TableGen/DisassemblerEmitter.cpp | 12 +- 8 utils/TableGen/FixedLenDecoderEmitter.cpp | 248 ++++++++++++++++++++-- 9 2 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, 16 void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { 17 CodeGenTarget Target(Records); 18 emitSourceFileHeader(" * " + Target.getName().str() + " Disassembler", OS); 19+#ifdef CAPSTONE 20+ OS << "/* Capstone Disassembly Engine */\n" 21+ "/* By Nguyen Anh Quynh <[email protected]>, 2013-2015 */\n" 22+ "\n"; 23+#endif 24 25 // X86 uses a custom disassembler. 26 if (Target.getName() == "X86") { 27@@ -150,7 +155,12 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { 28 } 29 30 EmitFixedLenDecoder(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; 47 unsigned Start = *I++; 48 unsigned 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{"; 58 if (Len > 1) 59 OS << (Start + Len - 1) << "-"; 60@@ -739,7 +745,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 61 } 62 case 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. 73 while (*I >= 128) 74 OS << (unsigned)*I++ << ", "; 75@@ -759,7 +771,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 76 ++I; 77 unsigned Start = *I++; 78 unsigned 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. 89 for (; *I >= 128; ++I) 90@@ -777,7 +795,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 91 } 92 case 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+ << ", "; 102 for (; *I >= 128; ++I) 103 OS << (unsigned)*I << ", "; 104 OS << (unsigned)*I++ << ", "; 105@@ -803,7 +827,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 106 && "ULEB128 value too large!"); 107 // Decode the Opcode value. 108 unsigned 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, "; 118 for (p = Buffer; *p >= 128; ++p) 119 OS << (unsigned)*p << ", "; 120@@ -837,7 +867,12 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 121 } 122 case 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 132 uint64_t Value = 0; 133 unsigned Shift = 0; 134@@ -869,7 +904,13 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 135 } 136 case 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"; 146 break; 147 } 148 } 149@@ -884,23 +925,46 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS, 150 void FixedLenDecoderEmitter:: 151 emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates, 152 unsigned 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. 162 OS.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 168 Indentation += 2; 169 if (!Predicates.empty()) { 170 OS.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"; 177 unsigned Index = 0; 178 for (const auto &Predicate : Predicates) { 179 OS.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 } 187 OS.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 } 197 Indentation -= 2; 198 OS.indent(Indentation) << "}\n\n"; 199@@ -911,23 +975,39 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders, 200 unsigned 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" 211 OS.indent(Indentation) << "template<typename InsnType>\n"; 212 OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S," 213 << " unsigned Idx, InsnType insn, MCInst &MI,\n"; 214 OS.indent(Indentation) << " uint64_t " 215 << "Address, const void *Decoder, bool &DecodeComplete) {\n"; 216+#endif 217 Indentation += 2; 218+#ifndef CAPSTONE 219 OS.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 232 unsigned Index = 0; 233 for (const auto &Decoder : Decoders) { 234- OS.indent(Indentation) << "case " << Index++ << ":\n"; 235+ OS.indent(Indentation) << "case " << Index++ << ":" EDF_EOL; 236 OS << 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; 242 Indentation -= 2; 243 OS.indent(Indentation) << "}\n\n"; 244 } 245@@ -1054,16 +1134,21 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 246 const std::string &Decoder = OpInfo.Decoder; 247 248 if (OpInfo.numFields() != 1) 249- o.indent(Indentation) << "tmp = 0;\n"; 250+ o.indent(Indentation) << "tmp = 0;" EDF_EOL; 251 252 for (const EncodingField &EF : OpInfo) { 253 o.indent(Indentation) << "tmp "; 254 if (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 << ')'; 263 if (OpInfo.numFields() != 1 || EF.Offset != 0) 264 o << " << " << EF.Offset; 265- o << ";\n"; 266+ o << ";" EDF_EOL; 267 } 268 269 if (Decoder != "") { 270@@ -1071,8 +1156,12 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, 271 o.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 { 281 OpHasCompleteDecoder = true; 282 o.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"; 295 break; 296 } 297 298@@ -1129,10 +1224,19 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders, 299 static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, 300 const std::string &PredicateNamespace) { 301 if (str[0] == '!') 302+#ifdef CAPSTONE 303+ o << "~(Bits & " << PredicateNamespace << "_" 304+ << str.slice(1,str.size()) << ")"; 305+#else 306 o << "!Bits[" << PredicateNamespace << "::" 307 << str.slice(1,str.size()) << "]"; 308+#endif 309 else 310+#ifdef CAPSTONE 311+ o << "(Bits & " << PredicateNamespace << "_" << str << ")"; 312+#else 313 o << "Bits[" << PredicateNamespace << "::" << str << "]"; 314+#endif 315 } 316 317 bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, 318@@ -2047,6 +2151,17 @@ static bool populateInstruction(CodeGenTarget &Target, 319 // fieldFromInstruction(). 320 static void emitFieldFromInstruction(formatted_raw_ostream &OS) { 321 OS << "// 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(). 346 static 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 426 OS << "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. 438 void FixedLenDecoderEmitter::run(raw_ostream &o) { 439 formatted_raw_ostream OS(o); 440+#ifdef CAPSTONE 441+ OS << "#include \"../../MCInst.h\"\n"; 442+ OS << "#include \"../../LEB128.h\"\n"; 443+ OS << "\n"; 444+#else 445 OS << "#include \"llvm/MC/MCInst.h\"\n"; 446 OS << "#include \"llvm/Support/Debug.h\"\n"; 447 OS << "#include \"llvm/Support/DataTypes.h\"\n"; 448@@ -2254,6 +2455,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { 449 OS << "#include <assert.h>\n"; 450 OS << '\n'; 451 OS << "namespace llvm {\n\n"; 452+#endif 453 454 emitFieldFromInstruction(OS); 455 456@@ -2322,7 +2524,13 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) { 457 // Emit the main entry point for the decoder, decodeInstruction(). 458 emitDecodeInstruction(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 465 OS << "\n} // End llvm namespace\n"; 466+#endif 467 } 468 469 namespace llvm { 470-- 4712.19.1 472 473