]> git.proxmox.com Git - mirror_qemu.git/blame - target/i386/tcg/decode-new.c.inc
target/i386: add AVX_EN hflag
[mirror_qemu.git] / target / i386 / tcg / decode-new.c.inc
CommitLineData
b3e22b23
PB
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
caa01fad 88#define cpuid(feat) .cpuid = X86_FEAT_##feat,
b3e22b23
PB
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
96static 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
105static const X86OpEntry opcodes_0F38_00toEF[240] = {
106};
107
108/* five rows for no prefix, 66, F3, F2, 66+F2 */
109static const X86OpEntry opcodes_0F38_F0toFF[16][5] = {
110};
111
112static 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
130static const X86OpEntry opcodes_0F3A[256] = {
131};
132
133static 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
139static const X86OpEntry opcodes_0F[256] = {
140 [0x38] = X86_OP_GROUP0(0F38),
141 [0x3a] = X86_OP_GROUP0(0F3A),
142};
143
144static void do_decode_0F(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
145{
146 *entry = opcodes_0F[*b];
147}
148
149static 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
155static 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 */
165static void decode_root(DisasContext *s, CPUX86State *env, X86OpEntry *entry, uint8_t *b)
166{
167 *entry = opcodes_root[*b];
168}
169
170
171static 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
192static 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
273static 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
454static 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
caa01fad
PB
517static 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
6ba13999
PB
567static void decode_temp_free(X86DecodedOp *op)
568{
569 if (op->v_ptr) {
570 tcg_temp_free_ptr(op->v_ptr);
571 }
572}
573
574static 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
b3e22b23
PB
581/*
582 * Convert one instruction. s->base.is_jmp is set if the translation must
583 * be stopped.
584 */
585static 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
caa01fad
PB
755 if (!has_cpuid_feature(s, decode.e.cpuid)) {
756 goto illegal_op;
757 }
758
b3e22b23
PB
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 }
6ba13999
PB
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);
b3e22b23
PB
828 return;
829 illegal_op:
830 gen_illegal_opcode(s);
831 return;
832 unknown_op:
833 gen_unknown_opcode(env, s);
834}