X86DisassemblerTables.h 12 KB

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