[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 44/57] target-i386: Decode the VEX prefixes
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 44/57] target-i386: Decode the VEX prefixes |
Date: |
Wed, 23 Jan 2013 20:03:28 -0800 |
No actual required uses of these encodings yet.
Signed-off-by: Richard Henderson <address@hidden>
---
target-i386/translate.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 4 deletions(-)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 91d3957..a9cb60b 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -37,6 +37,7 @@
#define PREFIX_LOCK 0x04
#define PREFIX_DATA 0x08
#define PREFIX_ADR 0x10
+#define PREFIX_VEX 0x20
#ifdef TARGET_X86_64
#define CODE64(s) ((s)->code64)
@@ -97,6 +98,8 @@ typedef struct DisasContext {
int code64; /* 64 bit code segment */
int rex_x, rex_b;
#endif
+ int vex_l; /* vex vector length */
+ int vex_v; /* vex vvvv register, without 1's compliment. */
int ss32; /* 32 bit stack segment */
CCOp cc_op; /* current CC operation */
bool cc_op_dirty;
@@ -4269,6 +4272,8 @@ static target_ulong disas_insn(CPUX86State *env,
DisasContext *s,
x86_64_hregs = 0;
#endif
s->rip_offset = 0; /* for relative ip address */
+ s->vex_l = 0;
+ s->vex_v = 0;
next_byte:
b = cpu_ldub_code(env, s->pc);
s->pc++;
@@ -4320,6 +4325,63 @@ static target_ulong disas_insn(CPUX86State *env,
DisasContext *s,
}
break;
#endif
+ case 0xc5: /* 2-byte VEX */
+ case 0xc4: /* 3-byte VEX */
+ /* VEX prefixes cannot be used except in 32-bit mode.
+ Otherwise the instruction is LES or LDS. */
+ if (s->code32 && !s->vm86) {
+ static const int pp_prefix[4] = {
+ 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
+ };
+ int vex3, vex2 = cpu_ldub_code(env, s->pc);
+
+ if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
+ /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
+ otherwise the instruction is LES or LDS. */
+ break;
+ }
+ s->pc++;
+
+ /* 4.1.1-4.1.3: No preceeding lock, 66, f2, f3, or rex prefixes. */
+ if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
+ | PREFIX_LOCK | PREFIX_DATA)) {
+ goto illegal_op;
+ }
+#ifdef TARGET_X86_64
+ if (x86_64_hregs) {
+ goto illegal_op;
+ }
+#endif
+ rex_r = (~vex2 >> 4) & 8;
+ if (b == 0xc5) {
+ vex3 = vex2;
+ b = cpu_ldub_code(env, s->pc++);
+ } else {
+#ifdef TARGET_X86_64
+ s->rex_x = (~vex2 >> 3) & 8;
+ s->rex_b = (~vex2 >> 2) & 8;
+#endif
+ vex3 = cpu_ldub_code(env, s->pc++);
+ rex_w = (vex3 >> 7) & 1;
+ switch (vex2 & 0x1f) {
+ case 0x01: /* Implied 0f leading opcode bytes. */
+ b = cpu_ldub_code(env, s->pc++) | 0x100;
+ break;
+ case 0x02: /* Implied 0f 38 leading opcode bytes. */
+ b = 0x138;
+ break;
+ case 0x03: /* Implied 0f 3a leading opcode bytes. */
+ b = 0x13a;
+ break;
+ default: /* Reserved for future use. */
+ goto illegal_op;
+ }
+ }
+ s->vex_v = (~vex3 >> 3) & 0xf;
+ s->vex_l = (vex3 >> 2) & 1;
+ prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
+ }
+ break;
}
/* Post-process prefixes. */
@@ -5466,13 +5528,11 @@ static target_ulong disas_insn(CPUX86State *env,
DisasContext *s,
}
break;
case 0xc4: /* les Gv */
- if (CODE64(s))
- goto illegal_op;
+ /* In CODE64 this is VEX3; see above. */
op = R_ES;
goto do_lxx;
case 0xc5: /* lds Gv */
- if (CODE64(s))
- goto illegal_op;
+ /* In CODE64 this is VEX2; see above. */
op = R_DS;
goto do_lxx;
case 0x1b2: /* lss Gv */
--
1.7.11.7
- [Qemu-devel] [PATCH 13/57] target-i386: Name the cc_op enumeration, (continued)
- [Qemu-devel] [PATCH 13/57] target-i386: Name the cc_op enumeration, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 14/57] target-i386: Introduce set_cc_op, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 15/57] target-i386: Don't clobber s->cc_op in gen_update_cc_op, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 18/57] target-i386: do not compute eflags multiple times consecutively, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 17/57] target-i386: add helper functions to get other flags, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 16/57] target-i386: Use gen_update_cc_op everywhere, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 25/57] target-i386: optimize setbe, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 23/57] target-i386: convert gen_compute_eflags_c to TCG, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 28/57] target-i386: introduce CCPrepare, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 30/57] target-i386: use CCPrepare to generate conditional jumps, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 44/57] target-i386: Decode the VEX prefixes,
Richard Henderson <=
- [Qemu-devel] [PATCH 43/57] target-i386: Tidy prefix parsing, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 42/57] target-i386: Make helper_cc_compute_all const, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 53/57] target-i386: Implement RORX, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 55/57] target-i386: Use clz/ctz for bsf/bsr helpers, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 54/57] target-i386: Implement ADX extension, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 56/57] target-i386: Simplify bsf/bsr flags computation, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 57/57] target-i386: Implement tzcnt and fix lzcnt, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 33/57] target-i386: introduce gen_cmovcc1, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 31/57] target-i386: inline gen_prepare_cc_slow, Richard Henderson, 2013/01/23
- [Qemu-devel] [PATCH 40/57] target-i386: Use CC_SRC2 for ADC and SBB, Richard Henderson, 2013/01/23