This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] x86: ignore high register select bit(s) in 32- and 16-bit modes
- From: "Jan Beulich" <JBeulich at suse dot com>
- To: <binutils at sourceware dot org>
- Cc: "H.J. Lu" <hjl dot tools at gmail dot com>
- Date: Tue, 21 Feb 2017 09:27:20 -0700
- Subject: [PATCH] x86: ignore high register select bit(s) in 32- and 16-bit modes
- Authentication-results: sourceware.org; auth=none
While commits 9889cbb14e ("Check invalid mask registers") and
abfcb414b9 ("X86: Ignore REX_B bit for 32-bit XOP instructions") went a
bit into the right direction, this wasn't quite enough:
- VEX.vvvv has its high bit ignored
- EVEX.vvvv has its high bit ignored together with EVEX.v'
- the high bits of {,E}VEX.vvvv should not be prematurely zapped, to
allow proper checking of them when the fields has to hold al ones
- when the high bits of an immediate specify a register, bit 7 is
ignored
- GPR names should be determined base on REX_W rather than vex.w
gas/
2017-02-21 Jan Beulich <jbeulich@suse.com>
* gas/testsuite/gas/i386/noextreg.s,
gas/testsuite/gas/i386/noextreg.d: New.
* testsuite/gas/i386/i386.exp: Run new test.
opcodes/
2017-02-21 Jan Beulich <jbeulich@suse.com>
* i386-dis.c (VEXI4_Fixup, VexI4): Delete.
(prefix_table): Remove uses of VexI4.
(get_valid_dis386): Never flag bad opcode when
vex.register_specifier is beyond 7. Always store all four
bits of it. Move 16-/32-bit override in EVEX handling after
all to be overridden bits have been set.
(OP_VEX): Mask vex.register_specifier outside of 64-bit mode.
Use rex to determine GPR register set.
(OP_EX_VexReg, OP_Vex_2src_1, OP_Vex_2src_2): Mask
vex.register_specifier outside of 64-bit mode.
(OP_EX_VexW): Advance codep when 2nd pass done, deferring the
setting of vex_w_done until after that.
(OP_REG_VexI4): Don't check low four immediate bits. Mask
vex.register_specifier outside of 64-bit mode.
(OP_LWPCB_E): Use rex to determine GPR register set.
(OP_LWP_E): Likewise. Mask vex.register_specifier outside of
64-bit mode.
--- 2017-02-21/gas/testsuite/gas/i386/i386.exp
+++ 2017-02-21/gas/testsuite/gas/i386/i386.exp
@@ -182,6 +182,7 @@ if [expr ([istarget "i*86-*-*"] || [ist
run_dump_test "noavx-4"
run_list_test "noavx512-1" "-al"
run_list_test "noavx512-2" "-al"
+ run_dump_test "noextreg"
run_dump_test "xsave"
run_dump_test "xsave-intel"
run_dump_test "aes"
--- 2017-02-21/gas/testsuite/gas/i386/noextreg.d
+++ 2017-02-21/gas/testsuite/gas/i386/noextreg.d
@@ -0,0 +1,53 @@
+#objdump: -dw
+#name: ix86 no extended registers
+
+.*: file format .*
+
+Disassembly of section .text:
+
+0+ <ix86>:
+[ ]*[a-f0-9]+: c5 f9 db c0 vpand %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 c1 79 db c0 vpand %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 c1 39 db c0 vpand %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 62 f1 7d 08 db c0 vpandd %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 62 d1 7d 08 db c0 vpandd %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 62 f1 3d 08 db c0 vpandd %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 62 f1 7d 00 db c0 vpandd %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 4c c0 00 vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 c3 79 4c c0 00 vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 39 4c c0 00 vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 4c c0 80 vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 62 f2 7d 0f 90 0c 00 vpgatherdd \(%eax,%xmm0(,1)?\),%xmm1\{%k7\}
+[ ]*[a-f0-9]+: 62 d2 7d 0f 90 0c 00 vpgatherdd \(%eax,%xmm0(,1)?\),%xmm1\{%k7\}
+[ ]*[a-f0-9]+: 62 f2 7d 07 90 0c 00 vpgatherdd \(%eax,%xmm0(,1)?\),%xmm1\{%k7\}
+[ ]*[a-f0-9]+: c4 e2 78 f2 00 andn \(%eax\),%eax,%eax
+[ ]*[a-f0-9]+: c4 e2 38 f2 00 andn \(%eax\),%eax,%eax
+[ ]*[a-f0-9]+: c4 c2 78 f2 00 andn \(%eax\),%eax,%eax
+[ ]*[a-f0-9]+: c4 e2 f8 f2 00 andn \(%eax\),%eax,%eax
+[ ]*[a-f0-9]+: 8f e9 78 01 20 tzmsk \(%eax\),%eax
+[ ]*[a-f0-9]+: 8f c9 78 01 20 tzmsk \(%eax\),%eax
+[ ]*[a-f0-9]+: 8f e9 38 01 20 tzmsk \(%eax\),%eax
+[ ]*[a-f0-9]+: 8f e9 f8 01 20 tzmsk \(%eax\),%eax
+[ ]*[a-f0-9]+: 8f e9 78 12 c0 llwpcb %eax
+[ ]*[a-f0-9]+: 8f c9 78 12 c0 llwpcb %eax
+[ ]*[a-f0-9]+: 8f e9 f8 12 c0 llwpcb %eax
+[ ]*[a-f0-9]+: 8f e8 78 c0 c0 01 vprotb \$(0x)?1,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 8f e8 78 c0 00 01 vprotb \$(0x)?1,\(%eax\),%xmm0
+[ ]*[a-f0-9]+: 8f e9 78 90 c0 vprotb %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 8f e9 78 90 00 vprotb %xmm0,\(%eax\),%xmm0
+[ ]*[a-f0-9]+: 8f e9 f8 90 00 vprotb \(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: 8f c8 78 c0 c0 01 vprotb \$(0x)?1,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 8f c8 78 c0 00 01 vprotb \$(0x)?1,\(%eax\),%xmm0
+[ ]*[a-f0-9]+: 8f c9 b8 90 c0 vprotb %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 8f c9 78 90 00 vprotb %xmm0,\(%eax\),%xmm0
+[ ]*[a-f0-9]+: 8f e9 38 90 c0 vprotb %xmm0,%xmm0,%xmm0
+[ ]*[a-f0-9]+: 8f c9 f8 90 00 vprotb \(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 68 00 00 vfmaddps %xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 39 68 00 00 vfmaddps %xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 68 00 80 vfmaddps %xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 68 00 0f vfmaddps %xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 48 00 00 vpermil2ps \$(0x)?0,%xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 39 48 00 00 vpermil2ps \$(0x)?0,%xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c4 e3 79 48 00 80 vpermil2ps \$(0x)?0,%xmm0,\(%eax\),%xmm0,%xmm0
+[ ]*[a-f0-9]+: c3 ret[ ]*
+#pass
--- 2017-02-21/gas/testsuite/gas/i386/noextreg.s
+++ 2017-02-21/gas/testsuite/gas/i386/noextreg.s
@@ -0,0 +1,80 @@
+ .intel_syntax noprefix
+ .text
+ix86:
+ vpand xmm0, xmm0, xmm0
+ .code64
+ vpand xmm0, xmm0, xmm8
+ vpand xmm0, xmm8, xmm8
+ .code32
+
+ vpandd xmm0, xmm0, xmm0
+ .code64
+ vpandd xmm0, xmm0, xmm8
+ vpandd xmm0, xmm8, xmm0
+ vpandd xmm0, xmm16, xmm0
+ .code32
+
+ vpblendvb xmm0, xmm0, xmm0, xmm0
+ .code64
+ vpblendvb xmm0, xmm0, xmm8, xmm0
+ vpblendvb xmm0, xmm8, xmm0, xmm0
+ vpblendvb xmm0, xmm0, xmm0, xmm8
+ .code32
+
+ vpgatherdd xmm1{k7}, [eax+xmm0]
+ .code64
+ vpgatherdd xmm1{k7}, [r8+xmm0]
+ vpgatherdd xmm1{k7}, [rax+xmm16]
+ .code32
+
+ andn eax, eax, [eax]
+ .code64
+ andn eax, r8d, [rax]
+ andn eax, eax, [r8]
+ andn rax, rax, [rax]
+ .code32
+
+ tzmsk eax, [eax]
+ .code64
+ tzmsk eax, [r8]
+ tzmsk r8d, [rax]
+ tzmsk rax, [rax]
+ .code32
+
+ llwpcb eax
+ .code64
+ llwpcb r8d
+ llwpcb rax
+ .code32
+
+ vprotb xmm0, xmm0, 1
+ vprotb xmm0, [eax], 1
+ vprotb xmm0, xmm0, xmm0
+ vprotb xmm0, [eax], xmm0
+ vprotb xmm0, xmm0, [eax]
+ .code64
+ vprotb xmm0, xmm8, 1
+ vprotb xmm0, [r8], 1
+ .byte 0x8f, 0xc9, 0xb8, 0x90, 0xc0 # vprotb xmm0, xmm8, xmm0
+ vprotb xmm0, [r8], xmm0
+ vprotb xmm0, xmm0, xmm8
+ vprotb xmm0, xmm0, [r8]
+ .code32
+
+ vfmaddps xmm0, xmm0, [eax], xmm0
+ .code64
+ vfmaddps xmm0, xmm8, [rax], xmm0
+ vfmaddps xmm0, xmm0, [rax], xmm8
+ .code32
+ .byte 0xc4, 0xe3, 0x79, 0x68, 0x00, 0x0f # vfmaddps xmm0, xmm0, [eax], xmm0
+
+ vpermil2ps xmm0, xmm0, [eax], xmm0, 0
+ .code64
+ vpermil2ps xmm0, xmm8, [rax], xmm0, 0
+ vpermil2ps xmm0, xmm0, [rax], xmm8, 0
+ .code32
+
+ ret
+
+ .type ix86, @function
+ .size ix86, . - ix86
--- 2017-02-21/opcodes/i386-dis.c
+++ 2017-02-21/opcodes/i386-dis.c
@@ -95,7 +95,6 @@ static void OP_XMM_VexW (int, int);
static void OP_Rounding (int, int);
static void OP_REG_VexI4 (int, int);
static void PCLMUL_Fixup (int, int);
-static void VEXI4_Fixup (int, int);
static void VZERO_Fixup (int, int);
static void VCMP_Fixup (int, int);
static void VPCMP_Fixup (int, int);
@@ -418,7 +417,6 @@ fetch_data (struct disassemble_info *inf
#define Vex128 { OP_VEX, vex128_mode }
#define Vex256 { OP_VEX, vex256_mode }
#define VexGdq { OP_VEX, dq_mode }
-#define VexI4 { VEXI4_Fixup, 0}
#define EXdVex { OP_EX_Vex, d_mode }
#define EXdVexS { OP_EX_Vex, d_swap_mode }
#define EXdVexScalarS { OP_EX_Vex, d_scalar_swap_mode }
@@ -6611,28 +6609,28 @@ static const struct dis386 prefix_table[
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmaddsubps", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmaddsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A5D */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmaddsubpd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmaddsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A5E */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmsubaddps", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmsubaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A5F */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmsubaddpd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmsubaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A60 */
@@ -6668,14 +6666,14 @@ static const struct dis386 prefix_table[
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmaddps", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A69 */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmaddpd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A6A */
@@ -6696,14 +6694,14 @@ static const struct dis386 prefix_table[
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmsubps", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A6D */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfmsubpd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfmsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A6E */
@@ -6724,14 +6722,14 @@ static const struct dis386 prefix_table[
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfnmaddps", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfnmaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A79 */
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfnmaddpd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfnmaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A7A */
@@ -6752,7 +6750,7 @@ static const struct dis386 prefix_table[
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfnmsubps", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfnmsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
{ Bad_Opcode },
},
@@ -6760,7 +6758,7 @@ static const struct dis386 prefix_table[
{
{ Bad_Opcode },
{ Bad_Opcode },
- { "vfnmsubpd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vfnmsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
},
/* PREFIX_VEX_0F3A7E */
@@ -7706,9 +7704,9 @@ static const struct dis386 xop_table[][2
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpmacssww", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpmacsswd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpmacssdql", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpmacssww", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpmacsswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpmacssdql", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
/* 88 */
{ Bad_Opcode },
{ Bad_Opcode },
@@ -7716,17 +7714,17 @@ static const struct dis386 xop_table[][2
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpmacssdd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpmacssdqh", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpmacssdd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpmacssdqh", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
/* 90 */
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpmacsww", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpmacswd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpmacsdql", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpmacsww", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpmacswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpmacsdql", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
/* 98 */
{ Bad_Opcode },
{ Bad_Opcode },
@@ -7734,16 +7732,16 @@ static const struct dis386 xop_table[][2
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpmacsdd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpmacsdqh", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpmacsdd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpmacsdqh", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
/* a0 */
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpcmov", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
- { "vpperm", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpcmov", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+ { "vpperm", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpmadcsswd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpmadcsswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
{ Bad_Opcode },
/* a8 */
{ Bad_Opcode },
@@ -7761,7 +7759,7 @@ static const struct dis386 xop_table[][2
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
- { "vpmadcswd", { XMVexW, Vex, EXVexW, EXVexW, VexI4 }, 0 },
+ { "vpmadcswd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
{ Bad_Opcode },
/* b8 */
{ Bad_Opcode },
@@ -10018,42 +10016,42 @@ static const struct dis386 vex_len_table
/* VEX_LEN_0F3A6A_P_2 */
{
- { "vfmaddss", { XMVexW, Vex128, EXdVexW, EXdVexW, VexI4 }, 0 },
+ { "vfmaddss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
},
/* VEX_LEN_0F3A6B_P_2 */
{
- { "vfmaddsd", { XMVexW, Vex128, EXqVexW, EXqVexW, VexI4 }, 0 },
+ { "vfmaddsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
},
/* VEX_LEN_0F3A6E_P_2 */
{
- { "vfmsubss", { XMVexW, Vex128, EXdVexW, EXdVexW, VexI4 }, 0 },
+ { "vfmsubss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
},
/* VEX_LEN_0F3A6F_P_2 */
{
- { "vfmsubsd", { XMVexW, Vex128, EXqVexW, EXqVexW, VexI4 }, 0 },
+ { "vfmsubsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
},
/* VEX_LEN_0F3A7A_P_2 */
{
- { "vfnmaddss", { XMVexW, Vex128, EXdVexW, EXdVexW, VexI4 }, 0 },
+ { "vfnmaddss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
},
/* VEX_LEN_0F3A7B_P_2 */
{
- { "vfnmaddsd", { XMVexW, Vex128, EXqVexW, EXqVexW, VexI4 }, 0 },
+ { "vfnmaddsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
},
/* VEX_LEN_0F3A7E_P_2 */
{
- { "vfnmsubss", { XMVexW, Vex128, EXdVexW, EXdVexW, VexI4 }, 0 },
+ { "vfnmsubss", { XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
},
/* VEX_LEN_0F3A7F_P_2 */
{
- { "vfnmsubsd", { XMVexW, Vex128, EXqVexW, EXqVexW, VexI4 }, 0 },
+ { "vfnmsubsd", { XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
},
/* VEX_LEN_0F3ADF_P_2 */
@@ -12676,11 +12674,6 @@ get_valid_dis386 (const struct dis386 *d
{
/* In 16/32-bit mode REX_B is silently ignored. */
rex &= ~REX_B;
- if (vex.register_specifier > 0x7)
- {
- dp = &bad_opcode;
- return dp;
- }
}
vex.length = (*codep & 0x4) ? 256 : 128;
@@ -12739,16 +12732,15 @@ get_valid_dis386 (const struct dis386 *d
{
if (vex.w)
rex |= REX_W;
- vex.register_specifier = (~(*codep >> 3)) & 0xf;
}
else
{
/* For the 3-byte VEX prefix in 32-bit mode, the REX_B bit
is ignored, other REX bits are 0 and the highest bit in
- VEX.vvvv is also ignored. */
+ VEX.vvvv is also ignored (but we mustn't clear it here). */
rex = 0;
- vex.register_specifier = (~(*codep >> 3)) & 0x7;
}
+ vex.register_specifier = (~(*codep >> 3)) & 0xf;
vex.length = (*codep & 0x4) ? 256 : 128;
switch ((*codep & 0x3))
{
@@ -12863,14 +12855,6 @@ get_valid_dis386 (const struct dis386 *d
rex |= REX_W;
vex.register_specifier = (~(*codep >> 3)) & 0xf;
- if (address_mode != mode_64bit)
- {
- /* In 16/32-bit mode silently ignore following bits. */
- rex &= ~REX_B;
- vex.r = 1;
- vex.v = 1;
- vex.register_specifier &= 0x7;
- }
/* The U bit. */
if (!(*codep & 0x4))
@@ -12903,6 +12887,14 @@ get_valid_dis386 (const struct dis386 *d
vex.mask_register_specifier = *codep & 0x7;
vex.zeroing = *codep & 0x80;
+ if (address_mode != mode_64bit)
+ {
+ /* In 16/32-bit mode silently ignore following bits. */
+ rex &= ~REX_B;
+ vex.r = 1;
+ vex.v = 1;
+ }
+
need_vex = 1;
need_vex_reg = 1;
codep++;
@@ -16913,11 +16905,10 @@ OP_VEX (int bytemode, int sizeflag ATTRI
return;
reg = vex.register_specifier;
- if (vex.evex)
- {
- if (!vex.v)
- reg += 16;
- }
+ if (address_mode != mode_64bit)
+ reg &= 7;
+ else if (vex.evex && !vex.v)
+ reg += 16;
if (bytemode == vex_scalar_mode)
{
@@ -16937,7 +16928,7 @@ OP_VEX (int bytemode, int sizeflag ATTRI
names = names_xmm;
break;
case dq_mode:
- if (vex.w)
+ if (rex & REX_W)
names = names64;
else
names = names32;
@@ -17102,8 +17093,8 @@ OP_EX_VexReg (int bytemode, int sizeflag
if (rex & REX_B)
reg += 8;
}
- else if (reg > 7 && address_mode != mode_64bit)
- BadOp ();
+ if (address_mode != mode_64bit)
+ reg &= 7;
}
switch (vex.length)
@@ -17195,7 +17186,13 @@ OP_Vex_2src_1 (int bytemode, int sizefla
}
if (vex.w)
- oappend (names_xmm[vex.register_specifier]);
+ {
+ unsigned int reg = vex.register_specifier;
+
+ if (address_mode != mode_64bit)
+ reg &= 7;
+ oappend (names_xmm[reg]);
+ }
else
OP_Vex_2src (bytemode, sizeflag);
}
@@ -17206,7 +17203,13 @@ OP_Vex_2src_2 (int bytemode, int sizefla
if (vex.w)
OP_Vex_2src (bytemode, sizeflag);
else
- oappend (names_xmm[vex.register_specifier]);
+ {
+ unsigned int reg = vex.register_specifier;
+
+ if (address_mode != mode_64bit)
+ reg &= 7;
+ oappend (names_xmm[reg]);
+ }
}
static void
@@ -17216,8 +17219,6 @@ OP_EX_VexW (int bytemode, int sizeflag)
if (!vex_w_done)
{
- vex_w_done = 1;
-
/* Skip mod/rm byte. */
MODRM_CHECK;
codep++;
@@ -17232,16 +17233,10 @@ OP_EX_VexW (int bytemode, int sizeflag)
}
OP_EX_VexReg (bytemode, sizeflag, reg);
-}
-static void
-VEXI4_Fixup (int bytemode ATTRIBUTE_UNUSED,
- int sizeflag ATTRIBUTE_UNUSED)
-{
- /* Skip the immediate byte and check for invalid bits. */
- FETCH_DATA (the_info, codep + 1);
- if (*codep++ & 0xf)
- BadOp ();
+ if (vex_w_done)
+ codep++;
+ vex_w_done = 1;
}
static void
@@ -17256,12 +17251,9 @@ OP_REG_VexI4 (int bytemode, int sizeflag
if (bytemode != x_mode)
abort ();
- if (reg & 0xf)
- BadOp ();
-
reg >>= 4;
- if (reg > 7 && address_mode != mode_64bit)
- BadOp ();
+ if (address_mode != mode_64bit)
+ reg &= 7;
switch (vex.length)
{
@@ -17532,7 +17524,7 @@ OP_LWPCB_E (int bytemode ATTRIBUTE_UNUSE
MODRM_CHECK;
codep++;
- if (vex.w)
+ if (rex & REX_W)
names = names64;
else
names = names32;
@@ -17549,13 +17541,16 @@ static void
OP_LWP_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
{
const char **names;
+ unsigned int reg = vex.register_specifier;
- if (vex.w)
+ if (rex & REX_W)
names = names64;
else
names = names32;
- oappend (names[vex.register_specifier]);
+ if (address_mode != mode_64bit)
+ reg &= 7;
+ oappend (names[reg]);
}
static void