blob: c4d34ee6c80c9b6b7567cb9a40f581d39c153ba3 [file] [log] [blame]
Sean Callanan8ed9f512009-12-19 02:59:52 +00001//===- X86RecognizableInstr.h - Disassembler instruction spec ----*- 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 a single recognizable instruction.
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_X86RECOGNIZABLEINSTR_H
18#define LLVM_UTILS_TABLEGEN_X86RECOGNIZABLEINSTR_H
Sean Callanan8ed9f512009-12-19 02:59:52 +000019
Sean Callanan8ed9f512009-12-19 02:59:52 +000020#include "CodeGenTarget.h"
Chandler Carruth4ffd89f2012-12-04 10:37:14 +000021#include "X86DisassemblerTables.h"
Chandler Carruth4ffd89f2012-12-04 10:37:14 +000022#include "llvm/Support/DataTypes.h"
23#include "llvm/TableGen/Record.h"
Sean Callanan8ed9f512009-12-19 02:59:52 +000024
25namespace llvm {
26
Ayman Musa059f03a2017-05-11 11:51:12 +000027#define X86_INSTR_MRM_MAPPING \
28 MAP(C0, 64) \
29 MAP(C1, 65) \
30 MAP(C2, 66) \
31 MAP(C3, 67) \
32 MAP(C4, 68) \
33 MAP(C5, 69) \
34 MAP(C6, 70) \
35 MAP(C7, 71) \
36 MAP(C8, 72) \
37 MAP(C9, 73) \
38 MAP(CA, 74) \
39 MAP(CB, 75) \
40 MAP(CC, 76) \
41 MAP(CD, 77) \
42 MAP(CE, 78) \
43 MAP(CF, 79) \
44 MAP(D0, 80) \
45 MAP(D1, 81) \
46 MAP(D2, 82) \
47 MAP(D3, 83) \
48 MAP(D4, 84) \
49 MAP(D5, 85) \
50 MAP(D6, 86) \
51 MAP(D7, 87) \
52 MAP(D8, 88) \
53 MAP(D9, 89) \
54 MAP(DA, 90) \
55 MAP(DB, 91) \
56 MAP(DC, 92) \
57 MAP(DD, 93) \
58 MAP(DE, 94) \
59 MAP(DF, 95) \
60 MAP(E0, 96) \
61 MAP(E1, 97) \
62 MAP(E2, 98) \
63 MAP(E3, 99) \
64 MAP(E4, 100) \
65 MAP(E5, 101) \
66 MAP(E6, 102) \
67 MAP(E7, 103) \
68 MAP(E8, 104) \
69 MAP(E9, 105) \
70 MAP(EA, 106) \
71 MAP(EB, 107) \
72 MAP(EC, 108) \
73 MAP(ED, 109) \
74 MAP(EE, 110) \
75 MAP(EF, 111) \
76 MAP(F0, 112) \
77 MAP(F1, 113) \
78 MAP(F2, 114) \
79 MAP(F3, 115) \
80 MAP(F4, 116) \
81 MAP(F5, 117) \
82 MAP(F6, 118) \
83 MAP(F7, 119) \
84 MAP(F8, 120) \
85 MAP(F9, 121) \
86 MAP(FA, 122) \
87 MAP(FB, 123) \
88 MAP(FC, 124) \
89 MAP(FD, 125) \
90 MAP(FE, 126) \
91 MAP(FF, 127)
92
93// A clone of X86 since we can't depend on something that is generated.
94namespace X86Local {
95 enum {
96 Pseudo = 0,
97 RawFrm = 1,
98 AddRegFrm = 2,
99 RawFrmMemOffs = 3,
100 RawFrmSrc = 4,
101 RawFrmDst = 5,
102 RawFrmDstSrc = 6,
103 RawFrmImm8 = 7,
104 RawFrmImm16 = 8,
105 MRMDestMem = 32,
106 MRMSrcMem = 33,
107 MRMSrcMem4VOp3 = 34,
108 MRMSrcMemOp4 = 35,
109 MRMXm = 39,
110 MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43,
111 MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47,
112 MRMDestReg = 48,
113 MRMSrcReg = 49,
114 MRMSrcReg4VOp3 = 50,
115 MRMSrcRegOp4 = 51,
116 MRMXr = 55,
117 MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59,
118 MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63,
119#define MAP(from, to) MRM_##from = to,
120 X86_INSTR_MRM_MAPPING
121#undef MAP
122 };
123
124 enum {
Craig Topperf0c0da82018-03-24 06:04:12 +0000125 OB = 0, TB = 1, T8 = 2, TA = 3, XOP8 = 4, XOP9 = 5, XOPA = 6, ThreeDNow = 7
Ayman Musa059f03a2017-05-11 11:51:12 +0000126 };
127
128 enum {
Craig Topper16fa9062018-04-03 06:37:04 +0000129 PD = 1, XS = 2, XD = 3, PS = 4
Ayman Musa059f03a2017-05-11 11:51:12 +0000130 };
131
132 enum {
133 VEX = 1, XOP = 2, EVEX = 3
134 };
135
136 enum {
137 OpSize16 = 1, OpSize32 = 2
138 };
139
140 enum {
141 AdSize16 = 1, AdSize32 = 2, AdSize64 = 3
142 };
143
144 enum {
Craig Topper023b4072018-06-19 04:24:42 +0000145 VEX_W0 = 0, VEX_W1 = 1, VEX_WIG = 2, VEX_W1X = 3
Ayman Musa059f03a2017-05-11 11:51:12 +0000146 };
147}
148
Sean Callanan8ed9f512009-12-19 02:59:52 +0000149namespace X86Disassembler {
150
151/// RecognizableInstr - Encapsulates all information required to decode a single
152/// instruction, as extracted from the LLVM instruction tables. Has methods
153/// to interpret the information available in the LLVM tables, and to emit the
154/// instruction into DisassemblerTables.
155class RecognizableInstr {
156private:
157 /// The opcode of the instruction, as used in an MCInst
158 InstrUID UID;
159 /// The record from the .td files corresponding to this instruction
160 const Record* Rec;
Craig Topperf0b161d2014-01-31 08:47:06 +0000161 /// The OpPrefix field from the record
162 uint8_t OpPrefix;
163 /// The OpMap field from the record
164 uint8_t OpMap;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000165 /// The opcode field from the record; this is the opcode used in the Intel
166 /// encoding and therefore distinct from the UID
167 uint8_t Opcode;
168 /// The form field from the record
169 uint8_t Form;
Craig Topper1415ca12014-02-02 07:08:01 +0000170 // The encoding field from the record
171 uint8_t Encoding;
Craig Topper6b6dfa52014-02-02 09:25:09 +0000172 /// The OpSize field from the record
173 uint8_t OpSize;
Craig Topper3bc43972014-12-24 06:05:22 +0000174 /// The AdSize field from the record
175 uint8_t AdSize;
Sean Callanan8ed9f512009-12-19 02:59:52 +0000176 /// The hasREX_WPrefix field from the record
177 bool HasREX_WPrefix;
Craig Topper1415ca12014-02-02 07:08:01 +0000178 /// The hasVEX_4V field from the record
179 bool HasVEX_4V;
Ayman Musa5cb22782017-02-20 08:27:54 +0000180 /// The VEX_WPrefix field from the record
181 uint8_t VEX_WPrefix;
Sean Callanana21e2ea2011-03-15 01:23:15 +0000182 /// Inferred from the operands; indicates whether the L bit in the VEX prefix is set
183 bool HasVEX_LPrefix;
Craig Toppere6a3a292011-12-30 05:20:36 +0000184 /// The ignoreVEX_L field from the record
Craig Topper6744a172011-10-04 06:30:42 +0000185 bool IgnoresVEX_L;
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000186 /// The hasEVEX_L2Prefix field from the record
187 bool HasEVEX_L2Prefix;
188 /// The hasEVEX_K field from the record
189 bool HasEVEX_K;
Elena Demikhovsky633f98b2013-11-03 13:46:31 +0000190 /// The hasEVEX_KZ field from the record
191 bool HasEVEX_KZ;
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000192 /// The hasEVEX_B field from the record
193 bool HasEVEX_B;
Craig Topper0f7dce52017-10-23 02:26:24 +0000194 /// Indicates that the instruction uses the L and L' fields for RC.
195 bool EncodeRC;
Craig Topper527f1322014-01-05 04:17:28 +0000196 /// The isCodeGenOnly field from the record
Sean Callanan8ed9f512009-12-19 02:59:52 +0000197 bool IsCodeGenOnly;
Craig Topper527f1322014-01-05 04:17:28 +0000198 /// The ForceDisassemble field from the record
199 bool ForceDisassemble;
Adam Nemet6ae29412014-07-17 17:04:56 +0000200 // The CD8_Scale field from the record
201 uint8_t CD8_Scale;
Craig Topper4da632e2011-09-23 06:57:25 +0000202 // Whether the instruction has the predicate "In64BitMode"
Eli Friedman71052592011-07-16 02:41:28 +0000203 bool Is64Bit;
Craig Topper4da632e2011-09-23 06:57:25 +0000204 // Whether the instruction has the predicate "In32BitMode"
205 bool Is32Bit;
Craig Topper17730842011-10-16 03:51:13 +0000206
Sean Callanan8ed9f512009-12-19 02:59:52 +0000207 /// The instruction name as listed in the tables
208 std::string Name;
Craig Topper38e6f732014-01-15 05:02:02 +0000209
Sean Callanan8ed9f512009-12-19 02:59:52 +0000210 /// Indicates whether the instruction should be emitted into the decode
211 /// tables; regardless, it will be emitted into the instruction info table
212 bool ShouldBeEmitted;
Rafael Auler048f3922018-02-15 21:20:31 +0000213
Sean Callanan8ed9f512009-12-19 02:59:52 +0000214 /// The operands of the instruction, as listed in the CodeGenInstruction.
215 /// They are not one-to-one with operands listed in the MCInst; for example,
216 /// memory operands expand to 5 operands in the MCInst
Chris Lattnerc240bb02010-11-01 04:03:32 +0000217 const std::vector<CGIOperandList::OperandInfo>* Operands;
Rafael Auler048f3922018-02-15 21:20:31 +0000218
Sean Callanan8ed9f512009-12-19 02:59:52 +0000219 /// The description of the instruction that is emitted into the instruction
220 /// info table
221 InstructionSpecifier* Spec;
222
223 /// insnContext - Returns the primary context in which the instruction is
224 /// valid.
225 ///
226 /// @return - The context in which the instruction is valid.
227 InstructionContext insnContext() const;
Sean Callanana21e2ea2011-03-15 01:23:15 +0000228
Sean Callanan8ed9f512009-12-19 02:59:52 +0000229 /// typeFromString - Translates an operand type from the string provided in
230 /// the LLVM tables to an OperandType for use in the operand specifier.
231 ///
232 /// @param s - The string, as extracted by calling Rec->getName()
233 /// on a CodeGenInstruction::OperandInfo.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000234 /// @param hasREX_WPrefix - Indicates whether the instruction has a REX.W
235 /// prefix. If it does, 32-bit register operands stay
236 /// 32-bit regardless of the operand size.
Craig Topper6b6dfa52014-02-02 09:25:09 +0000237 /// @param OpSize Indicates the operand size of the instruction.
238 /// If register size does not match OpSize, then
239 /// register sizes keep their size.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000240 /// @return - The operand's type.
Craig Topper6b6dfa52014-02-02 09:25:09 +0000241 static OperandType typeFromString(const std::string& s,
242 bool hasREX_WPrefix, uint8_t OpSize);
243
Sean Callanan8ed9f512009-12-19 02:59:52 +0000244 /// immediateEncodingFromString - Translates an immediate encoding from the
245 /// string provided in the LLVM tables to an OperandEncoding for use in
246 /// the operand specifier.
247 ///
Craig Topper6b6dfa52014-02-02 09:25:09 +0000248 /// @param s - See typeFromString().
249 /// @param OpSize - Indicates whether this is an OpSize16 instruction.
250 /// If it is not, then 16-bit immediate operands stay 16-bit.
251 /// @return - The operand's encoding.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000252 static OperandEncoding immediateEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000253 uint8_t OpSize);
254
Sean Callanan8ed9f512009-12-19 02:59:52 +0000255 /// rmRegisterEncodingFromString - Like immediateEncodingFromString, but
256 /// handles operands that are in the REG field of the ModR/M byte.
257 static OperandEncoding rmRegisterEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000258 uint8_t OpSize);
259
Sean Callanan8ed9f512009-12-19 02:59:52 +0000260 /// rmRegisterEncodingFromString - Like immediateEncodingFromString, but
261 /// handles operands that are in the REG field of the ModR/M byte.
262 static OperandEncoding roRegisterEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000263 uint8_t OpSize);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000264 static OperandEncoding memoryEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000265 uint8_t OpSize);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000266 static OperandEncoding relocationEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000267 uint8_t OpSize);
Sean Callanan8ed9f512009-12-19 02:59:52 +0000268 static OperandEncoding opcodeModifierEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000269 uint8_t OpSize);
Sean Callanana21e2ea2011-03-15 01:23:15 +0000270 static OperandEncoding vvvvRegisterEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000271 uint8_t OpSize);
Elena Demikhovskyc18f4ef2013-07-28 08:28:38 +0000272 static OperandEncoding writemaskRegisterEncodingFromString(const std::string &s,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000273 uint8_t OpSize);
274
Adrian Prantl26b584c2018-05-01 15:54:18 +0000275 /// Adjust the encoding type for an operand based on the instruction.
Adam Nemet6ae29412014-07-17 17:04:56 +0000276 void adjustOperandEncoding(OperandEncoding &encoding);
277
Sean Callanan8ed9f512009-12-19 02:59:52 +0000278 /// handleOperand - Converts a single operand from the LLVM table format to
279 /// the emitted table format, handling any duplicate operands it encounters
280 /// and then one non-duplicate.
281 ///
282 /// @param optional - Determines whether to assert that the
283 /// operand exists.
284 /// @param operandIndex - The index into the generated operand table.
285 /// Incremented by this function one or more
Rafael Auler048f3922018-02-15 21:20:31 +0000286 /// times to reflect possible duplicate
Sean Callanan8ed9f512009-12-19 02:59:52 +0000287 /// operands).
288 /// @param physicalOperandIndex - The index of the current operand into the
289 /// set of non-duplicate ('physical') operands.
290 /// Incremented by this function once.
291 /// @param numPhysicalOperands - The number of non-duplicate operands in the
292 /// instructions.
293 /// @param operandMapping - The operand mapping, which has an entry for
294 /// each operand that indicates whether it is a
295 /// duplicate, and of what.
296 void handleOperand(bool optional,
297 unsigned &operandIndex,
298 unsigned &physicalOperandIndex,
Craig Topper69dced02016-02-16 04:24:56 +0000299 unsigned numPhysicalOperands,
Craig Topper5aba78b2012-07-12 06:52:41 +0000300 const unsigned *operandMapping,
Sean Callanan8ed9f512009-12-19 02:59:52 +0000301 OperandEncoding (*encodingFromString)
302 (const std::string&,
Craig Topper6b6dfa52014-02-02 09:25:09 +0000303 uint8_t OpSize));
304
Sean Callanan8ed9f512009-12-19 02:59:52 +0000305 /// shouldBeEmitted - Returns the shouldBeEmitted field. Although filter()
306 /// filters out many instructions, at various points in decoding we
307 /// determine that the instruction should not actually be decodable. In
308 /// particular, MMX MOV instructions aren't emitted, but they're only
309 /// identified during operand parsing.
310 ///
311 /// @return - true if at this point we believe the instruction should be
312 /// emitted; false if not. This will return false if filter() returns false
313 /// once emitInstructionSpecifier() has been called.
314 bool shouldBeEmitted() const {
315 return ShouldBeEmitted;
316 }
Rafael Auler048f3922018-02-15 21:20:31 +0000317
Sean Callanan8ed9f512009-12-19 02:59:52 +0000318 /// emitInstructionSpecifier - Loads the instruction specifier for the current
319 /// instruction into a DisassemblerTables.
320 ///
Craig Toppere61c70a2014-01-02 03:58:45 +0000321 void emitInstructionSpecifier();
Rafael Auler048f3922018-02-15 21:20:31 +0000322
Sean Callanan8ed9f512009-12-19 02:59:52 +0000323 /// emitDecodePath - Populates the proper fields in the decode tables
324 /// corresponding to the decode paths for this instruction.
325 ///
Dmitri Gribenko2d9eb722012-09-13 12:34:29 +0000326 /// \param tables The DisassemblerTables to populate with the decode
Sean Callanan8ed9f512009-12-19 02:59:52 +0000327 /// decode information for the current instruction.
328 void emitDecodePath(DisassemblerTables &tables) const;
329
330 /// Constructor - Initializes a RecognizableInstr with the appropriate fields
331 /// from a CodeGenInstruction.
332 ///
Dmitri Gribenko2d9eb722012-09-13 12:34:29 +0000333 /// \param tables The DisassemblerTables that the specifier will be added to.
334 /// \param insn The CodeGenInstruction to extract information from.
335 /// \param uid The unique ID of the current instruction.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000336 RecognizableInstr(DisassemblerTables &tables,
337 const CodeGenInstruction &insn,
338 InstrUID uid);
339public:
340 /// processInstr - Accepts a CodeGenInstruction and loads decode information
341 /// for it into a DisassemblerTables if appropriate.
342 ///
Dmitri Gribenko2d9eb722012-09-13 12:34:29 +0000343 /// \param tables The DiassemblerTables to be populated with decode
Sean Callanan8ed9f512009-12-19 02:59:52 +0000344 /// information.
Dmitri Gribenko2d9eb722012-09-13 12:34:29 +0000345 /// \param insn The CodeGenInstruction to be used as a source for this
Sean Callanan8ed9f512009-12-19 02:59:52 +0000346 /// information.
Dmitri Gribenko2d9eb722012-09-13 12:34:29 +0000347 /// \param uid The unique ID of the instruction.
Sean Callanan8ed9f512009-12-19 02:59:52 +0000348 static void processInstr(DisassemblerTables &tables,
349 const CodeGenInstruction &insn,
350 InstrUID uid);
351};
Rafael Auler048f3922018-02-15 21:20:31 +0000352
Sean Callanan8ed9f512009-12-19 02:59:52 +0000353} // namespace X86Disassembler
354
355} // namespace llvm
356
357#endif