X86MnemonicTables.cpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //==- X86MnemonicTables.cpp - Generate mnemonic extraction tables. -*- C++ -*-//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This tablegen backend is responsible for emitting tables that group
  10. // instructions by their mnemonic name wrt AsmWriter Variant (e.g. isADD, etc).
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "CodeGenInstruction.h"
  14. #include "CodeGenTarget.h"
  15. #include "X86RecognizableInstr.h"
  16. #include "llvm/TableGen/Error.h"
  17. #include "llvm/TableGen/TableGenBackend.h"
  18. using namespace llvm;
  19. namespace {
  20. class X86MnemonicTablesEmitter {
  21. CodeGenTarget Target;
  22. public:
  23. X86MnemonicTablesEmitter(RecordKeeper &R) : Target(R) {}
  24. // Output X86 mnemonic tables.
  25. void run(raw_ostream &OS);
  26. };
  27. void X86MnemonicTablesEmitter::run(raw_ostream &OS) {
  28. emitSourceFileHeader("X86 Mnemonic tables", OS);
  29. OS << "namespace llvm {\nnamespace X86 {\n\n";
  30. Record *AsmWriter = Target.getAsmWriter();
  31. unsigned Variant = AsmWriter->getValueAsInt("Variant");
  32. // Hold all instructions grouped by mnemonic
  33. StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;
  34. ArrayRef<const CodeGenInstruction *> NumberedInstructions =
  35. Target.getInstructionsByEnumValue();
  36. for (const CodeGenInstruction *I : NumberedInstructions) {
  37. const Record *Def = I->TheDef;
  38. // Filter non-X86 instructions.
  39. if (!Def->isSubClassOf("X86Inst"))
  40. continue;
  41. X86Disassembler::RecognizableInstrBase RI(*I);
  42. if (!RI.shouldBeEmitted())
  43. continue;
  44. if ( // Non-parsable instruction defs contain prefix as part of AsmString
  45. Def->getValueAsString("AsmVariantName") == "NonParsable" ||
  46. // Skip prefix byte
  47. RI.Form == X86Local::PrefixByte)
  48. continue;
  49. std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);
  50. MnemonicToCGInstrMap[Mnemonic].push_back(I);
  51. }
  52. OS << "#ifdef GET_X86_MNEMONIC_TABLES_H\n";
  53. OS << "#undef GET_X86_MNEMONIC_TABLES_H\n\n";
  54. for (StringRef Mnemonic : MnemonicToCGInstrMap.keys())
  55. OS << "bool is" << Mnemonic << "(unsigned Opcode);\n";
  56. OS << "#endif // GET_X86_MNEMONIC_TABLES_H\n\n";
  57. OS << "#ifdef GET_X86_MNEMONIC_TABLES_CPP\n";
  58. OS << "#undef GET_X86_MNEMONIC_TABLES_CPP\n\n";
  59. for (StringRef Mnemonic : MnemonicToCGInstrMap.keys()) {
  60. OS << "bool is" << Mnemonic << "(unsigned Opcode) {\n";
  61. auto Mnemonics = MnemonicToCGInstrMap[Mnemonic];
  62. if (Mnemonics.size() == 1) {
  63. const CodeGenInstruction *CGI = *Mnemonics.begin();
  64. OS << "\treturn Opcode == " << CGI->TheDef->getName() << ";\n}\n\n";
  65. } else {
  66. OS << "\tswitch (Opcode) {\n";
  67. for (const CodeGenInstruction *CGI : Mnemonics) {
  68. OS << "\tcase " << CGI->TheDef->getName() << ":\n";
  69. }
  70. OS << "\t\treturn true;\n\t}\n\treturn false;\n}\n\n";
  71. }
  72. }
  73. OS << "#endif // GET_X86_MNEMONIC_TABLES_CPP\n\n";
  74. OS << "} // end namespace X86\n} // end namespace llvm";
  75. }
  76. } // namespace
  77. namespace llvm {
  78. void EmitX86MnemonicTables(RecordKeeper &RK, raw_ostream &OS) {
  79. X86MnemonicTablesEmitter(RK).run(OS);
  80. }
  81. } // namespace llvm