|  | //===- X86DisassemblerTables.h - Disassembler tables ------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file is part of the X86 Disassembler Emitter. | 
|  | // It contains the interface of the disassembler tables. | 
|  | // Documentation for the disassembler emitter in general can be found in | 
|  | //  X86DisassemblerEmitter.h. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H | 
|  | #define LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H | 
|  |  | 
|  | #include "X86DisassemblerShared.h" | 
|  | #include "X86ModRMFilters.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  | #include <map> | 
|  | #include <vector> | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | namespace X86Disassembler { | 
|  |  | 
|  | /// DisassemblerTables - Encapsulates all the decode tables being generated by | 
|  | ///   the table emitter.  Contains functions to populate the tables as well as | 
|  | ///   to emit them as hierarchical C structures suitable for consumption by the | 
|  | ///   runtime. | 
|  | class DisassemblerTables { | 
|  | private: | 
|  | /// The decoder tables.  There is one for each opcode type: | 
|  | /// [0] one-byte opcodes | 
|  | /// [1] two-byte opcodes of the form 0f __ | 
|  | /// [2] three-byte opcodes of the form 0f 38 __ | 
|  | /// [3] three-byte opcodes of the form 0f 3a __ | 
|  | /// [4] XOP8 map opcode | 
|  | /// [5] XOP9 map opcode | 
|  | /// [6] XOPA map opcode | 
|  | /// [7] 3dnow map opcode | 
|  | std::unique_ptr<ContextDecision> Tables[8]; | 
|  |  | 
|  | // Table of ModRM encodings. | 
|  | typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy; | 
|  | mutable ModRMMapTy ModRMTable; | 
|  |  | 
|  | /// The instruction information table | 
|  | std::vector<InstructionSpecifier> InstructionSpecifiers; | 
|  |  | 
|  | /// True if there are primary decode conflicts in the instruction set | 
|  | bool HasConflicts; | 
|  |  | 
|  | /// emitModRMDecision - Emits a table of entries corresponding to a single | 
|  | ///   ModR/M decision.  Compacts the ModR/M decision if possible.  ModR/M | 
|  | ///   decisions are printed as: | 
|  | /// | 
|  | ///   { /* struct ModRMDecision */ | 
|  | ///     TYPE, | 
|  | ///     modRMTablennnn | 
|  | ///   } | 
|  | /// | 
|  | ///   where nnnn is a unique ID for the corresponding table of IDs. | 
|  | ///   TYPE indicates whether the table has one entry that is the same | 
|  | ///   regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one | 
|  | ///   for bytes 0xc0-0xff -, or 256 entries, one for each possible byte. | 
|  | ///   nnnn is the number of a table for looking up these values.  The tables | 
|  | ///   are written separately so that tables consisting entirely of zeros will | 
|  | ///   not be duplicated.  (These all have the name modRMEmptyTable.)  A table | 
|  | ///   is printed as: | 
|  | /// | 
|  | ///   InstrUID modRMTablennnn[k] = { | 
|  | ///     nnnn, /* MNEMONIC */ | 
|  | ///     ... | 
|  | ///     nnnn /* MNEMONIC */ | 
|  | ///   }; | 
|  | /// | 
|  | /// @param o1       - The output stream to print the ID table to. | 
|  | /// @param o2       - The output stream to print the decision structure to. | 
|  | /// @param i1       - The indentation level to use with stream o1. | 
|  | /// @param i2       - The indentation level to use with stream o2. | 
|  | /// @param ModRMTableNum - next table number for adding to ModRMTable. | 
|  | /// @param decision - The ModR/M decision to emit.  This decision has 256 | 
|  | ///                   entries - emitModRMDecision decides how to compact it. | 
|  | void emitModRMDecision(raw_ostream &o1, raw_ostream &o2, | 
|  | unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, | 
|  | ModRMDecision &decision) const; | 
|  |  | 
|  | /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M | 
|  | ///   decisions.  An OpcodeDecision is printed as: | 
|  | /// | 
|  | ///   { /* struct OpcodeDecision */ | 
|  | ///     /* 0x00 */ | 
|  | ///     { /* struct ModRMDecision */ | 
|  | ///       ... | 
|  | ///     } | 
|  | ///     ... | 
|  | ///   } | 
|  | /// | 
|  | ///   where the ModRMDecision structure is printed as described in the | 
|  | ///   documentation for emitModRMDecision().  emitOpcodeDecision() passes on a | 
|  | ///   stream and indent level for the UID tables generated by | 
|  | ///   emitModRMDecision(), but does not use them itself. | 
|  | /// | 
|  | /// @param o1       - The output stream to print the ID tables generated by | 
|  | ///                   emitModRMDecision() to. | 
|  | /// @param o2       - The output stream for the decision structure itself. | 
|  | /// @param i1       - The indent level to use with stream o1. | 
|  | /// @param i2       - The indent level to use with stream o2. | 
|  | /// @param ModRMTableNum - next table number for adding to ModRMTable. | 
|  | /// @param decision - The OpcodeDecision to emit along with its subsidiary | 
|  | ///                    structures. | 
|  | void emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, | 
|  | unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, | 
|  | OpcodeDecision &decision) const; | 
|  |  | 
|  | /// emitContextDecision - Emits a ContextDecision and all its subsidiary | 
|  | ///   Opcode and ModRMDecisions.  A ContextDecision is printed as: | 
|  | /// | 
|  | ///   struct ContextDecision NAME = { | 
|  | ///     { /* OpcodeDecisions */ | 
|  | ///       /* IC */ | 
|  | ///       { /* struct OpcodeDecision */ | 
|  | ///         ... | 
|  | ///       }, | 
|  | ///       ... | 
|  | ///     } | 
|  | ///   } | 
|  | /// | 
|  | ///   NAME is the name of the ContextDecision (typically one of the four names | 
|  | ///   ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM from | 
|  | ///   X86DisassemblerDecoderCommon.h). | 
|  | ///   IC is one of the contexts in InstructionContext.  There is an opcode | 
|  | ///   decision for each possible context. | 
|  | ///   The OpcodeDecision structures are printed as described in the | 
|  | ///   documentation for emitOpcodeDecision. | 
|  | /// | 
|  | /// @param o1       - The output stream to print the ID tables generated by | 
|  | ///                   emitModRMDecision() to. | 
|  | /// @param o2       - The output stream to print the decision structure to. | 
|  | /// @param i1       - The indent level to use with stream o1. | 
|  | /// @param i2       - The indent level to use with stream o2. | 
|  | /// @param ModRMTableNum - next table number for adding to ModRMTable. | 
|  | /// @param decision - The ContextDecision to emit along with its subsidiary | 
|  | ///                   structures. | 
|  | /// @param name     - The name for the ContextDecision. | 
|  | void emitContextDecision(raw_ostream &o1, raw_ostream &o2, | 
|  | unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, | 
|  | ContextDecision &decision, const char* name) const; | 
|  |  | 
|  | /// emitInstructionInfo - Prints the instruction specifier table, which has | 
|  | ///   one entry for each instruction, and contains name and operand | 
|  | ///   information.  This table is printed as: | 
|  | /// | 
|  | ///   struct InstructionSpecifier CONTEXTS_SYM[k] = { | 
|  | ///     { | 
|  | ///       /* nnnn */ | 
|  | ///       "MNEMONIC", | 
|  | ///       0xnn, | 
|  | ///       { | 
|  | ///         { | 
|  | ///           ENCODING, | 
|  | ///           TYPE | 
|  | ///         }, | 
|  | ///         ... | 
|  | ///       } | 
|  | ///     }, | 
|  | ///   }; | 
|  | /// | 
|  | ///   k is the total number of instructions. | 
|  | ///   nnnn is the ID of the current instruction (0-based).  This table | 
|  | ///   includes entries for non-instructions like PHINODE. | 
|  | ///   0xnn is the lowest possible opcode for the current instruction, used for | 
|  | ///   AddRegFrm instructions to compute the operand's value. | 
|  | ///   ENCODING and TYPE describe the encoding and type for a single operand. | 
|  | /// | 
|  | /// @param o  - The output stream to which the instruction table should be | 
|  | ///             written. | 
|  | /// @param i  - The indent level for use with the stream. | 
|  | void emitInstructionInfo(raw_ostream &o, unsigned &i) const; | 
|  |  | 
|  | /// emitContextTable - Prints the table that is used to translate from an | 
|  | ///   instruction attribute mask to an instruction context.  This table is | 
|  | ///   printed as: | 
|  | /// | 
|  | ///   InstructionContext CONTEXTS_STR[256] = { | 
|  | ///     IC, /* 0x00 */ | 
|  | ///     ... | 
|  | ///   }; | 
|  | /// | 
|  | ///   IC is the context corresponding to the mask 0x00, and there are 256 | 
|  | ///   possible masks. | 
|  | /// | 
|  | /// @param o  - The output stream to which the context table should be written. | 
|  | /// @param i  - The indent level for use with the stream. | 
|  | void emitContextTable(raw_ostream &o, uint32_t &i) const; | 
|  |  | 
|  | /// emitContextDecisions - Prints all four ContextDecision structures using | 
|  | ///   emitContextDecision(). | 
|  | /// | 
|  | /// @param o1 - The output stream to print the ID tables generated by | 
|  | ///             emitModRMDecision() to. | 
|  | /// @param o2 - The output stream to print the decision structures to. | 
|  | /// @param i1 - The indent level to use with stream o1. | 
|  | /// @param i2 - The indent level to use with stream o2. | 
|  | /// @param ModRMTableNum - next table number for adding to ModRMTable. | 
|  | void emitContextDecisions(raw_ostream &o1, raw_ostream &o2, | 
|  | unsigned &i1, unsigned &i2, | 
|  | unsigned &ModRMTableNum) const; | 
|  |  | 
|  | /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a | 
|  | ///   ModRMDecision to refer to a particular instruction ID. | 
|  | /// | 
|  | /// @param decision - The ModRMDecision to populate. | 
|  | /// @param filter   - The filter to use in deciding which entries to populate. | 
|  | /// @param uid      - The unique ID to set matching entries to. | 
|  | /// @param opcode   - The opcode of the instruction, for error reporting. | 
|  | void setTableFields(ModRMDecision &decision, | 
|  | const ModRMFilter &filter, | 
|  | InstrUID uid, | 
|  | uint8_t opcode); | 
|  | public: | 
|  | /// Constructor - Allocates space for the class decisions and clears them. | 
|  | DisassemblerTables(); | 
|  |  | 
|  | ~DisassemblerTables(); | 
|  |  | 
|  | /// emit - Emits the instruction table, context table, and class decisions. | 
|  | /// | 
|  | /// @param o  - The output stream to print the tables to. | 
|  | void emit(raw_ostream &o) const; | 
|  |  | 
|  | /// setTableFields - Uses the opcode type, instruction context, opcode, and a | 
|  | ///   ModRMFilter as criteria to set a particular set of entries in the | 
|  | ///   decode tables to point to a specific uid. | 
|  | /// | 
|  | /// @param type         - The opcode type (ONEBYTE, TWOBYTE, etc.) | 
|  | /// @param insnContext  - The context to use (IC, IC_64BIT, etc.) | 
|  | /// @param opcode       - The last byte of the opcode (not counting any escape | 
|  | ///                       or extended opcodes). | 
|  | /// @param filter       - The ModRMFilter that decides which ModR/M byte values | 
|  | ///                       correspond to the desired instruction. | 
|  | /// @param uid          - The unique ID of the instruction. | 
|  | /// @param is32bit      - Instructon is only 32-bit | 
|  | /// @param noPrefix     - Instruction record has no prefix. | 
|  | /// @param ignoresVEX_L - Instruction ignores VEX.L | 
|  | /// @param ignoresVEX_W - Instruction ignores VEX.W | 
|  | /// @param AddrSize     - Instructions address size 16/32/64. 0 is unspecified | 
|  | void setTableFields(OpcodeType type, | 
|  | InstructionContext insnContext, | 
|  | uint8_t opcode, | 
|  | const ModRMFilter &filter, | 
|  | InstrUID uid, | 
|  | bool is32bit, | 
|  | bool noPrefix, | 
|  | bool ignoresVEX_L, | 
|  | bool ignoresVEX_W, | 
|  | unsigned AddrSize); | 
|  |  | 
|  | /// specForUID - Returns the instruction specifier for a given unique | 
|  | ///   instruction ID.  Used when resolving collisions. | 
|  | /// | 
|  | /// @param uid  - The unique ID of the instruction. | 
|  | /// @return     - A reference to the instruction specifier. | 
|  | InstructionSpecifier& specForUID(InstrUID uid) { | 
|  | if (uid >= InstructionSpecifiers.size()) | 
|  | InstructionSpecifiers.resize(uid + 1); | 
|  |  | 
|  | return InstructionSpecifiers[uid]; | 
|  | } | 
|  |  | 
|  | // hasConflicts - Reports whether there were primary decode conflicts | 
|  | //   from any instructions added to the tables. | 
|  | // @return  - true if there were; false otherwise. | 
|  |  | 
|  | bool hasConflicts() { | 
|  | return HasConflicts; | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // namespace X86Disassembler | 
|  |  | 
|  | } // namespace llvm | 
|  |  | 
|  | #endif |