| //===- 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 |