]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * New-style decoder for i386 instructions | |
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 | /* | |
23 | * The decoder is mostly based on tables copied from the Intel SDM. As | |
24 | * a result, most operand load and writeback is done entirely in common | |
25 | * table-driven code using the same operand type (X86_TYPE_*) and | |
26 | * size (X86_SIZE_*) codes used in the manual. | |
27 | * | |
28 | * The main difference is that the V, U and W types are extended to | |
29 | * cover MMX as well; if an instruction is like | |
30 | * | |
31 | * por Pq, Qq | |
32 | * 66 por Vx, Hx, Wx | |
33 | * | |
34 | * only the second row is included and the instruction is marked as a | |
35 | * valid MMX instruction. The MMX flag directs the decoder to rewrite | |
36 | * the V/U/H/W types to P/N/P/Q if there is no prefix, as well as changing | |
37 | * "x" to "q" if there is no prefix. | |
38 | * | |
39 | * In addition, the ss/ps/sd/pd types are sometimes mushed together as "x" | |
40 | * if the difference is expressed via prefixes. Individual instructions | |
41 | * are separated by prefix in the generator functions. | |
42 | * | |
43 | * There are a couple cases in which instructions (e.g. MOVD) write the | |
44 | * whole XMM or MM register but are established incorrectly in the manual | |
45 | * as "d" or "q". These have to be fixed for the decoder to work correctly. | |
46 | */ | |
47 | ||
48 | #define X86_OP_NONE { 0 }, | |
49 | ||
50 | #define X86_OP_GROUP3(op, op0_, s0_, op1_, s1_, op2_, s2_, ...) { \ | |
51 | .decode = glue(decode_, op), \ | |
52 | .op0 = glue(X86_TYPE_, op0_), \ | |
53 | .s0 = glue(X86_SIZE_, s0_), \ | |
54 | .op1 = glue(X86_TYPE_, op1_), \ | |
55 | .s1 = glue(X86_SIZE_, s1_), \ | |
56 | .op2 = glue(X86_TYPE_, op2_), \ | |
57 | .s2 = glue(X86_SIZE_, s2_), \ | |
58 | .is_decode = true, \ | |
59 | ## __VA_ARGS__ \ | |
60 | } | |
61 | ||
62 | #define X86_OP_GROUP2(op, op0, s0, op1, s1, ...) \ | |
63 | X86_OP_GROUP3(op, op0, s0, 2op, s0, op1, s1, ## __VA_ARGS__) | |
64 | #define X86_OP_GROUP0(op, ...) \ | |
65 | X86_OP_GROUP3(op, None, None, None, None, None, None, ## __VA_ARGS__) | |
66 | ||
67 | #define X86_OP_ENTRY3(op, op0_, s0_, op1_, s1_, op2_, s2_, ...) { \ | |
68 | .gen = glue(gen_, op), \ | |
69 | .op0 = glue(X86_TYPE_, op0_), \ | |
70 | .s0 = glue(X86_SIZE_, s0_), \ | |
71 | .op1 = glue(X86_TYPE_, op1_), \ | |
72 | .s1 = glue(X86_SIZE_, s1_), \ | |
73 | .op2 = glue(X86_TYPE_, op2_), \ | |
74 | .s2 = glue(X86_SIZE_, s2_), \ | |
75 | ## __VA_ARGS__ \ | |
76 | } | |
77 | ||
78 | #define X86_OP_ENTRY4(op, op0_, s0_, op1_, s1_, op2_, s2_, ...) \ | |
79 | X86_OP_ENTRY3(op, op0_, s0_, op1_, s1_, op2_, s2_, \ | |
80 | .op3 = X86_TYPE_I, .s3 = X86_SIZE_b, \ | |
81 | ## __VA_ARGS__) | |
82 | ||
83 | #define X86_OP_ENTRY2(op, op0, s0, op1, s1, ...) \ | |
84 | X86_OP_ENTRY3(op, op0, s0, 2op, s0, op1, s1, ## __VA_ARGS__) | |
85 | #define X86_OP_ENTRY0(op, ...) \ | |
86 | X86_OP_ENTRY3(op, None, None, None, None, None, None, ## __VA_ARGS__) | |
87 | ||
88 | #define cpuid(feat) .cpuid = X86_FEAT_##feat, | |
89 | #define i64 .special = X86_SPECIAL_i64, | |
90 | #define o64 .special = X86_SPECIAL_o64, | |
91 | #define xchg .special = X86_SPECIAL_Locked, | |
92 | #define mmx .special = X86_SPECIAL_MMX, | |
93 | #define zext0 .special = X86_SPECIAL_ZExtOp0, | |
94 | #define zext2 .special = X86_SPECIAL_ZExtOp2, | |
95 | ||
96 | static uint8_t get_modrm(DisasContext *s, CPUX86State *env) | |
97 | { | |
98 | if (!s->has_modrm) { | |
99 | s->modrm = x86_ldub_code(env, s); | |
100 | s->has_modrm = true; | |
101 | } | |
102 | return s->modrm; | |
103 | } | |
104 | ||
105 | static const X86OpEntry opcodes_0F38_00toEF[240] = { | |
106 | }; | |
107 | ||
108 | /* five rows for no prefix, 66, F3, F2, 66+F2 */ | |
109 | static const X86OpEntry opcodes_0F38_F0toFF[16][5] = { | |
110 | }; | |
111 | ||
112 | static void decode_0F38(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) | |
113 | { | |
114 | *b = x86_ldub_code(env, s); | |
115 | if (*b < 0xf0) { | |
116 | *entry = opcodes_0F38_00toEF[*b]; | |
117 | } else { | |
118 | int row = 0; | |
119 | if (s->prefix & PREFIX_REPZ) { | |
120 | /* The REPZ (F3) prefix has priority over 66 */ | |
121 | row = 2; | |
122 | } else { | |
123 | row += s->prefix & PREFIX_REPNZ ? 3 : 0; | |
124 | row += s->prefix & PREFIX_DATA ? 1 : 0; | |
125 | } | |
126 | *entry = opcodes_0F38_F0toFF[*b & 15][row]; | |
127 | } | |
128 | } | |
129 | ||
130 | static const X86OpEntry opcodes_0F3A[256] = { | |
131 | }; | |
132 | ||
133 | static void decode_0F3A(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) | |
134 | { | |
135 | *b = x86_ldub_code(env, s); | |
136 | *entry = opcodes_0F3A[*b]; | |
137 | } | |
138 | ||
139 | static const X86OpEntry opcodes_0F[256] = { | |
140 | [0x38] = X86_OP_GROUP0(0F38), | |
141 | [0x3a] = X86_OP_GROUP0(0F3A), | |
142 | }; | |
143 | ||
144 | static void do_decode_0F(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) | |
145 | { | |
146 | *entry = opcodes_0F[*b]; | |
147 | } | |
148 | ||
149 | static void decode_0F(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) | |
150 | { | |
151 | *b = x86_ldub_code(env, s); | |
152 | do_decode_0F(s, env, entry, b); | |
153 | } | |
154 | ||
155 | static const X86OpEntry opcodes_root[256] = { | |
156 | [0x0F] = X86_OP_GROUP0(0F), | |
157 | }; | |
158 | ||
159 | #undef mmx | |
160 | ||
161 | /* | |
162 | * Decode the fixed part of the opcode and place the last | |
163 | * in b. | |
164 | */ | |
165 | static void decode_root(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b) | |
166 | { | |
167 | *entry = opcodes_root[*b]; | |
168 | } | |
169 | ||
170 | ||
171 | static int decode_modrm(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode, | |
172 | X86DecodedOp *op, X86OpType type) | |
173 | { | |
174 | int modrm = get_modrm(s, env); | |
175 | if ((modrm >> 6) == 3) { | |
176 | if (s->prefix & PREFIX_LOCK) { | |
177 | decode->e.gen = gen_illegal; | |
178 | return 0xff; | |
179 | } | |
180 | op->n = (modrm & 7); | |
181 | if (type != X86_TYPE_Q && type != X86_TYPE_N) { | |
182 | op->n |= REX_B(s); | |
183 | } | |
184 | } else { | |
185 | op->has_ea = true; | |
186 | op->n = -1; | |
187 | decode->mem = gen_lea_modrm_0(env, s, get_modrm(s, env)); | |
188 | } | |
189 | return modrm; | |
190 | } | |
191 | ||
192 | static bool decode_op_size(DisasContext *s, X86OpEntry *e, X86OpSize size, MemOp *ot) | |
193 | { | |
194 | switch (size) { | |
195 | case X86_SIZE_b: /* byte */ | |
196 | *ot = MO_8; | |
197 | return true; | |
198 | ||
199 | case X86_SIZE_d: /* 32-bit */ | |
200 | case X86_SIZE_ss: /* SSE/AVX scalar single precision */ | |
201 | *ot = MO_32; | |
202 | return true; | |
203 | ||
204 | case X86_SIZE_p: /* Far pointer, return offset size */ | |
205 | case X86_SIZE_s: /* Descriptor, return offset size */ | |
206 | case X86_SIZE_v: /* 16/32/64-bit, based on operand size */ | |
207 | *ot = s->dflag; | |
208 | return true; | |
209 | ||
210 | case X86_SIZE_pi: /* MMX */ | |
211 | case X86_SIZE_q: /* 64-bit */ | |
212 | case X86_SIZE_sd: /* SSE/AVX scalar double precision */ | |
213 | *ot = MO_64; | |
214 | return true; | |
215 | ||
216 | case X86_SIZE_w: /* 16-bit */ | |
217 | *ot = MO_16; | |
218 | return true; | |
219 | ||
220 | case X86_SIZE_y: /* 32/64-bit, based on operand size */ | |
221 | *ot = s->dflag == MO_16 ? MO_32 : s->dflag; | |
222 | return true; | |
223 | ||
224 | case X86_SIZE_z: /* 16-bit for 16-bit operand size, else 32-bit */ | |
225 | *ot = s->dflag == MO_16 ? MO_16 : MO_32; | |
226 | return true; | |
227 | ||
228 | case X86_SIZE_dq: /* SSE/AVX 128-bit */ | |
229 | if (e->special == X86_SPECIAL_MMX && | |
230 | !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { | |
231 | *ot = MO_64; | |
232 | return true; | |
233 | } | |
234 | if (s->vex_l && e->s0 != X86_SIZE_qq && e->s1 != X86_SIZE_qq) { | |
235 | return false; | |
236 | } | |
237 | *ot = MO_128; | |
238 | return true; | |
239 | ||
240 | case X86_SIZE_qq: /* AVX 256-bit */ | |
241 | if (!s->vex_l) { | |
242 | return false; | |
243 | } | |
244 | *ot = MO_256; | |
245 | return true; | |
246 | ||
247 | case X86_SIZE_x: /* 128/256-bit, based on operand size */ | |
248 | if (e->special == X86_SPECIAL_MMX && | |
249 | !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { | |
250 | *ot = MO_64; | |
251 | return true; | |
252 | } | |
253 | /* fall through */ | |
254 | case X86_SIZE_ps: /* SSE/AVX packed single precision */ | |
255 | case X86_SIZE_pd: /* SSE/AVX packed double precision */ | |
256 | *ot = s->vex_l ? MO_256 : MO_128; | |
257 | return true; | |
258 | ||
259 | case X86_SIZE_d64: /* Default to 64-bit in 64-bit mode */ | |
260 | *ot = CODE64(s) && s->dflag == MO_32 ? MO_64 : s->dflag; | |
261 | return true; | |
262 | ||
263 | case X86_SIZE_f64: /* Ignore size override prefix in 64-bit mode */ | |
264 | *ot = CODE64(s) ? MO_64 : s->dflag; | |
265 | return true; | |
266 | ||
267 | default: | |
268 | *ot = -1; | |
269 | return true; | |
270 | } | |
271 | } | |
272 | ||
273 | static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode, | |
274 | X86DecodedOp *op, X86OpType type, int b) | |
275 | { | |
276 | int modrm; | |
277 | ||
278 | switch (type) { | |
279 | case X86_TYPE_None: /* Implicit or absent */ | |
280 | case X86_TYPE_A: /* Implicit */ | |
281 | case X86_TYPE_F: /* EFLAGS/RFLAGS */ | |
282 | break; | |
283 | ||
284 | case X86_TYPE_B: /* VEX.vvvv selects a GPR */ | |
285 | op->unit = X86_OP_INT; | |
286 | op->n = s->vex_v; | |
287 | break; | |
288 | ||
289 | case X86_TYPE_C: /* REG in the modrm byte selects a control register */ | |
290 | op->unit = X86_OP_CR; | |
291 | goto get_reg; | |
292 | ||
293 | case X86_TYPE_D: /* REG in the modrm byte selects a debug register */ | |
294 | op->unit = X86_OP_DR; | |
295 | goto get_reg; | |
296 | ||
297 | case X86_TYPE_G: /* REG in the modrm byte selects a GPR */ | |
298 | op->unit = X86_OP_INT; | |
299 | goto get_reg; | |
300 | ||
301 | case X86_TYPE_S: /* reg selects a segment register */ | |
302 | op->unit = X86_OP_SEG; | |
303 | goto get_reg; | |
304 | ||
305 | case X86_TYPE_P: | |
306 | op->unit = X86_OP_MMX; | |
307 | goto get_reg; | |
308 | ||
309 | case X86_TYPE_V: /* reg in the modrm byte selects an XMM/YMM register */ | |
310 | if (decode->e.special == X86_SPECIAL_MMX && | |
311 | !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { | |
312 | op->unit = X86_OP_MMX; | |
313 | } else { | |
314 | op->unit = X86_OP_SSE; | |
315 | } | |
316 | get_reg: | |
317 | op->n = ((get_modrm(s, env) >> 3) & 7) | REX_R(s); | |
318 | break; | |
319 | ||
320 | case X86_TYPE_E: /* ALU modrm operand */ | |
321 | op->unit = X86_OP_INT; | |
322 | goto get_modrm; | |
323 | ||
324 | case X86_TYPE_Q: /* MMX modrm operand */ | |
325 | op->unit = X86_OP_MMX; | |
326 | goto get_modrm; | |
327 | ||
328 | case X86_TYPE_W: /* XMM/YMM modrm operand */ | |
329 | if (decode->e.special == X86_SPECIAL_MMX && | |
330 | !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { | |
331 | op->unit = X86_OP_MMX; | |
332 | } else { | |
333 | op->unit = X86_OP_SSE; | |
334 | } | |
335 | goto get_modrm; | |
336 | ||
337 | case X86_TYPE_N: /* R/M in the modrm byte selects an MMX register */ | |
338 | op->unit = X86_OP_MMX; | |
339 | goto get_modrm_reg; | |
340 | ||
341 | case X86_TYPE_U: /* R/M in the modrm byte selects an XMM/YMM register */ | |
342 | if (decode->e.special == X86_SPECIAL_MMX && | |
343 | !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { | |
344 | op->unit = X86_OP_MMX; | |
345 | } else { | |
346 | op->unit = X86_OP_SSE; | |
347 | } | |
348 | goto get_modrm_reg; | |
349 | ||
350 | case X86_TYPE_R: /* R/M in the modrm byte selects a register */ | |
351 | op->unit = X86_OP_INT; | |
352 | get_modrm_reg: | |
353 | modrm = get_modrm(s, env); | |
354 | if ((modrm >> 6) != 3) { | |
355 | return false; | |
356 | } | |
357 | goto get_modrm; | |
358 | ||
359 | case X86_TYPE_M: /* modrm byte selects a memory operand */ | |
360 | modrm = get_modrm(s, env); | |
361 | if ((modrm >> 6) == 3) { | |
362 | return false; | |
363 | } | |
364 | get_modrm: | |
365 | decode_modrm(s, env, decode, op, type); | |
366 | break; | |
367 | ||
368 | case X86_TYPE_O: /* Absolute address encoded in the instruction */ | |
369 | op->unit = X86_OP_INT; | |
370 | op->has_ea = true; | |
371 | op->n = -1; | |
372 | decode->mem = (AddressParts) { | |
373 | .def_seg = R_DS, | |
374 | .base = -1, | |
375 | .index = -1, | |
376 | .disp = insn_get_addr(env, s, s->aflag) | |
377 | }; | |
378 | break; | |
379 | ||
380 | case X86_TYPE_H: /* For AVX, VEX.vvvv selects an XMM/YMM register */ | |
381 | if ((s->prefix & PREFIX_VEX)) { | |
382 | op->unit = X86_OP_SSE; | |
383 | op->n = s->vex_v; | |
384 | break; | |
385 | } | |
386 | if (op == &decode->op[0]) { | |
387 | /* shifts place the destination in VEX.vvvv, use modrm */ | |
388 | return decode_op(s, env, decode, op, decode->e.op1, b); | |
389 | } else { | |
390 | return decode_op(s, env, decode, op, decode->e.op0, b); | |
391 | } | |
392 | ||
393 | case X86_TYPE_I: /* Immediate */ | |
394 | op->unit = X86_OP_IMM; | |
395 | decode->immediate = insn_get_signed(env, s, op->ot); | |
396 | break; | |
397 | ||
398 | case X86_TYPE_J: /* Relative offset for a jump */ | |
399 | op->unit = X86_OP_IMM; | |
400 | decode->immediate = insn_get_signed(env, s, op->ot); | |
401 | decode->immediate += s->pc - s->cs_base; | |
402 | if (s->dflag == MO_16) { | |
403 | decode->immediate &= 0xffff; | |
404 | } else if (!CODE64(s)) { | |
405 | decode->immediate &= 0xffffffffu; | |
406 | } | |
407 | break; | |
408 | ||
409 | case X86_TYPE_L: /* The upper 4 bits of the immediate select a 128-bit register */ | |
410 | op->n = insn_get(env, s, op->ot) >> 4; | |
411 | break; | |
412 | ||
413 | case X86_TYPE_X: /* string source */ | |
414 | op->n = -1; | |
415 | decode->mem = (AddressParts) { | |
416 | .def_seg = R_DS, | |
417 | .base = R_ESI, | |
418 | .index = -1, | |
419 | }; | |
420 | break; | |
421 | ||
422 | case X86_TYPE_Y: /* string destination */ | |
423 | op->n = -1; | |
424 | decode->mem = (AddressParts) { | |
425 | .def_seg = R_ES, | |
426 | .base = R_EDI, | |
427 | .index = -1, | |
428 | }; | |
429 | break; | |
430 | ||
431 | case X86_TYPE_2op: | |
432 | *op = decode->op[0]; | |
433 | break; | |
434 | ||
435 | case X86_TYPE_LoBits: | |
436 | op->n = (b & 7) | REX_B(s); | |
437 | op->unit = X86_OP_INT; | |
438 | break; | |
439 | ||
440 | case X86_TYPE_0 ... X86_TYPE_7: | |
441 | op->n = type - X86_TYPE_0; | |
442 | op->unit = X86_OP_INT; | |
443 | break; | |
444 | ||
445 | case X86_TYPE_ES ... X86_TYPE_GS: | |
446 | op->n = type - X86_TYPE_ES; | |
447 | op->unit = X86_OP_SEG; | |
448 | break; | |
449 | } | |
450 | ||
451 | return true; | |
452 | } | |
453 | ||
454 | static bool decode_insn(DisasContext *s, CPUX86State *env, X86DecodeFunc decode_func, | |
455 | X86DecodedInsn *decode) | |
456 | { | |
457 | X86OpEntry *e = &decode->e; | |
458 | ||
459 | decode_func(s, env, e, &decode->b); | |
460 | while (e->is_decode) { | |
461 | e->is_decode = false; | |
462 | e->decode(s, env, e, &decode->b); | |
463 | } | |
464 | ||
465 | /* First compute size of operands in order to initialize s->rip_offset. */ | |
466 | if (e->op0 != X86_TYPE_None) { | |
467 | if (!decode_op_size(s, e, e->s0, &decode->op[0].ot)) { | |
468 | return false; | |
469 | } | |
470 | if (e->op0 == X86_TYPE_I) { | |
471 | s->rip_offset += 1 << decode->op[0].ot; | |
472 | } | |
473 | } | |
474 | if (e->op1 != X86_TYPE_None) { | |
475 | if (!decode_op_size(s, e, e->s1, &decode->op[1].ot)) { | |
476 | return false; | |
477 | } | |
478 | if (e->op1 == X86_TYPE_I) { | |
479 | s->rip_offset += 1 << decode->op[1].ot; | |
480 | } | |
481 | } | |
482 | if (e->op2 != X86_TYPE_None) { | |
483 | if (!decode_op_size(s, e, e->s2, &decode->op[2].ot)) { | |
484 | return false; | |
485 | } | |
486 | if (e->op2 == X86_TYPE_I) { | |
487 | s->rip_offset += 1 << decode->op[2].ot; | |
488 | } | |
489 | } | |
490 | if (e->op3 != X86_TYPE_None) { | |
491 | assert(e->op3 == X86_TYPE_I && e->s3 == X86_SIZE_b); | |
492 | s->rip_offset += 1; | |
493 | } | |
494 | ||
495 | if (e->op0 != X86_TYPE_None && | |
496 | !decode_op(s, env, decode, &decode->op[0], e->op0, decode->b)) { | |
497 | return false; | |
498 | } | |
499 | ||
500 | if (e->op1 != X86_TYPE_None && | |
501 | !decode_op(s, env, decode, &decode->op[1], e->op1, decode->b)) { | |
502 | return false; | |
503 | } | |
504 | ||
505 | if (e->op2 != X86_TYPE_None && | |
506 | !decode_op(s, env, decode, &decode->op[2], e->op2, decode->b)) { | |
507 | return false; | |
508 | } | |
509 | ||
510 | if (e->op3 != X86_TYPE_None) { | |
511 | decode->immediate = insn_get_signed(env, s, MO_8); | |
512 | } | |
513 | ||
514 | return true; | |
515 | } | |
516 | ||
517 | static bool has_cpuid_feature(DisasContext *s, X86CPUIDFeature cpuid) | |
518 | { | |
519 | switch (cpuid) { | |
520 | case X86_FEAT_None: | |
521 | return true; | |
522 | case X86_FEAT_MOVBE: | |
523 | return (s->cpuid_ext_features & CPUID_EXT_MOVBE); | |
524 | case X86_FEAT_PCLMULQDQ: | |
525 | return (s->cpuid_ext_features & CPUID_EXT_PCLMULQDQ); | |
526 | case X86_FEAT_SSE: | |
527 | return (s->cpuid_ext_features & CPUID_SSE); | |
528 | case X86_FEAT_SSE2: | |
529 | return (s->cpuid_ext_features & CPUID_SSE2); | |
530 | case X86_FEAT_SSE3: | |
531 | return (s->cpuid_ext_features & CPUID_EXT_SSE3); | |
532 | case X86_FEAT_SSSE3: | |
533 | return (s->cpuid_ext_features & CPUID_EXT_SSSE3); | |
534 | case X86_FEAT_SSE41: | |
535 | return (s->cpuid_ext_features & CPUID_EXT_SSE41); | |
536 | case X86_FEAT_SSE42: | |
537 | return (s->cpuid_ext_features & CPUID_EXT_SSE42); | |
538 | case X86_FEAT_AES: | |
539 | if (!(s->cpuid_ext_features & CPUID_EXT_AES)) { | |
540 | return false; | |
541 | } else if (!(s->prefix & PREFIX_VEX)) { | |
542 | return true; | |
543 | } else if (!(s->cpuid_ext_features & CPUID_EXT_AVX)) { | |
544 | return false; | |
545 | } else { | |
546 | return !s->vex_l || (s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_VAES); | |
547 | } | |
548 | ||
549 | case X86_FEAT_AVX: | |
550 | return (s->cpuid_ext_features & CPUID_EXT_AVX); | |
551 | ||
552 | case X86_FEAT_SSE4A: | |
553 | return (s->cpuid_ext3_features & CPUID_EXT3_SSE4A); | |
554 | ||
555 | case X86_FEAT_ADX: | |
556 | return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX); | |
557 | case X86_FEAT_BMI1: | |
558 | return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1); | |
559 | case X86_FEAT_BMI2: | |
560 | return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2); | |
561 | case X86_FEAT_AVX2: | |
562 | return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_AVX2); | |
563 | } | |
564 | g_assert_not_reached(); | |
565 | } | |
566 | ||
567 | static void decode_temp_free(X86DecodedOp *op) | |
568 | { | |
569 | if (op->v_ptr) { | |
570 | tcg_temp_free_ptr(op->v_ptr); | |
571 | } | |
572 | } | |
573 | ||
574 | static void decode_temps_free(X86DecodedInsn *decode) | |
575 | { | |
576 | decode_temp_free(&decode->op[0]); | |
577 | decode_temp_free(&decode->op[1]); | |
578 | decode_temp_free(&decode->op[2]); | |
579 | } | |
580 | ||
581 | /* | |
582 | * Convert one instruction. s->base.is_jmp is set if the translation must | |
583 | * be stopped. | |
584 | */ | |
585 | static void disas_insn_new(DisasContext *s, CPUState *cpu, int b) | |
586 | { | |
587 | CPUX86State *env = cpu->env_ptr; | |
588 | bool first = true; | |
589 | X86DecodedInsn decode; | |
590 | X86DecodeFunc decode_func = decode_root; | |
591 | ||
592 | #ifdef CONFIG_USER_ONLY | |
593 | if (limit) { --limit; } | |
594 | #endif | |
595 | s->has_modrm = false; | |
596 | ||
597 | next_byte: | |
598 | if (first) { | |
599 | first = false; | |
600 | } else { | |
601 | b = x86_ldub_code(env, s); | |
602 | } | |
603 | /* Collect prefixes. */ | |
604 | switch (b) { | |
605 | case 0xf3: | |
606 | s->prefix |= PREFIX_REPZ; | |
607 | s->prefix &= ~PREFIX_REPNZ; | |
608 | goto next_byte; | |
609 | case 0xf2: | |
610 | s->prefix |= PREFIX_REPNZ; | |
611 | s->prefix &= ~PREFIX_REPZ; | |
612 | goto next_byte; | |
613 | case 0xf0: | |
614 | s->prefix |= PREFIX_LOCK; | |
615 | goto next_byte; | |
616 | case 0x2e: | |
617 | s->override = R_CS; | |
618 | goto next_byte; | |
619 | case 0x36: | |
620 | s->override = R_SS; | |
621 | goto next_byte; | |
622 | case 0x3e: | |
623 | s->override = R_DS; | |
624 | goto next_byte; | |
625 | case 0x26: | |
626 | s->override = R_ES; | |
627 | goto next_byte; | |
628 | case 0x64: | |
629 | s->override = R_FS; | |
630 | goto next_byte; | |
631 | case 0x65: | |
632 | s->override = R_GS; | |
633 | goto next_byte; | |
634 | case 0x66: | |
635 | s->prefix |= PREFIX_DATA; | |
636 | goto next_byte; | |
637 | case 0x67: | |
638 | s->prefix |= PREFIX_ADR; | |
639 | goto next_byte; | |
640 | #ifdef TARGET_X86_64 | |
641 | case 0x40 ... 0x4f: | |
642 | if (CODE64(s)) { | |
643 | /* REX prefix */ | |
644 | s->prefix |= PREFIX_REX; | |
645 | s->vex_w = (b >> 3) & 1; | |
646 | s->rex_r = (b & 0x4) << 1; | |
647 | s->rex_x = (b & 0x2) << 2; | |
648 | s->rex_b = (b & 0x1) << 3; | |
649 | goto next_byte; | |
650 | } | |
651 | break; | |
652 | #endif | |
653 | case 0xc5: /* 2-byte VEX */ | |
654 | case 0xc4: /* 3-byte VEX */ | |
655 | /* | |
656 | * VEX prefixes cannot be used except in 32-bit mode. | |
657 | * Otherwise the instruction is LES or LDS. | |
658 | */ | |
659 | if (CODE32(s) && !VM86(s)) { | |
660 | static const int pp_prefix[4] = { | |
661 | 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ | |
662 | }; | |
663 | int vex3, vex2 = x86_ldub_code(env, s); | |
664 | ||
665 | if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { | |
666 | /* | |
667 | * 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, | |
668 | * otherwise the instruction is LES or LDS. | |
669 | */ | |
670 | s->pc--; /* rewind the advance_pc() x86_ldub_code() did */ | |
671 | break; | |
672 | } | |
673 | ||
674 | /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */ | |
675 | if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ | |
676 | | PREFIX_LOCK | PREFIX_DATA | PREFIX_REX)) { | |
677 | goto illegal_op; | |
678 | } | |
679 | #ifdef TARGET_X86_64 | |
680 | s->rex_r = (~vex2 >> 4) & 8; | |
681 | #endif | |
682 | if (b == 0xc5) { | |
683 | /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */ | |
684 | vex3 = vex2; | |
685 | decode_func = decode_0F; | |
686 | } else { | |
687 | /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */ | |
688 | vex3 = x86_ldub_code(env, s); | |
689 | #ifdef TARGET_X86_64 | |
690 | s->rex_x = (~vex2 >> 3) & 8; | |
691 | s->rex_b = (~vex2 >> 2) & 8; | |
692 | #endif | |
693 | s->vex_w = (vex3 >> 7) & 1; | |
694 | switch (vex2 & 0x1f) { | |
695 | case 0x01: /* Implied 0f leading opcode bytes. */ | |
696 | decode_func = decode_0F; | |
697 | break; | |
698 | case 0x02: /* Implied 0f 38 leading opcode bytes. */ | |
699 | decode_func = decode_0F38; | |
700 | break; | |
701 | case 0x03: /* Implied 0f 3a leading opcode bytes. */ | |
702 | decode_func = decode_0F3A; | |
703 | break; | |
704 | default: /* Reserved for future use. */ | |
705 | goto unknown_op; | |
706 | } | |
707 | } | |
708 | s->vex_v = (~vex3 >> 3) & 0xf; | |
709 | s->vex_l = (vex3 >> 2) & 1; | |
710 | s->prefix |= pp_prefix[vex3 & 3] | PREFIX_VEX; | |
711 | } | |
712 | break; | |
713 | default: | |
714 | if (b >= 0x100) { | |
715 | b -= 0x100; | |
716 | decode_func = do_decode_0F; | |
717 | } | |
718 | break; | |
719 | } | |
720 | ||
721 | /* Post-process prefixes. */ | |
722 | if (CODE64(s)) { | |
723 | /* | |
724 | * In 64-bit mode, the default data size is 32-bit. Select 64-bit | |
725 | * data with rex_w, and 16-bit data with 0x66; rex_w takes precedence | |
726 | * over 0x66 if both are present. | |
727 | */ | |
728 | s->dflag = (REX_W(s) ? MO_64 : s->prefix & PREFIX_DATA ? MO_16 : MO_32); | |
729 | /* In 64-bit mode, 0x67 selects 32-bit addressing. */ | |
730 | s->aflag = (s->prefix & PREFIX_ADR ? MO_32 : MO_64); | |
731 | } else { | |
732 | /* In 16/32-bit mode, 0x66 selects the opposite data size. */ | |
733 | if (CODE32(s) ^ ((s->prefix & PREFIX_DATA) != 0)) { | |
734 | s->dflag = MO_32; | |
735 | } else { | |
736 | s->dflag = MO_16; | |
737 | } | |
738 | /* In 16/32-bit mode, 0x67 selects the opposite addressing. */ | |
739 | if (CODE32(s) ^ ((s->prefix & PREFIX_ADR) != 0)) { | |
740 | s->aflag = MO_32; | |
741 | } else { | |
742 | s->aflag = MO_16; | |
743 | } | |
744 | } | |
745 | ||
746 | memset(&decode, 0, sizeof(decode)); | |
747 | decode.b = b; | |
748 | if (!decode_insn(s, env, decode_func, &decode)) { | |
749 | goto illegal_op; | |
750 | } | |
751 | if (!decode.e.gen) { | |
752 | goto unknown_op; | |
753 | } | |
754 | ||
755 | if (!has_cpuid_feature(s, decode.e.cpuid)) { | |
756 | goto illegal_op; | |
757 | } | |
758 | ||
759 | switch (decode.e.special) { | |
760 | case X86_SPECIAL_None: | |
761 | break; | |
762 | ||
763 | case X86_SPECIAL_Locked: | |
764 | if (decode.op[0].has_ea) { | |
765 | s->prefix |= PREFIX_LOCK; | |
766 | } | |
767 | break; | |
768 | ||
769 | case X86_SPECIAL_ProtMode: | |
770 | if (!PE(s) || VM86(s)) { | |
771 | goto illegal_op; | |
772 | } | |
773 | break; | |
774 | ||
775 | case X86_SPECIAL_i64: | |
776 | if (CODE64(s)) { | |
777 | goto illegal_op; | |
778 | } | |
779 | break; | |
780 | case X86_SPECIAL_o64: | |
781 | if (!CODE64(s)) { | |
782 | goto illegal_op; | |
783 | } | |
784 | break; | |
785 | ||
786 | case X86_SPECIAL_ZExtOp0: | |
787 | assert(decode.op[0].unit == X86_OP_INT); | |
788 | if (!decode.op[0].has_ea) { | |
789 | decode.op[0].ot = MO_32; | |
790 | } | |
791 | break; | |
792 | ||
793 | case X86_SPECIAL_ZExtOp2: | |
794 | assert(decode.op[2].unit == X86_OP_INT); | |
795 | if (!decode.op[2].has_ea) { | |
796 | decode.op[2].ot = MO_32; | |
797 | } | |
798 | break; | |
799 | ||
800 | case X86_SPECIAL_MMX: | |
801 | if (!(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))) { | |
802 | gen_helper_enter_mmx(cpu_env); | |
803 | } | |
804 | break; | |
805 | } | |
806 | ||
807 | if (decode.op[0].has_ea || decode.op[1].has_ea || decode.op[2].has_ea) { | |
808 | gen_load_ea(s, &decode.mem); | |
809 | } | |
810 | if (s->prefix & PREFIX_LOCK) { | |
811 | if (decode.op[0].unit != X86_OP_INT || !decode.op[0].has_ea) { | |
812 | goto illegal_op; | |
813 | } | |
814 | gen_load(s, &decode, 2, s->T1); | |
815 | decode.e.gen(s, env, &decode); | |
816 | } else { | |
817 | if (decode.op[0].unit == X86_OP_MMX) { | |
818 | compute_mmx_offset(&decode.op[0]); | |
819 | } else if (decode.op[0].unit == X86_OP_SSE) { | |
820 | compute_xmm_offset(&decode.op[0]); | |
821 | } | |
822 | gen_load(s, &decode, 1, s->T0); | |
823 | gen_load(s, &decode, 2, s->T1); | |
824 | decode.e.gen(s, env, &decode); | |
825 | gen_writeback(s, &decode, 0, s->T0); | |
826 | } | |
827 | decode_temps_free(&decode); | |
828 | return; | |
829 | illegal_op: | |
830 | gen_illegal_opcode(s); | |
831 | return; | |
832 | unknown_op: | |
833 | gen_unknown_opcode(env, s); | |
834 | } |