Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.h
35258 views
//===- X86DisassemblerTables.h - Disassembler tables ------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is part of the X86 Disassembler Emitter.9// It contains the interface of the disassembler tables.10// Documentation for the disassembler emitter in general can be found in11// X86DisassemblerEmitter.h.12//13//===----------------------------------------------------------------------===//1415#ifndef LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H16#define LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H1718#include "X86DisassemblerShared.h"19#include "llvm/Support/X86DisassemblerDecoderCommon.h"20#include <map>21#include <memory>22#include <vector>2324namespace llvm {25class raw_ostream;2627namespace X86Disassembler {2829class ModRMFilter;3031/// DisassemblerTables - Encapsulates all the decode tables being generated by32/// the table emitter. Contains functions to populate the tables as well as33/// to emit them as hierarchical C structures suitable for consumption by the34/// runtime.35class DisassemblerTables {36private:37/// The decoder tables. There is one for each opcode type:38/// [0] one-byte opcodes39/// [1] two-byte opcodes of the form 0f __40/// [2] three-byte opcodes of the form 0f 38 __41/// [3] three-byte opcodes of the form 0f 3a __42/// [4] XOP8 map opcode43/// [5] XOP9 map opcode44/// [6] XOPA map opcode45/// [7] 3dnow map opcode46/// [8] fixed length MAP4 opcode47/// [9] fixed length MAP5 opcode48/// [10] fixed length MAP6 opcode49/// [11] fixed length MAP7 opcode50std::unique_ptr<ContextDecision> Tables[12];5152// Table of ModRM encodings.53typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;54mutable ModRMMapTy ModRMTable;5556/// The instruction information table57std::vector<InstructionSpecifier> InstructionSpecifiers;5859/// True if there are primary decode conflicts in the instruction set60bool HasConflicts;6162/// emitModRMDecision - Emits a table of entries corresponding to a single63/// ModR/M decision. Compacts the ModR/M decision if possible. ModR/M64/// decisions are printed as:65///66/// { /* struct ModRMDecision */67/// TYPE,68/// modRMTablennnn69/// }70///71/// where nnnn is a unique ID for the corresponding table of IDs.72/// TYPE indicates whether the table has one entry that is the same73/// regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one74/// for bytes 0xc0-0xff -, or 256 entries, one for each possible byte.75/// nnnn is the number of a table for looking up these values. The tables76/// are written separately so that tables consisting entirely of zeros will77/// not be duplicated. (These all have the name modRMEmptyTable.) A table78/// is printed as:79///80/// InstrUID modRMTablennnn[k] = {81/// nnnn, /* MNEMONIC */82/// ...83/// nnnn /* MNEMONIC */84/// };85///86/// @param o1 - The output stream to print the ID table to.87/// @param o2 - The output stream to print the decision structure to.88/// @param i1 - The indentation level to use with stream o1.89/// @param i2 - The indentation level to use with stream o2.90/// @param ModRMTableNum - next table number for adding to ModRMTable.91/// @param decision - The ModR/M decision to emit. This decision has 25692/// entries - emitModRMDecision decides how to compact it.93void emitModRMDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1,94unsigned &i2, unsigned &ModRMTableNum,95ModRMDecision &decision) const;9697/// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M98/// decisions. An OpcodeDecision is printed as:99///100/// { /* struct OpcodeDecision */101/// /* 0x00 */102/// { /* struct ModRMDecision */103/// ...104/// }105/// ...106/// }107///108/// where the ModRMDecision structure is printed as described in the109/// documentation for emitModRMDecision(). emitOpcodeDecision() passes on a110/// stream and indent level for the UID tables generated by111/// emitModRMDecision(), but does not use them itself.112///113/// @param o1 - The output stream to print the ID tables generated by114/// emitModRMDecision() to.115/// @param o2 - The output stream for the decision structure itself.116/// @param i1 - The indent level to use with stream o1.117/// @param i2 - The indent level to use with stream o2.118/// @param ModRMTableNum - next table number for adding to ModRMTable.119/// @param decision - The OpcodeDecision to emit along with its subsidiary120/// structures.121void emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1,122unsigned &i2, unsigned &ModRMTableNum,123OpcodeDecision &decision) const;124125/// emitContextDecision - Emits a ContextDecision and all its subsidiary126/// Opcode and ModRMDecisions. A ContextDecision is printed as:127///128/// struct ContextDecision NAME = {129/// { /* OpcodeDecisions */130/// /* IC */131/// { /* struct OpcodeDecision */132/// ...133/// },134/// ...135/// }136/// }137///138/// NAME is the name of the ContextDecision (typically one of the four names139/// ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM from140/// X86DisassemblerDecoderCommon.h).141/// IC is one of the contexts in InstructionContext. There is an opcode142/// decision for each possible context.143/// The OpcodeDecision structures are printed as described in the144/// documentation for emitOpcodeDecision.145///146/// @param o1 - The output stream to print the ID tables generated by147/// emitModRMDecision() to.148/// @param o2 - The output stream to print the decision structure to.149/// @param i1 - The indent level to use with stream o1.150/// @param i2 - The indent level to use with stream o2.151/// @param ModRMTableNum - next table number for adding to ModRMTable.152/// @param decision - The ContextDecision to emit along with its subsidiary153/// structures.154/// @param name - The name for the ContextDecision.155void emitContextDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1,156unsigned &i2, unsigned &ModRMTableNum,157ContextDecision &decision, const char *name) const;158159/// emitInstructionInfo - Prints the instruction specifier table, which has160/// one entry for each instruction, and contains name and operand161/// information. This table is printed as:162///163/// struct InstructionSpecifier CONTEXTS_SYM[k] = {164/// {165/// /* nnnn */166/// "MNEMONIC",167/// 0xnn,168/// {169/// {170/// ENCODING,171/// TYPE172/// },173/// ...174/// }175/// },176/// };177///178/// k is the total number of instructions.179/// nnnn is the ID of the current instruction (0-based). This table180/// includes entries for non-instructions like PHINODE.181/// 0xnn is the lowest possible opcode for the current instruction, used for182/// AddRegFrm instructions to compute the operand's value.183/// ENCODING and TYPE describe the encoding and type for a single operand.184///185/// @param o - The output stream to which the instruction table should be186/// written.187/// @param i - The indent level for use with the stream.188void emitInstructionInfo(raw_ostream &o, unsigned &i) const;189190/// emitContextTable - Prints the table that is used to translate from an191/// instruction attribute mask to an instruction context. This table is192/// printed as:193///194/// InstructionContext CONTEXTS_STR[256] = {195/// IC, /* 0x00 */196/// ...197/// };198///199/// IC is the context corresponding to the mask 0x00, and there are 256200/// possible masks.201///202/// @param o - The output stream to which the context table should be203/// written.204/// @param i - The indent level for use with the stream.205void emitContextTable(raw_ostream &o, uint32_t &i) const;206207/// emitContextDecisions - Prints all four ContextDecision structures using208/// emitContextDecision().209///210/// @param o1 - The output stream to print the ID tables generated by211/// emitModRMDecision() to.212/// @param o2 - The output stream to print the decision structures to.213/// @param i1 - The indent level to use with stream o1.214/// @param i2 - The indent level to use with stream o2.215/// @param ModRMTableNum - next table number for adding to ModRMTable.216void emitContextDecisions(raw_ostream &o1, raw_ostream &o2, unsigned &i1,217unsigned &i2, unsigned &ModRMTableNum) const;218219/// setTableFields - Uses a ModRMFilter to set the appropriate entries in a220/// ModRMDecision to refer to a particular instruction ID.221///222/// @param decision - The ModRMDecision to populate.223/// @param filter - The filter to use in deciding which entries to populate.224/// @param uid - The unique ID to set matching entries to.225/// @param opcode - The opcode of the instruction, for error reporting.226void setTableFields(ModRMDecision &decision, const ModRMFilter &filter,227InstrUID uid, uint8_t opcode);228229public:230/// Constructor - Allocates space for the class decisions and clears them.231DisassemblerTables();232233~DisassemblerTables();234235/// emit - Emits the instruction table, context table, and class decisions.236///237/// @param o - The output stream to print the tables to.238void emit(raw_ostream &o) const;239240/// setTableFields - Uses the opcode type, instruction context, opcode, and a241/// ModRMFilter as criteria to set a particular set of entries in the242/// decode tables to point to a specific uid.243///244/// @param type - The opcode type (ONEBYTE, TWOBYTE, etc.)245/// @param insnContext - The context to use (IC, IC_64BIT, etc.)246/// @param opcode - The last byte of the opcode (not counting any escape247/// or extended opcodes).248/// @param filter - The ModRMFilter that decides which ModR/M byte249/// values250/// correspond to the desired instruction.251/// @param uid - The unique ID of the instruction.252/// @param is32bit - Instructon is only 32-bit253/// @param noPrefix - Instruction record has no prefix.254/// @param ignoresVEX_L - Instruction ignores VEX.L255/// @param ignoresVEX_W - Instruction ignores VEX.W256/// @param AddrSize - Instructions address size 16/32/64. 0 is unspecified257void setTableFields(OpcodeType type, InstructionContext insnContext,258uint8_t opcode, const ModRMFilter &filter, InstrUID uid,259bool is32bit, bool noPrefix, bool ignoresVEX_L,260bool ignoresVEX_W, unsigned AddrSize);261262/// specForUID - Returns the instruction specifier for a given unique263/// instruction ID. Used when resolving collisions.264///265/// @param uid - The unique ID of the instruction.266/// @return - A reference to the instruction specifier.267InstructionSpecifier &specForUID(InstrUID uid) {268if (uid >= InstructionSpecifiers.size())269InstructionSpecifiers.resize(uid + 1);270271return InstructionSpecifiers[uid];272}273274// hasConflicts - Reports whether there were primary decode conflicts275// from any instructions added to the tables.276// @return - true if there were; false otherwise.277278bool hasConflicts() { return HasConflicts; }279};280281} // namespace X86Disassembler282283} // namespace llvm284285#endif286287288