brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 7851919 Raw
89 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This tablegen backend is responsible for emitting tables that group10// instructions by their mnemonic name wrt AsmWriter Variant (e.g. isADD, etc).11//12//===----------------------------------------------------------------------===//13 14#include "Common/CodeGenInstruction.h"15#include "Common/CodeGenTarget.h"16#include "X86RecognizableInstr.h"17#include "llvm/TableGen/Record.h"18#include "llvm/TableGen/TableGenBackend.h"19 20using namespace llvm;21 22namespace {23 24class X86MnemonicTablesEmitter {25  const CodeGenTarget Target;26 27public:28  X86MnemonicTablesEmitter(const RecordKeeper &R) : Target(R) {}29 30  // Output X86 mnemonic tables.31  void run(raw_ostream &OS);32};33} // namespace34 35void X86MnemonicTablesEmitter::run(raw_ostream &OS) {36  emitSourceFileHeader("X86 Mnemonic tables", OS);37  OS << "namespace llvm {\nnamespace X86 {\n\n";38  const Record *AsmWriter = Target.getAsmWriter();39  unsigned Variant = AsmWriter->getValueAsInt("Variant");40 41  // Hold all instructions grouped by mnemonic42  StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;43 44  for (const CodeGenInstruction *I : Target.getInstructions()) {45    const Record *Def = I->TheDef;46    // Filter non-X86 instructions.47    if (!Def->isSubClassOf("X86Inst"))48      continue;49    X86Disassembler::RecognizableInstrBase RI(*I);50    if (!RI.shouldBeEmitted())51      continue;52    if ( // Non-parsable instruction defs contain prefix as part of AsmString53        Def->getValueAsString("AsmVariantName") == "NonParsable" ||54        // Skip prefix byte55        RI.Form == X86Local::PrefixByte)56      continue;57    std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);58    MnemonicToCGInstrMap[Mnemonic].push_back(I);59  }60 61  OS << "#ifdef GET_X86_MNEMONIC_TABLES_H\n";62  OS << "#undef GET_X86_MNEMONIC_TABLES_H\n\n";63  for (StringRef Mnemonic : MnemonicToCGInstrMap.keys())64    OS << "bool is" << Mnemonic << "(unsigned Opcode);\n";65  OS << "#endif // GET_X86_MNEMONIC_TABLES_H\n\n";66 67  OS << "#ifdef GET_X86_MNEMONIC_TABLES_CPP\n";68  OS << "#undef GET_X86_MNEMONIC_TABLES_CPP\n\n";69  for (StringRef Mnemonic : MnemonicToCGInstrMap.keys()) {70    OS << "bool is" << Mnemonic << "(unsigned Opcode) {\n";71    auto Mnemonics = MnemonicToCGInstrMap[Mnemonic];72    if (Mnemonics.size() == 1) {73      const CodeGenInstruction *CGI = *Mnemonics.begin();74      OS << "\treturn Opcode == " << CGI->getName() << ";\n}\n\n";75    } else {76      OS << "\tswitch (Opcode) {\n";77      for (const CodeGenInstruction *CGI : Mnemonics) {78        OS << "\tcase " << CGI->getName() << ":\n";79      }80      OS << "\t\treturn true;\n\t}\n\treturn false;\n}\n\n";81    }82  }83  OS << "#endif // GET_X86_MNEMONIC_TABLES_CPP\n\n";84  OS << "} // end namespace X86\n} // end namespace llvm";85}86 87static TableGen::Emitter::OptClass<X86MnemonicTablesEmitter>88    X("gen-x86-mnemonic-tables", "Generate X86 mnemonic tables");89