blob: b0ea9c2e86252d07c7d964835ef774c2f3152b31 [file] [log] [blame]
Sean Callanan8ed9f512009-12-19 02:59:52 +00001//===- X86DisassemblerTables.h - Disassembler tables ------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the X86 Disassembler Emitter.
11// It contains the interface of the disassembler tables.
12// Documentation for the disassembler emitter in general can be found in
Hiroshi Inoueb08063c2017-07-04 13:09:29 +000013// X86DisassemblerEmitter.h.
Sean Callanan8ed9f512009-12-19 02:59:52 +000014//
15//===----------------------------------------------------------------------===//
16
Benjamin Kramer00e08fc2014-08-13 16:26:38 +000017#ifndef LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H
18#define LLVM_UTILS_TABLEGEN_X86DISASSEMBLERTABLES_H
Sean Callanan8ed9f512009-12-19 02:59:52 +000019
20#include "X86DisassemblerShared.h"
21#include "X86ModRMFilters.h"
Sean Callanan8ed9f512009-12-19 02:59:52 +000022#include "llvm/Support/raw_ostream.h"
Craig Topper39004b52013-09-30 06:23:19 +000023#include <map>
Sean Callanan8ed9f512009-12-19 02:59:52 +000024#include <vector>
25
26namespace llvm {
27
28namespace X86Disassembler {
29
30/// DisassemblerTables - Encapsulates all the decode tables being generated by
31/// the table emitter. Contains functions to populate the tables as well as
32/// to emit them as hierarchical C structures suitable for consumption by the
33/// runtime.
34class DisassemblerTables {
35private:
36 /// The decoder tables. There is one for each opcode type:
37 /// [0] one-byte opcodes
38 /// [1] two-byte opcodes of the form 0f __
39 /// [2] three-byte opcodes of the form 0f 38 __
40 /// [3] three-byte opcodes of the form 0f 3a __
Craig Topper82a644a2014-02-19 05:34:21 +000041 /// [4] XOP8 map opcode
42 /// [5] XOP9 map opcode
43 /// [6] XOPA map opcode
Craig Topper7cff4112018-03-24 07:48:54 +000044 /// [7] 3dnow map opcode
45 std::unique_ptr<ContextDecision> Tables[8];
Craig Toppera31359a2012-07-31 05:28:41 +000046
Craig Topper39004b52013-09-30 06:23:19 +000047 // Table of ModRM encodings.
48 typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy;
49 mutable ModRMMapTy ModRMTable;
50
Sean Callanan8ed9f512009-12-19 02:59:52 +000051 /// The instruction information table
52 std::vector<InstructionSpecifier> InstructionSpecifiers;
Craig Toppera31359a2012-07-31 05:28:41 +000053
Sean Callanan8ed9f512009-12-19 02:59:52 +000054 /// True if there are primary decode conflicts in the instruction set
55 bool HasConflicts;
Craig Toppera31359a2012-07-31 05:28:41 +000056
Sean Callanan8ed9f512009-12-19 02:59:52 +000057 /// emitModRMDecision - Emits a table of entries corresponding to a single
58 /// ModR/M decision. Compacts the ModR/M decision if possible. ModR/M
59 /// decisions are printed as:
60 ///
61 /// { /* struct ModRMDecision */
62 /// TYPE,
63 /// modRMTablennnn
64 /// }
65 ///
66 /// where nnnn is a unique ID for the corresponding table of IDs.
67 /// TYPE indicates whether the table has one entry that is the same
68 /// regardless of ModR/M byte, two entries - one for bytes 0x00-0xbf and one
Craig Toppera31359a2012-07-31 05:28:41 +000069 /// for bytes 0xc0-0xff -, or 256 entries, one for each possible byte.
Sean Callanan8ed9f512009-12-19 02:59:52 +000070 /// nnnn is the number of a table for looking up these values. The tables
Chris Lattner7a2bdde2011-04-15 05:18:47 +000071 /// are written separately so that tables consisting entirely of zeros will
Sean Callanan8ed9f512009-12-19 02:59:52 +000072 /// not be duplicated. (These all have the name modRMEmptyTable.) A table
73 /// is printed as:
Craig Toppera31359a2012-07-31 05:28:41 +000074 ///
Sean Callanan8ed9f512009-12-19 02:59:52 +000075 /// InstrUID modRMTablennnn[k] = {
76 /// nnnn, /* MNEMONIC */
77 /// ...
78 /// nnnn /* MNEMONIC */
79 /// };
80 ///
81 /// @param o1 - The output stream to print the ID table to.
82 /// @param o2 - The output stream to print the decision structure to.
83 /// @param i1 - The indentation level to use with stream o1.
84 /// @param i2 - The indentation level to use with stream o2.
Craig Topper39004b52013-09-30 06:23:19 +000085 /// @param ModRMTableNum - next table number for adding to ModRMTable.
Sean Callanan8ed9f512009-12-19 02:59:52 +000086 /// @param decision - The ModR/M decision to emit. This decision has 256
87 /// entries - emitModRMDecision decides how to compact it.
Craig Topper39004b52013-09-30 06:23:19 +000088 void emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
89 unsigned &i1, unsigned &i2, unsigned &ModRMTableNum,
Sean Callanan8ed9f512009-12-19 02:59:52 +000090 ModRMDecision &decision) const;
Craig Toppera31359a2012-07-31 05:28:41 +000091
Sean Callanan8ed9f512009-12-19 02:59:52 +000092 /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M
93 /// decisions. An OpcodeDecision is printed as:
94 ///
95 /// { /* struct OpcodeDecision */
96 /// /* 0x00 */
97 /// { /* struct ModRMDecision */
98 /// ...
99 /// }
100 /// ...
101 /// }
102 ///
103 /// where the ModRMDecision structure is printed as described in the
104 /// documentation for emitModRMDecision(). emitOpcodeDecision() passes on a
105 /// stream and indent level for the UID tables generated by
106 /// emitModRMDecision(), but does not use them itself.
107 ///
108 /// @param o1 - The output stream to print the ID tables generated by
109 /// emitModRMDecision() to.
110 /// @param o2 - The output stream for the decision structure itself.
111 /// @param i1 - The indent level to use with stream o1.
112 /// @param i2 - The indent level to use with stream o2.
Craig Topper39004b52013-09-30 06:23:19 +0000113 /// @param ModRMTableNum - next table number for adding to ModRMTable.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000114 /// @param decision - The OpcodeDecision to emit along with its subsidiary
115 /// structures.
Craig Topper39004b52013-09-30 06:23:19 +0000116 void emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2,
117 unsigned &i1, unsigned &i2, unsigned &ModRMTableNum,
Sean Callanan8ed9f512009-12-19 02:59:52 +0000118 OpcodeDecision &decision) const;
Craig Toppera31359a2012-07-31 05:28:41 +0000119
120 /// emitContextDecision - Emits a ContextDecision and all its subsidiary
Sean Callanan8ed9f512009-12-19 02:59:52 +0000121 /// Opcode and ModRMDecisions. A ContextDecision is printed as:
122 ///
123 /// struct ContextDecision NAME = {
124 /// { /* OpcodeDecisions */
125 /// /* IC */
126 /// { /* struct OpcodeDecision */
127 /// ...
128 /// },
129 /// ...
130 /// }
131 /// }
132 ///
Joerg Sonnenberger4a8ac8d2011-04-04 16:58:13 +0000133 /// NAME is the name of the ContextDecision (typically one of the four names
Craig Topper82a644a2014-02-19 05:34:21 +0000134 /// ONEBYTE_SYM, TWOBYTE_SYM, THREEBYTE38_SYM, THREEBYTE3A_SYM from
Sean Callanan8ed9f512009-12-19 02:59:52 +0000135 /// X86DisassemblerDecoderCommon.h).
136 /// IC is one of the contexts in InstructionContext. There is an opcode
137 /// decision for each possible context.
138 /// The OpcodeDecision structures are printed as described in the
139 /// documentation for emitOpcodeDecision.
140 ///
141 /// @param o1 - The output stream to print the ID tables generated by
142 /// emitModRMDecision() to.
143 /// @param o2 - The output stream to print the decision structure to.
144 /// @param i1 - The indent level to use with stream o1.
145 /// @param i2 - The indent level to use with stream o2.
Craig Topper39004b52013-09-30 06:23:19 +0000146 /// @param ModRMTableNum - next table number for adding to ModRMTable.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000147 /// @param decision - The ContextDecision to emit along with its subsidiary
148 /// structures.
149 /// @param name - The name for the ContextDecision.
Craig Topper39004b52013-09-30 06:23:19 +0000150 void emitContextDecision(raw_ostream &o1, raw_ostream &o2,
151 unsigned &i1, unsigned &i2, unsigned &ModRMTableNum,
152 ContextDecision &decision, const char* name) const;
Craig Toppera31359a2012-07-31 05:28:41 +0000153
Sean Callanan8ed9f512009-12-19 02:59:52 +0000154 /// emitInstructionInfo - Prints the instruction specifier table, which has
155 /// one entry for each instruction, and contains name and operand
156 /// information. This table is printed as:
157 ///
158 /// struct InstructionSpecifier CONTEXTS_SYM[k] = {
159 /// {
160 /// /* nnnn */
161 /// "MNEMONIC",
162 /// 0xnn,
163 /// {
164 /// {
165 /// ENCODING,
166 /// TYPE
167 /// },
168 /// ...
169 /// }
170 /// },
171 /// };
172 ///
173 /// k is the total number of instructions.
Craig Toppera31359a2012-07-31 05:28:41 +0000174 /// nnnn is the ID of the current instruction (0-based). This table
Sean Callanan8ed9f512009-12-19 02:59:52 +0000175 /// includes entries for non-instructions like PHINODE.
176 /// 0xnn is the lowest possible opcode for the current instruction, used for
177 /// AddRegFrm instructions to compute the operand's value.
178 /// ENCODING and TYPE describe the encoding and type for a single operand.
179 ///
Craig Toppera31359a2012-07-31 05:28:41 +0000180 /// @param o - The output stream to which the instruction table should be
Sean Callanan8ed9f512009-12-19 02:59:52 +0000181 /// written.
182 /// @param i - The indent level for use with the stream.
Craig Topper39004b52013-09-30 06:23:19 +0000183 void emitInstructionInfo(raw_ostream &o, unsigned &i) const;
Craig Toppera31359a2012-07-31 05:28:41 +0000184
Sean Callanan8ed9f512009-12-19 02:59:52 +0000185 /// emitContextTable - Prints the table that is used to translate from an
186 /// instruction attribute mask to an instruction context. This table is
187 /// printed as:
188 ///
189 /// InstructionContext CONTEXTS_STR[256] = {
190 /// IC, /* 0x00 */
191 /// ...
192 /// };
193 ///
194 /// IC is the context corresponding to the mask 0x00, and there are 256
195 /// possible masks.
196 ///
197 /// @param o - The output stream to which the context table should be written.
198 /// @param i - The indent level for use with the stream.
199 void emitContextTable(raw_ostream &o, uint32_t &i) const;
Craig Toppera31359a2012-07-31 05:28:41 +0000200
Sean Callanan8ed9f512009-12-19 02:59:52 +0000201 /// emitContextDecisions - Prints all four ContextDecision structures using
202 /// emitContextDecision().
203 ///
204 /// @param o1 - The output stream to print the ID tables generated by
205 /// emitModRMDecision() to.
206 /// @param o2 - The output stream to print the decision structures to.
207 /// @param i1 - The indent level to use with stream o1.
208 /// @param i2 - The indent level to use with stream o2.
Craig Topper39004b52013-09-30 06:23:19 +0000209 /// @param ModRMTableNum - next table number for adding to ModRMTable.
210 void emitContextDecisions(raw_ostream &o1, raw_ostream &o2,
211 unsigned &i1, unsigned &i2,
212 unsigned &ModRMTableNum) const;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000213
214 /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a
215 /// ModRMDecision to refer to a particular instruction ID.
216 ///
217 /// @param decision - The ModRMDecision to populate.
218 /// @param filter - The filter to use in deciding which entries to populate.
219 /// @param uid - The unique ID to set matching entries to.
220 /// @param opcode - The opcode of the instruction, for error reporting.
221 void setTableFields(ModRMDecision &decision,
222 const ModRMFilter &filter,
223 InstrUID uid,
224 uint8_t opcode);
225public:
226 /// Constructor - Allocates space for the class decisions and clears them.
227 DisassemblerTables();
Craig Toppera31359a2012-07-31 05:28:41 +0000228
Sean Callanan8ed9f512009-12-19 02:59:52 +0000229 ~DisassemblerTables();
Craig Toppera31359a2012-07-31 05:28:41 +0000230
Sean Callanan8ed9f512009-12-19 02:59:52 +0000231 /// emit - Emits the instruction table, context table, and class decisions.
232 ///
233 /// @param o - The output stream to print the tables to.
234 void emit(raw_ostream &o) const;
Craig Toppera31359a2012-07-31 05:28:41 +0000235
Sean Callanan8ed9f512009-12-19 02:59:52 +0000236 /// setTableFields - Uses the opcode type, instruction context, opcode, and a
237 /// ModRMFilter as criteria to set a particular set of entries in the
238 /// decode tables to point to a specific uid.
239 ///
240 /// @param type - The opcode type (ONEBYTE, TWOBYTE, etc.)
241 /// @param insnContext - The context to use (IC, IC_64BIT, etc.)
242 /// @param opcode - The last byte of the opcode (not counting any escape
243 /// or extended opcodes).
244 /// @param filter - The ModRMFilter that decides which ModR/M byte values
245 /// correspond to the desired instruction.
246 /// @param uid - The unique ID of the instruction.
Craig Topper4da632e2011-09-23 06:57:25 +0000247 /// @param is32bit - Instructon is only 32-bit
Craig Topper8c2358a2017-10-23 16:49:26 +0000248 /// @param noPrefix - Instruction record has no prefix.
Craig Topper6744a172011-10-04 06:30:42 +0000249 /// @param ignoresVEX_L - Instruction ignores VEX.L
Craig Topperd35a2562017-10-23 03:42:35 +0000250 /// @param ignoresVEX_W - Instruction ignores VEX.W
Craig Topper71fc42d2015-01-02 07:02:25 +0000251 /// @param AddrSize - Instructions address size 16/32/64. 0 is unspecified
Sean Callanan8ed9f512009-12-19 02:59:52 +0000252 void setTableFields(OpcodeType type,
253 InstructionContext insnContext,
254 uint8_t opcode,
255 const ModRMFilter &filter,
Craig Topper4da632e2011-09-23 06:57:25 +0000256 InstrUID uid,
Craig Topper6744a172011-10-04 06:30:42 +0000257 bool is32bit,
Craig Topper8c2358a2017-10-23 16:49:26 +0000258 bool noPrefix,
Craig Topper71fc42d2015-01-02 07:02:25 +0000259 bool ignoresVEX_L,
Craig Topper3ae8f2d2017-10-22 06:18:26 +0000260 bool ignoresVEX_W,
Craig Topper71fc42d2015-01-02 07:02:25 +0000261 unsigned AddrSize);
Craig Toppera31359a2012-07-31 05:28:41 +0000262
Sean Callanan8ed9f512009-12-19 02:59:52 +0000263 /// specForUID - Returns the instruction specifier for a given unique
264 /// instruction ID. Used when resolving collisions.
265 ///
266 /// @param uid - The unique ID of the instruction.
Craig Toppera31359a2012-07-31 05:28:41 +0000267 /// @return - A reference to the instruction specifier.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000268 InstructionSpecifier& specForUID(InstrUID uid) {
269 if (uid >= InstructionSpecifiers.size())
270 InstructionSpecifiers.resize(uid + 1);
Craig Toppera31359a2012-07-31 05:28:41 +0000271
Sean Callanan8ed9f512009-12-19 02:59:52 +0000272 return InstructionSpecifiers[uid];
273 }
Craig Toppera31359a2012-07-31 05:28:41 +0000274
Sean Callanan8ed9f512009-12-19 02:59:52 +0000275 // hasConflicts - Reports whether there were primary decode conflicts
276 // from any instructions added to the tables.
277 // @return - true if there were; false otherwise.
Craig Toppera31359a2012-07-31 05:28:41 +0000278
Sean Callanan8ed9f512009-12-19 02:59:52 +0000279 bool hasConflicts() {
280 return HasConflicts;
281 }
282};
283
284} // namespace X86Disassembler
285
286} // namespace llvm
287
288#endif