]>
Commit | Line | Data |
---|---|---|
b3e22b23 PB |
1 | /* |
2 | * Decode table flags, mostly based on Intel SDM. | |
3 | * | |
4 | * Copyright (c) 2022 Red Hat, Inc. | |
5 | * | |
6 | * Author: Paolo Bonzini <pbonzini@redhat.com> | |
7 | * | |
8 | * This library is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * | |
13 | * This library is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
20 | */ | |
21 | ||
22 | typedef enum X86OpType { | |
23 | X86_TYPE_None, | |
24 | ||
25 | X86_TYPE_A, /* Implicit */ | |
26 | X86_TYPE_B, /* VEX.vvvv selects a GPR */ | |
27 | X86_TYPE_C, /* REG in the modrm byte selects a control register */ | |
28 | X86_TYPE_D, /* REG in the modrm byte selects a debug register */ | |
29 | X86_TYPE_E, /* ALU modrm operand */ | |
30 | X86_TYPE_F, /* EFLAGS/RFLAGS */ | |
31 | X86_TYPE_G, /* REG in the modrm byte selects a GPR */ | |
32 | X86_TYPE_H, /* For AVX, VEX.vvvv selects an XMM/YMM register */ | |
33 | X86_TYPE_I, /* Immediate */ | |
34 | X86_TYPE_J, /* Relative offset for a jump */ | |
35 | X86_TYPE_L, /* The upper 4 bits of the immediate select a 128-bit register */ | |
36 | X86_TYPE_M, /* modrm byte selects a memory operand */ | |
37 | X86_TYPE_N, /* R/M in the modrm byte selects an MMX register */ | |
38 | X86_TYPE_O, /* Absolute address encoded in the instruction */ | |
39 | X86_TYPE_P, /* reg in the modrm byte selects an MMX register */ | |
40 | X86_TYPE_Q, /* MMX modrm operand */ | |
41 | X86_TYPE_R, /* R/M in the modrm byte selects a register */ | |
42 | X86_TYPE_S, /* reg selects a segment register */ | |
43 | X86_TYPE_U, /* R/M in the modrm byte selects an XMM/YMM register */ | |
44 | X86_TYPE_V, /* reg in the modrm byte selects an XMM/YMM register */ | |
45 | X86_TYPE_W, /* XMM/YMM modrm operand */ | |
46 | X86_TYPE_X, /* string source */ | |
47 | X86_TYPE_Y, /* string destination */ | |
48 | ||
49 | /* Custom */ | |
6bbeb98d | 50 | X86_TYPE_WM, /* modrm byte selects an XMM/YMM memory operand */ |
b3e22b23 PB |
51 | X86_TYPE_2op, /* 2-operand RMW instruction */ |
52 | X86_TYPE_LoBits, /* encoded in bits 0-2 of the operand + REX.B */ | |
53 | X86_TYPE_0, /* Hard-coded GPRs (RAX..RDI) */ | |
54 | X86_TYPE_1, | |
55 | X86_TYPE_2, | |
56 | X86_TYPE_3, | |
57 | X86_TYPE_4, | |
58 | X86_TYPE_5, | |
59 | X86_TYPE_6, | |
60 | X86_TYPE_7, | |
61 | X86_TYPE_ES, /* Hard-coded segment registers */ | |
62 | X86_TYPE_CS, | |
63 | X86_TYPE_SS, | |
64 | X86_TYPE_DS, | |
65 | X86_TYPE_FS, | |
66 | X86_TYPE_GS, | |
67 | } X86OpType; | |
68 | ||
69 | typedef enum X86OpSize { | |
70 | X86_SIZE_None, | |
71 | ||
72 | X86_SIZE_a, /* BOUND operand */ | |
73 | X86_SIZE_b, /* byte */ | |
74 | X86_SIZE_d, /* 32-bit */ | |
75 | X86_SIZE_dq, /* SSE/AVX 128-bit */ | |
76 | X86_SIZE_p, /* Far pointer */ | |
77 | X86_SIZE_pd, /* SSE/AVX packed double precision */ | |
78 | X86_SIZE_pi, /* MMX */ | |
79 | X86_SIZE_ps, /* SSE/AVX packed single precision */ | |
80 | X86_SIZE_q, /* 64-bit */ | |
81 | X86_SIZE_qq, /* AVX 256-bit */ | |
82 | X86_SIZE_s, /* Descriptor */ | |
83 | X86_SIZE_sd, /* SSE/AVX scalar double precision */ | |
84 | X86_SIZE_ss, /* SSE/AVX scalar single precision */ | |
85 | X86_SIZE_si, /* 32-bit GPR */ | |
86 | X86_SIZE_v, /* 16/32/64-bit, based on operand size */ | |
87 | X86_SIZE_w, /* 16-bit */ | |
88 | X86_SIZE_x, /* 128/256-bit, based on operand size */ | |
89 | X86_SIZE_y, /* 32/64-bit, based on operand size */ | |
90 | X86_SIZE_z, /* 16-bit for 16-bit operand size, else 32-bit */ | |
91 | ||
92 | /* Custom */ | |
93 | X86_SIZE_d64, | |
94 | X86_SIZE_f64, | |
95 | } X86OpSize; | |
96 | ||
caa01fad PB |
97 | typedef enum X86CPUIDFeature { |
98 | X86_FEAT_None, | |
99 | X86_FEAT_ADX, | |
100 | X86_FEAT_AES, | |
101 | X86_FEAT_AVX, | |
102 | X86_FEAT_AVX2, | |
103 | X86_FEAT_BMI1, | |
104 | X86_FEAT_BMI2, | |
105 | X86_FEAT_MOVBE, | |
106 | X86_FEAT_PCLMULQDQ, | |
107 | X86_FEAT_SSE, | |
108 | X86_FEAT_SSE2, | |
109 | X86_FEAT_SSE3, | |
110 | X86_FEAT_SSSE3, | |
111 | X86_FEAT_SSE41, | |
112 | X86_FEAT_SSE42, | |
113 | X86_FEAT_SSE4A, | |
114 | } X86CPUIDFeature; | |
115 | ||
b3e22b23 PB |
116 | /* Execution flags */ |
117 | ||
118 | typedef enum X86OpUnit { | |
119 | X86_OP_SKIP, /* not valid or managed by emission function */ | |
120 | X86_OP_SEG, /* segment selector */ | |
121 | X86_OP_CR, /* control register */ | |
122 | X86_OP_DR, /* debug register */ | |
123 | X86_OP_INT, /* loaded into/stored from s->T0/T1 */ | |
124 | X86_OP_IMM, /* immediate */ | |
125 | X86_OP_SSE, /* address in either s->ptrX or s->A0 depending on has_ea */ | |
126 | X86_OP_MMX, /* address in either s->ptrX or s->A0 depending on has_ea */ | |
127 | } X86OpUnit; | |
128 | ||
129 | typedef enum X86InsnSpecial { | |
130 | X86_SPECIAL_None, | |
131 | ||
132 | /* Always locked if it has a memory operand (XCHG) */ | |
133 | X86_SPECIAL_Locked, | |
134 | ||
135 | /* Fault outside protected mode */ | |
136 | X86_SPECIAL_ProtMode, | |
137 | ||
138 | /* | |
139 | * Register operand 0/2 is zero extended to 32 bits. Rd/Mb or Rd/Mw | |
140 | * in the manual. | |
141 | */ | |
142 | X86_SPECIAL_ZExtOp0, | |
143 | X86_SPECIAL_ZExtOp2, | |
144 | ||
145 | /* | |
146 | * MMX instruction exists with no prefix; if there is no prefix, V/H/W/U operands | |
147 | * become P/P/Q/N, and size "x" becomes "q". | |
148 | */ | |
149 | X86_SPECIAL_MMX, | |
150 | ||
151 | /* Illegal or exclusive to 64-bit mode */ | |
152 | X86_SPECIAL_i64, | |
153 | X86_SPECIAL_o64, | |
154 | } X86InsnSpecial; | |
155 | ||
20581aad PB |
156 | /* |
157 | * Special cases for instructions that operate on XMM/YMM registers. Intel | |
158 | * retconned all of them to have VEX exception classes other than 0 and 13, so | |
159 | * all these only matter for instructions that have a VEX exception class. | |
160 | * Based on tables in the "AVX and SSE Instruction Exception Specification" | |
161 | * section of the manual. | |
162 | */ | |
163 | typedef enum X86VEXSpecial { | |
164 | /* Legacy SSE instructions that allow unaligned operands */ | |
165 | X86_VEX_SSEUnaligned, | |
166 | ||
167 | /* | |
168 | * Used for instructions that distinguish the XMM operand type with an | |
169 | * instruction prefix; legacy SSE encodings will allow unaligned operands | |
170 | * for scalar operands only (identified by a REP prefix). In this case, | |
171 | * the decoding table uses "x" for the vector operands instead of specifying | |
172 | * pd/ps/sd/ss individually. | |
173 | */ | |
174 | X86_VEX_REPScalar, | |
175 | ||
176 | /* | |
177 | * VEX instructions that only support 256-bit operands with AVX2 (Table 2-17 | |
178 | * column 3). Columns 2 and 4 (instructions limited to 256- and 127-bit | |
179 | * operands respectively) are implicit in the presence of dq and qq | |
180 | * operands, and thus handled by decode_op_size. | |
181 | */ | |
182 | X86_VEX_AVX2_256, | |
183 | } X86VEXSpecial; | |
184 | ||
185 | ||
b3e22b23 PB |
186 | typedef struct X86OpEntry X86OpEntry; |
187 | typedef struct X86DecodedInsn X86DecodedInsn; | |
188 | ||
189 | /* Decode function for multibyte opcodes. */ | |
190 | typedef void (*X86DecodeFunc)(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b); | |
191 | ||
192 | /* Code generation function. */ | |
193 | typedef void (*X86GenFunc)(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode); | |
194 | ||
195 | struct X86OpEntry { | |
196 | /* Based on the is_decode flags. */ | |
197 | union { | |
198 | X86GenFunc gen; | |
199 | X86DecodeFunc decode; | |
200 | }; | |
201 | /* op0 is always written, op1 and op2 are always read. */ | |
202 | X86OpType op0:8; | |
203 | X86OpSize s0:8; | |
204 | X86OpType op1:8; | |
205 | X86OpSize s1:8; | |
206 | X86OpType op2:8; | |
207 | X86OpSize s2:8; | |
208 | /* Must be I and b respectively if present. */ | |
209 | X86OpType op3:8; | |
210 | X86OpSize s3:8; | |
211 | ||
212 | X86InsnSpecial special:8; | |
caa01fad | 213 | X86CPUIDFeature cpuid:8; |
20581aad PB |
214 | unsigned vex_class:8; |
215 | X86VEXSpecial vex_special:8; | |
55a33286 | 216 | uint16_t valid_prefix:16; |
b3e22b23 PB |
217 | bool is_decode:1; |
218 | }; | |
219 | ||
220 | typedef struct X86DecodedOp { | |
221 | int8_t n; | |
222 | MemOp ot; /* For b/c/d/p/s/q/v/w/y/z */ | |
223 | X86OpUnit unit; | |
224 | bool has_ea; | |
6ba13999 PB |
225 | int offset; /* For MMX and SSE */ |
226 | ||
227 | /* | |
228 | * This field is used internally by macros OP0_PTR/OP1_PTR/OP2_PTR, | |
229 | * do not access directly! | |
230 | */ | |
231 | TCGv_ptr v_ptr; | |
b3e22b23 PB |
232 | } X86DecodedOp; |
233 | ||
234 | struct X86DecodedInsn { | |
235 | X86OpEntry e; | |
236 | X86DecodedOp op[3]; | |
237 | target_ulong immediate; | |
238 | AddressParts mem; | |
239 | ||
240 | uint8_t b; | |
241 | }; | |
242 |