This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] x86: ignore high register select bit(s) in 32- and 16-bit modes


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]