X86DisassemblerTables.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. //===- X86DisassemblerTables.h - Disassembler 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 file is part of the X86 Disassembler Emitter.
  10. // It contains the interface of the disassembler tables.
  11. // Documentation for the disassembler emitter in general can be found in
  12. // X86DisassemblerEmitter.h.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #ifndef LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H
  16. #define LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H
  17. #include "X86DisassemblerShared.h"
  18. #include "X86ModRMFilters.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. #include <map>
  21. #include <vector>
  22. namespace llvm {
  23. namespace X86Disassembler {
  24. /// DisassemblerTables - Encapsulates all the decode tables being generated by
  25. /// the table emitter. Contains functions to populate the tables as well as
  26. /// to emit them as hierarchical C structures suitable for consumption by the
  27. /// runtime.
  28. class DisassemblerTables {
  29. private:
  30. /// The decoder tables. There is one for each opcode type:
  31. /// [0] one-byte opcodes
  32. /// [1] two-byte opcodes of the form 0f __
  33. /// [2] three-byte opcodes of the form 0f 38 __
  34. /// [3] three-byte opcodes of the form 0f 3a __
  35. /// [4] XOP8 map opcode
  36. /// [5] XOP9 map opcode
  37. /// [6] XOPA map opcode
  38. /// [7] 3dnow map opcode
  39. std::unique_ptr<ContextDecision> Tables[8];
  40. // Table of ModRM encodings.
  41. typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;
  42. mutable ModRMMapTy ModRMTable;
  43. /// The instruction information table
  44. std::vector<InstructionSpecifier> InstructionSpecifiers;
  45. /// True if there are primary decode conflicts in the instruction set
  46. bool HasConflicts;
  47. /// emitModRMDecision - Emits a table of entries corresponding to a single
  48. /// ModR/M decision. Compacts the ModR/M decision if possible. ModR/M
  49. /// decisions are printed as:
  50. ///
  51. /// { /* struct ModRMDecision */
  52. /// TYPE,
  53. /// modRMTablennnn
  54. /// }
  55. ///
  56. /// where nnnn is a unique ID for the corresponding table of IDs.
  57. /// TYPE indicates whether the table has one entry that is the same
  58. /// regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one
  59. /// for bytes 0xc0-0xff -, or 256 entries, one for each possible byte.
  60. /// nnnn is the number of a table for looking up these values. The tables
  61. /// are written separately so that tables consisting entirely of zeros will
  62. /// not be duplicated. (These all have the name modRMEmptyTable.) A table
  63. /// is printed as:
  64. ///
  65. /// InstrUID modRMTablennnn[k] = {
  66. /// nnnn, /* MNEMONIC */
  67. /// ...
  68. /// nnnn /* MNEMONIC */
  69. /// };
  70. ///
  71. /// @param o1 - The output stream to print the ID table to.
  72. /// @param o2 - The output stream to print the decision structure to.
  73. /// @param i1 - The indentation level to use with stream o1.
  74. /// @param i2 - The indentation level to use with stream o2.
  75. /// @param ModRMTableNum - next table number for adding to ModRMTable.
  76. /// @param decision - The ModR/M decision to emit. This decision has 256
  77. /// entries - emitModRMDecision decides how to compact it.
  78. void emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
  79. unsigned &i1, unsigned &i2, unsigned &ModRMTableNum,
  80. ModRMDecision &decision) const;
  81. /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M
  82. /// decisions. An OpcodeDecision is printed as:
  83. ///
  84. /// { /* struct OpcodeDecision */
  85. /// /* 0x00 */
  86. /// { /* struct ModRMDecision */
  87. /// ...
  88. /// }
  89. /// ...
  90. /// }
  91. ///
  92. /// where the ModRMDecision structure is printed as described in the
  93. /// documentation for emitModRMDecision(). emitOpcodeDecision() passes on a
  94. /// stream and indent level for the UID tables generated by
  95. /// emitModRMDecision(), but does not use them itself.
  96. ///
  97. /// @param o1 - The output stream to print the ID tables generated by
  98. /// emitModRMDecision() to.
  99. /// @param o2 - The output stream for the decision structure itself.
  100. /// @param i1 - The indent level to use with stream o1.
  101. /// @param i2 - The indent level to use with stream o2.
  102. /// @param ModRMTableNum - next table number for adding to ModRMTable.
  103. /// @param decision - The OpcodeDecision to emit along with its subsidiary
  104. /// structures.
  105. void emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
  106. unsigned &i1, unsigned &i2, unsigned &ModRMTableNum,
  107. OpcodeDecision &decision) const;
  108. /// emitContextDecision - Emits a ContextDecision and all its subsidiary
  109. /// Opcode and ModRMDecisions. A ContextDecision is printed as:
  110. ///
  111. /// struct ContextDecision NAME = {
  112. /// { /* OpcodeDecisions */
  113. /// /* IC */
  114. /// { /* struct OpcodeDecision */
  115. /// ...
  116. /// },
  117. /// ...
  118. /// }
  119. /// }
  120. ///
  121. /// NAME is the name of the ContextDecision (typically one of the four names
  122. /// ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM from
  123. /// X86DisassemblerDecoderCommon.h).
  124. /// IC is one of the contexts in InstructionContext. There is an opcode
  125. /// decision for each possible context.
  126. /// The OpcodeDecision structures are printed as described in the
  127. /// documentation for emitOpcodeDecision.
  128. ///
  129. /// @param o1 - The output stream to print the ID tables generated by
  130. /// emitModRMDecision() to.
  131. /// @param o2 - The output stream to print the decision structure to.
  132. /// @param i1 - The indent level to use with stream o1.
  133. /// @param i2 - The indent level to use with stream o2.
  134. /// @param ModRMTableNum - next table number for adding to ModRMTable.
  135. /// @param decision - The ContextDecision to emit along with its subsidiary
  136. /// structures.
  137. /// @param name - The name for the ContextDecision.
  138. void emitContextDecision(raw_ostream &o1, raw_ostream &o2,
  139. unsigned &i1, unsigned &i2, unsigned &ModRMTableNum,
  140. ContextDecision &decision, const char* name) const;
  141. /// emitInstructionInfo - Prints the instruction specifier table, which has
  142. /// one entry for each instruction, and contains name and operand
  143. /// information. This table is printed as:
  144. ///
  145. /// struct InstructionSpecifier CONTEXTS_SYM[k] = {
  146. /// {
  147. /// /* nnnn */
  148. /// "MNEMONIC",
  149. /// 0xnn,
  150. /// {
  151. /// {
  152. /// ENCODING,
  153. /// TYPE
  154. /// },
  155. /// ...
  156. /// }
  157. /// },
  158. /// };
  159. ///
  160. /// k is the total number of instructions.
  161. /// nnnn is the ID of the current instruction (0-based). This table
  162. /// includes entries for non-instructions like PHINODE.
  163. /// 0xnn is the lowest possible opcode for the current instruction, used for
  164. /// AddRegFrm instructions to compute the operand's value.
  165. /// ENCODING and TYPE describe the encoding and type for a single operand.
  166. ///
  167. /// @param o - The output stream to which the instruction table should be
  168. /// written.
  169. /// @param i - The indent level for use with the stream.
  170. void emitInstructionInfo(raw_ostream &o, unsigned &i) const;
  171. /// emitContextTable - Prints the table that is used to translate from an
  172. /// instruction attribute mask to an instruction context. This table is
  173. /// printed as:
  174. ///
  175. /// InstructionContext CONTEXTS_STR[256] = {
  176. /// IC, /* 0x00 */
  177. /// ...
  178. /// };
  179. ///
  180. /// IC is the context corresponding to the mask 0x00, and there are 256
  181. /// possible masks.
  182. ///
  183. /// @param o - The output stream to which the context table should be written.
  184. /// @param i - The indent level for use with the stream.
  185. void emitContextTable(raw_ostream &o, uint32_t &i) const;
  186. /// emitContextDecisions - Prints all four ContextDecision structures using
  187. /// emitContextDecision().
  188. ///
  189. /// @param o1 - The output stream to print the ID tables generated by
  190. /// emitModRMDecision() to.
  191. /// @param o2 - The output stream to print the decision structures to.
  192. /// @param i1 - The indent level to use with stream o1.
  193. /// @param i2 - The indent level to use with stream o2.
  194. /// @param ModRMTableNum - next table number for adding to ModRMTable.
  195. void emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
  196. unsigned &i1, unsigned &i2,
  197. unsigned &ModRMTableNum) const;
  198. /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a
  199. /// ModRMDecision to refer to a particular instruction ID.
  200. ///
  201. /// @param decision - The ModRMDecision to populate.
  202. /// @param filter - The filter to use in deciding which entries to populate.
  203. /// @param uid - The unique ID to set matching entries to.
  204. /// @param opcode - The opcode of the instruction, for error reporting.
  205. void setTableFields(ModRMDecision &decision,
  206. const ModRMFilter &filter,
  207. InstrUID uid,
  208. uint8_t opcode);
  209. public:
  210. /// Constructor - Allocates space for the class decisions and clears them.
  211. DisassemblerTables();
  212. ~DisassemblerTables();
  213. /// emit - Emits the instruction table, context table, and class decisions.
  214. ///
  215. /// @param o - The output stream to print the tables to.
  216. void emit(raw_ostream &o) const;
  217. /// setTableFields - Uses the opcode type, instruction context, opcode, and a
  218. /// ModRMFilter as criteria to set a particular set of entries in the
  219. /// decode tables to point to a specific uid.
  220. ///
  221. /// @param type - The opcode type (ONEBYTE, TWOBYTE, etc.)
  222. /// @param insnContext - The context to use (IC, IC_64BIT, etc.)
  223. /// @param opcode - The last byte of the opcode (not counting any escape
  224. /// or extended opcodes).
  225. /// @param filter - The ModRMFilter that decides which ModR/M byte values
  226. /// correspond to the desired instruction.
  227. /// @param uid - The unique ID of the instruction.
  228. /// @param is32bit - Instructon is only 32-bit
  229. /// @param noPrefix - Instruction record has no prefix.
  230. /// @param ignoresVEX_L - Instruction ignores VEX.L
  231. /// @param ignoresVEX_W - Instruction ignores VEX.W
  232. /// @param AddrSize - Instructions address size 16/32/64. 0 is unspecified
  233. void setTableFields(OpcodeType type,
  234. InstructionContext insnContext,
  235. uint8_t opcode,
  236. const ModRMFilter &filter,
  237. InstrUID uid,
  238. bool is32bit,
  239. bool noPrefix,
  240. bool ignoresVEX_L,
  241. bool ignoresVEX_W,
  242. unsigned AddrSize);
  243. /// specForUID - Returns the instruction specifier for a given unique
  244. /// instruction ID. Used when resolving collisions.
  245. ///
  246. /// @param uid - The unique ID of the instruction.
  247. /// @return - A reference to the instruction specifier.
  248. InstructionSpecifier& specForUID(InstrUID uid) {
  249. if (uid >= InstructionSpecifiers.size())
  250. InstructionSpecifiers.resize(uid + 1);
  251. return InstructionSpecifiers[uid];
  252. }
  253. // hasConflicts - Reports whether there were primary decode conflicts
  254. // from any instructions added to the tables.
  255. // @return - true if there were; false otherwise.
  256. bool hasConflicts() {
  257. return HasConflicts;
  258. }
  259. };
  260. } // namespace X86Disassembler
  261. } // namespace llvm
  262. #endif