[4/4] x86: flag bad S/G insn operand combinations

Message ID 4dfdd514-5a25-e58a-ff3f-7f0df76d5d64@suse.com
State New
Headers show
Series
  • x86: assorted bug fixes
Related show

Commit Message

H.J. Lu via Binutils March 24, 2021, 9:24 a.m.
For VEX-encoded ones, all three involved vector registers have to be
distinct. For EVEX-encoded ones an actual mask register has to be in use
and zeroing-masking cannot be used (violation of either will #UD).
Additionally both involved vector registers have to be distinct for
EVEX-encoded gathers.

gas/
2021-03-XX  Jan Beulich  <jbeulich@suse.com>

	* testsuite/gas/i386/avx512f-nondef.s: Add vgather cases.
	* testsuite/gas/i386/x86-64-vgather-check.s: Add cases with
	colliding registers in the upper half of the space.
	* testsuite/gas/i386/avx512f-nondef.d,
	testsuite/gas/i386/vgather-check.d,
	testsuite/gas/i386/x86-64-vgather-check.d,
	testsuite/gas/i386/x86-64-vgather-check-error.l,
	testsuite/gas/i386/x86-64-vgather-check-warn.e: Adjust
	expecations.
	* testsuite/gas/i386/vgather-check-none.d,
	testsuite/gas/i386/vgather-check-warn.d,
	testsuite/gas/i386/x86-64-vgather-check-none.d,
	testsuite/gas/i386/x86-64-vgather-check-warn.d: Refer to "base"
	tests for expected dump output.

opcodes/
2021-03-XX  Jan Beulich  <jbeulich@suse.com>

	* i386-dis.c (XMGatherD, VexGatherD): New.
	(vex_table): Use VexGatherD for vpgatherd* and vgatherdp*.
	(print_insn): Check masking for S/G insns.
	(OP_E_memory): New local variable check_gather. Extend mandatory
	SIB check. Check register conflicts for (EVEX-encoded) gathers.
	Extend check for disallowed 16-bit addressing.
	(OP_VEX): New local variables modrm_reg and sib_index. Convert
	if()s to switch(). Check register conflicts for (VEX-encoded)
	gathers. Drop no longer reachable cases.
	* i386-dis-evex.h (evex_table): Use XMGatherD for vpgatherd* and
	vgatherdp*.
---
Of course there's a wider issue here - there are more insns not allowing
zeroing-masking. And there are also a number of insns not allowing
masking at all. I'm considering whether to express this via an insn name
macro expanding to nothing, but flagging the issue (such that "/(bad)"
can be appended to the destination operand after having appended the
masking notation, effectively generalizing what the patch here does for
this specific case).

Patch

--- a/gas/testsuite/gas/i386/avx512f-nondef.d
+++ b/gas/testsuite/gas/i386/avx512f-nondef.d
@@ -18,4 +18,8 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	31 72 7f             	xor    %esi,0x7f\(%edx\)
 [ 	]*[a-f0-9]+:	62 f1 7c 88 58       	\(bad\)
 [ 	]*[a-f0-9]+:	c3                   	ret *
+[ 	]*[a-f0-9]+:	62 f2 7d 4f 92 01    	vgatherdps \(bad\),%zmm0\{%k7\}
+[ 	]*[a-f0-9]+:	67 62 f2 7d 4f 92 01 	addr16 vgatherdps \(bad\),%zmm0\{%k7\}
+[ 	]*[a-f0-9]+:	62 f2 7d cf 92 04 08 	vgatherdps \(%eax,%zmm1(,1)?\),%zmm0\{%k7\}\{z\}/\(bad\)
+[ 	]*[a-f0-9]+:	62 f2 7d 48 92 04 08 	vgatherdps \(%eax,%zmm1(,1)?\),%zmm0/\(bad\)
 #pass
--- a/gas/testsuite/gas/i386/avx512f-nondef.s
+++ b/gas/testsuite/gas/i386/avx512f-nondef.s
@@ -15,3 +15,11 @@ 
 .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f
 # vaddps xmm0, xmm0, xmm3 # with EVEX.z set
 .byte 0x62, 0xf1, 0x7c, 0x88, 0x58, 0xc3
+# vgatherdps (%ecx), %zmm0{%k7}			# without SIB / index register
+.byte 0x62, 0xf2, 0x7d, 0x4f, 0x92, 0x01
+# vgatherdps (%bx,%xmm?), %zmm0{%k7}		# with 16-bit addressing
+.byte 0x67, 0x62, 0xf2, 0x7d, 0x4f, 0x92, 0x01
+# vgatherdps (%eax,%zmm1), %zmm0{%k7}{z}	# with set EVEX.z
+.byte 0x62, 0xf2, 0x7d, 0xcf, 0x92, 0x04, 0x08
+# vgatherdps (%eax,%zmm1), %zmm0		# without actual mask register
+.byte 0x62, 0xf2, 0x7d, 0x48, 0x92, 0x04, 0x08
--- a/gas/testsuite/gas/i386/vgather-check-none.d
+++ b/gas/testsuite/gas/i386/vgather-check-none.d
@@ -1,34 +1,4 @@ 
 #as: -moperand-check=error -I${srcdir}/$subdir
 #objdump: -dw
 #name: i386 vgather check (.operand_check none)
-
-.*:     file format .*
-
-Disassembly of section .text:
-
-0+ <vgather>:
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
-
-00000018 <avx512vgather>:
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 fd 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 fd 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 fd 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 fd 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm7,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm6,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 fd 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 fd 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 fd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm7,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm6,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 fd 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 fd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm7,8\),%xmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm6,8\),%xmm6\{%k1\}
-#pass
+#dump: vgather-check.d
--- a/gas/testsuite/gas/i386/vgather-check-warn.d
+++ b/gas/testsuite/gas/i386/vgather-check-warn.d
@@ -1,35 +1,4 @@ 
 #source: vgather-check.s
 #warning_output: vgather-check-warn.e
 #objdump: -dw
-#name: i386 vgather check (warning)
-
-.*:     file format .*
-
-Disassembly of section .text:
-
-0+ <vgather>:
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
-
-00000018 <avx512vgather>:
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 fd 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 fd 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 fd 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 fd 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm7,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm6,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 fd 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 fd 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 fd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm7,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm6,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 fd 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 fd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm7,8\),%xmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm6,8\),%xmm6\{%k1\}
-#pass
+#dump: vgather-check.d
--- a/gas/testsuite/gas/i386/vgather-check.d
+++ b/gas/testsuite/gas/i386/vgather-check.d
@@ -8,27 +8,27 @@  Disassembly of section .text:
 
 0+ <vgather>:
 [ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,1\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,2\),%xmm2
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%eax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2/\(bad\),\(%eax,%xmm1,2\),%xmm2/\(bad\)
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1/\(bad\),\(%eax,%xmm1,4\)/\(bad\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%eax,%xmm1,8\)/\(bad\),%xmm1/\(bad\)
 
 00000018 <avx512vgather>:
 [ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 fd 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm6,8\),%zmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%ebp,%ymm6,8\)/\(bad\),%zmm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 fd 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 92 b4 f5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%ebp,%zmm6,8\)/\(bad\),%zmm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 fd 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%ebp,%zmm6,8\)/\(bad\),%zmm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 fd 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm7,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm6,8\),%ymm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 93 b4 f5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%ebp,%zmm6,8\)/\(bad\),%ymm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 fd 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%ebp,%zmm6,8\)/\(bad\),%zmm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 fd 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm6,8\),%zmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 90 b4 f5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%ebp,%ymm6,8\)/\(bad\),%zmm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 fd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm7,8\),%ymm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm6,8\),%ymm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%zmm6,8\)/\(bad\),%ymm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 fd 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm7,8\),%zmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm6,8\),%zmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 fd 49 91 b4 f5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%ebp,%zmm6,8\)/\(bad\),%zmm6\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 fd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm7,8\),%xmm6\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm6,8\),%xmm6\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 f2 7d 29 91 b4 f5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%ebp,%ymm6,8\)/\(bad\),%xmm6\{%k1\}
 #pass
--- a/gas/testsuite/gas/i386/x86-64-vgather-check-error.l
+++ b/gas/testsuite/gas/i386/x86-64-vgather-check-error.l
@@ -1,13 +1,16 @@ 
 .*: Assembler messages:
 .*:6: Error: .*
 .*:8: Error: .*
-.*:10: Error: .*
-.*:15: Error: .*
-.*:17: Error: .*
-.*:19: Error: .*
-.*:21: Error: .*
-.*:23: Error: .*
-.*:25: Error: .*
-.*:27: Error: .*
-.*:29: Error: .*
-.*:31: Error: .*
+.*:9: Error: .*
+.*:11: Error: .*
+.*:12: Error: .*
+.*:14: Error: .*
+.*:18: Error: .*
+.*:20: Error: .*
+.*:22: Error: .*
+.*:24: Error: .*
+.*:26: Error: .*
+.*:28: Error: .*
+.*:30: Error: .*
+.*:32: Error: .*
+.*:34: Error: .*
--- a/gas/testsuite/gas/i386/x86-64-vgather-check-none.d
+++ b/gas/testsuite/gas/i386/x86-64-vgather-check-none.d
@@ -1,37 +1,4 @@ 
 #as: -moperand-check=error -I${srcdir}/$subdir
 #objdump: -dw
 #name: x86-64 vgather check (.operand_check none)
-
-.*:     file format .*
-
-Disassembly of section .text:
-
-0+ <vgather>:
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
-[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
-[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
-
-000000000000002a <avx512vgather>:
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 cd 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 c5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 cd 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 c5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 cd 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 c5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 cd 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm17,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 c5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm16,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 cd 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 cd 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 cd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm17,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm16,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 cd 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 cd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm17,8\),%xmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm16,8\),%xmm16\{%k1\}
-#pass
+#dump: x86-64-vgather-check.d
--- a/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d
+++ b/gas/testsuite/gas/i386/x86-64-vgather-check-warn.d
@@ -2,37 +2,4 @@ 
 #warning_output: x86-64-vgather-check-warn.e
 #objdump: -dw
 #name: x86-64 vgather check (warning)
-
-.*:     file format .*
-
-Disassembly of section .text:
-
-0+ <vgather>:
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
-[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
-[ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
-
-000000000000002a <avx512vgather>:
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 cd 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 c5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 cd 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 c5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 cd 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 c5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 cd 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm17,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 c5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm16,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 cd 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 cd 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 cd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm17,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm16,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 cd 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 cd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm17,8\),%xmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm16,8\),%xmm16\{%k1\}
-#pass
+#dump: x86-64-vgather-check.d
--- a/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e
+++ b/gas/testsuite/gas/i386/x86-64-vgather-check-warn.e
@@ -1,13 +1,16 @@ 
 .*: Assembler messages:
 .*:6: Warning: .*
 .*:8: Warning: .*
-.*:10: Warning: .*
-.*:15: Warning: .*
-.*:17: Warning: .*
-.*:19: Warning: .*
-.*:21: Warning: .*
-.*:23: Warning: .*
-.*:25: Warning: .*
-.*:27: Warning: .*
-.*:29: Warning: .*
-.*:31: Warning: .*
+.*:9: Warning: .*
+.*:11: Warning: .*
+.*:12: Warning: .*
+.*:14: Warning: .*
+.*:18: Warning: .*
+.*:20: Warning: .*
+.*:22: Warning: .*
+.*:24: Warning: .*
+.*:26: Warning: .*
+.*:28: Warning: .*
+.*:30: Warning: .*
+.*:32: Warning: .*
+.*:34: Warning: .*
--- a/gas/testsuite/gas/i386/x86-64-vgather-check.d
+++ b/gas/testsuite/gas/i386/x86-64-vgather-check.d
@@ -8,30 +8,33 @@  Disassembly of section .text:
 
 0+ <vgather>:
 [ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 04 08[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,1\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm2
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 14 48[ 	]+vgatherdps %xmm2/\(bad\),\(%rax,%xmm1,2\),%xmm2/\(bad\)
 [ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 14 48[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,2\),%xmm10
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1,\(%rax,%xmm1,4\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 62 29 92 14 48[ 	]+vgatherdps %xmm10/\(bad\),\(%rax,%xmm1,2\),%xmm10/\(bad\)
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 71 92 04 88[ 	]+vgatherdps %xmm1/\(bad\),\(%rax,%xmm1,4\)/\(bad\),%xmm0
 [ 	]*[a-f0-9]+:[ 	]+c4 e2 31 92 04 88[ 	]+vgatherdps %xmm9,\(%rax,%xmm1,4\),%xmm0
-[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm1
+[ 	]*[a-f0-9]+:[ 	]+c4 a2 31 92 04 88[ 	]+vgatherdps %xmm9/\(bad\),\(%rax,%xmm9,4\)/\(bad\),%xmm0
+[ 	]*[a-f0-9]+:[ 	]+c4 e2 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\)/\(bad\),%xmm1/\(bad\)
 [ 	]*[a-f0-9]+:[ 	]+c4 62 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm1,8\),%xmm9
+[ 	]*[a-f0-9]+:[ 	]+c4 22 69 92 0c c8[ 	]+vgatherdps %xmm2,\(%rax,%xmm9,8\)/\(bad\),%xmm9/\(bad\)
 
-000000000000002a <avx512vgather>:
+[0-9a-f]+ <avx512vgather>:
 [ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 cd 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 c5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm16,8\),%zmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 92 84 c5 7b 00 00 00[ 	]+vgatherdpd 0x7b\(%rbp,%ymm16,8\)/\(bad\),%zmm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 cd 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 c5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 92 84 c5 7b 00 00 00[ 	]+vgatherdps 0x7b\(%rbp,%zmm16,8\)/\(bad\),%zmm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 cd 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 c5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 93 84 c5 7b 00 00 00[ 	]+vgatherqpd 0x7b\(%rbp,%zmm16,8\)/\(bad\),%zmm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 cd 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm17,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 c5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm16,8\),%ymm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 93 84 c5 7b 00 00 00[ 	]+vgatherqps 0x7b\(%rbp,%zmm16,8\)/\(bad\),%ymm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 cd 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdd 0x7b\(%rbp,%zmm16,8\)/\(bad\),%zmm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 cd 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm16,8\),%zmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 90 84 c5 7b 00 00 00[ 	]+vpgatherdq 0x7b\(%rbp,%ymm16,8\)/\(bad\),%zmm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 cd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm17,8\),%ymm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm16,8\),%ymm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%zmm16,8\)/\(bad\),%ymm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 cd 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm17,8\),%zmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm16,8\),%zmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 fd 41 91 84 c5 7b 00 00 00[ 	]+vpgatherqq 0x7b\(%rbp,%zmm16,8\)/\(bad\),%zmm16\{%k1\}
 [ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 cd 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm17,8\),%xmm16\{%k1\}
-[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm16,8\),%xmm16\{%k1\}
+[ 	]+[a-f0-9]+:[ 	]+62 e2 7d 21 91 84 c5 7b 00 00 00[ 	]+vpgatherqd 0x7b\(%rbp,%ymm16,8\)/\(bad\),%xmm16\{%k1\}
 #pass
--- a/gas/testsuite/gas/i386/x86-64-vgather-check.s
+++ b/gas/testsuite/gas/i386/x86-64-vgather-check.s
@@ -5,10 +5,13 @@  vgather:
 	vgatherdps %xmm2,(%rax,%xmm1,1),%xmm0
 	vgatherdps %xmm2,(%rax,%xmm1,2),%xmm2
 	vgatherdps %xmm2,(%rax,%xmm1,2),%xmm10
+	vgatherdps %xmm10,(%rax,%xmm1,2),%xmm10
 	vgatherdps %xmm1,(%rax,%xmm1,4),%xmm0
 	vgatherdps %xmm9,(%rax,%xmm1,4),%xmm0
+	vgatherdps %xmm9,(%rax,%xmm9,4),%xmm0
 	vgatherdps %xmm2,(%rax,%xmm1,8),%xmm1
 	vgatherdps %xmm2,(%rax,%xmm1,8),%xmm9
+	vgatherdps %xmm2,(%rax,%xmm9,8),%xmm9
 
 avx512vgather:
 	vgatherdpd	123(%rbp,%ymm17,8), %zmm16{%k1}
--- a/opcodes/i386-dis-evex.h
+++ b/opcodes/i386-dis-evex.h
@@ -455,9 +455,9 @@  static const struct dis386 evex_table[][
     { Bad_Opcode },
     { "vpshufbitqmb",  { XMask, Vex, EXx }, PREFIX_DATA },
     /* 90 */
-    { "vpgatherd%DQ",	{ XM, MVexVSIBDWpX }, PREFIX_DATA },
+    { "vpgatherd%DQ",	{ XMGatherD, MVexVSIBDWpX }, PREFIX_DATA },
     { "vpgatherq%DQ",	{ XMGatherQ, MVexVSIBQWpX }, PREFIX_DATA },
-    { "vgatherdp%XW",	{ XM, MVexVSIBDWpX}, PREFIX_DATA },
+    { "vgatherdp%XW",	{ XMGatherD, MVexVSIBDWpX }, PREFIX_DATA },
     { "vgatherqp%XW",	{ XMGatherQ, MVexVSIBQWpX }, PREFIX_DATA },
     { Bad_Opcode },
     { Bad_Opcode },
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -345,6 +345,7 @@  fetch_data (struct disassemble_info *inf
 #define MX { OP_MMX, 0 }
 #define XM { OP_XMM, 0 }
 #define XMScalar { OP_XMM, scalar_mode }
+#define XMGatherD { OP_XMM, vex_vsib_d_w_dq_mode }
 #define XMGatherQ { OP_XMM, vex_vsib_q_w_dq_mode }
 #define XMM { OP_XMM, xmm_mode }
 #define TMM { OP_XMM, tmm_mode }
@@ -390,6 +391,7 @@  fetch_data (struct disassemble_info *inf
 #define VexW { OP_VexW, vex_mode }
 #define VexScalar { OP_VEX, vex_scalar_mode }
 #define VexScalarR { OP_VexR, vex_scalar_mode }
+#define VexGatherD { OP_VEX, vex_vsib_d_w_dq_mode }
 #define VexGatherQ { OP_VEX, vex_vsib_q_w_dq_mode }
 #define VexGdq { OP_VEX, dq_mode }
 #define VexTmm { OP_VEX, tmm_mode }
@@ -6309,9 +6311,9 @@  static const struct dis386 vex_table[][2
     { MOD_TABLE (MOD_VEX_0F388E) },
     { Bad_Opcode },
     /* 90 */
-    { "vpgatherd%DQ", { XM, MVexVSIBDWpX, Vex }, PREFIX_DATA },
+    { "vpgatherd%DQ", { XM, MVexVSIBDWpX, VexGatherD }, PREFIX_DATA },
     { "vpgatherq%DQ", { XMGatherQ, MVexVSIBQWpX, VexGatherQ }, PREFIX_DATA },
-    { "vgatherdp%XW", { XM, MVexVSIBDWpX, Vex }, PREFIX_DATA },
+    { "vgatherdp%XW", { XM, MVexVSIBDWpX, VexGatherD }, PREFIX_DATA },
     { "vgatherqp%XW", { XMGatherQ, MVexVSIBQWpX, VexGatherQ }, PREFIX_DATA },
     { Bad_Opcode },
     { Bad_Opcode },
@@ -9682,6 +9684,13 @@  print_insn (bfd_vma pc, disassemble_info
 		    }
 		  if (vex.zeroing)
 		    oappend ("{z}");
+
+		  /* S/G insns require a mask and don't allow
+		     zeroing-masking.  */
+		  if ((dp->op[0].bytemode == vex_vsib_d_w_dq_mode
+		       || dp->op[0].bytemode == vex_vsib_q_w_dq_mode)
+		      && (vex.mask_register_specifier == 0 || vex.zeroing))
+		    oappend ("/(bad)");
 		}
 	    }
 	}
@@ -11539,6 +11548,7 @@  OP_E_memory (int bytemode, int sizeflag)
 			 || bytemode == v_bndmk_mode
 			 || bytemode == bnd_mode
 			 || bytemode == bnd_swap_mode);
+      bfd_boolean check_gather = FALSE;
       const char **indexes64 = names64;
       const char **indexes32 = names32;
 
@@ -11564,6 +11574,7 @@  OP_E_memory (int bytemode, int sizeflag)
 		{
 		  if (!vex.v)
 		    vindex += 16;
+		  check_gather = obufp == op_out[1];
 		}
 
 	      haveindex = 1;
@@ -11600,8 +11611,10 @@  OP_E_memory (int bytemode, int sizeflag)
 	}
       else
 	{
-	  /* mandatory non-vector SIB must have sib */
-	  if (bytemode == vex_sibmem_mode)
+	  /* Check for mandatory SIB.  */
+	  if (bytemode == vex_vsib_d_w_dq_mode
+	      || bytemode == vex_vsib_q_w_dq_mode
+	      || bytemode == vex_sibmem_mode)
 	    {
 	      oappend ("(bad)");
 	      return;
@@ -11754,6 +11767,19 @@  OP_E_memory (int bytemode, int sizeflag)
 
 	  *obufp++ = close_char;
 	  *obufp = '\0';
+
+	  if (check_gather)
+	    {
+	      /* Both XMM/YMM/ZMM registers must be distinct.  */
+	      int modrm_reg = modrm.reg;
+
+	      if (rex & REX_R)
+	        modrm_reg += 8;
+	      if (!vex.r)
+	        modrm_reg += 16;
+	      if (vindex == modrm_reg)
+		oappend ("/(bad)");
+	    }
 	}
       else if (intel_syntax)
 	{
@@ -11772,7 +11798,9 @@  OP_E_memory (int bytemode, int sizeflag)
   else if (bytemode == v_bnd_mode
 	   || bytemode == v_bndmk_mode
 	   || bytemode == bnd_mode
-	   || bytemode == bnd_swap_mode)
+	   || bytemode == bnd_swap_mode
+	   || bytemode == vex_vsib_d_w_dq_mode
+	   || bytemode == vex_vsib_q_w_dq_mode)
     {
       oappend ("(bad)");
       return;
@@ -13308,7 +13336,7 @@  FXSAVE_Fixup (int bytemode, int sizeflag
 static void
 OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 {
-  int reg;
+  int reg, modrm_reg, sib_index = -1;
   const char **names;
 
   if (!need_vex)
@@ -13321,14 +13349,46 @@  OP_VEX (int bytemode, int sizeflag ATTRI
   else if (vex.evex && !vex.v)
     reg += 16;
 
-  if (bytemode == vex_scalar_mode)
+  switch (bytemode)
     {
+    case vex_scalar_mode:
       oappend (names_xmm[reg]);
       return;
-    }
 
-  if (bytemode == tmm_mode)
-    {
+    case vex_vsib_d_w_dq_mode:
+    case vex_vsib_q_w_dq_mode:
+      /* This must be the 3rd operand.  */
+      if (obufp != op_out[2])
+	abort ();
+      if (vex.length == 128
+	  || (bytemode != vex_vsib_d_w_dq_mode
+	      && !vex.w))
+	oappend (names_xmm[reg]);
+      else
+	oappend (names_ymm[reg]);
+
+      /* All 3 XMM/YMM registers must be distinct.  */
+      modrm_reg = modrm.reg;
+      if (rex & REX_R)
+	modrm_reg += 8;
+
+      if (modrm.rm == 4)
+	{
+	  sib_index = sib.index;
+	  if (rex & REX_X)
+	    sib_index += 8;
+	}
+
+      if (reg == modrm_reg || reg == sib_index)
+	strcpy (obufp, "/(bad)");
+      if (modrm_reg == sib_index || modrm_reg == reg)
+	strcat (op_out[0], "/(bad)");
+      if (sib_index == modrm_reg || sib_index == reg)
+	strcat (op_out[1], "/(bad)");
+
+      return;
+
+    case tmm_mode:
       /* All 3 TMM registers must be distinct.  */
       if (reg >= 8)
 	oappend ("(bad)");
@@ -13361,7 +13421,6 @@  OP_VEX (int bytemode, int sizeflag ATTRI
       switch (bytemode)
 	{
 	case vex_mode:
-	case vex_vsib_q_w_dq_mode:
 	  names = names_xmm;
 	  break;
 	case dq_mode:
@@ -13390,9 +13449,6 @@  OP_VEX (int bytemode, int sizeflag ATTRI
 	case vex_mode:
 	  names = names_ymm;
 	  break;
-	case vex_vsib_q_w_dq_mode:
-	  names = vex.w ? names_ymm : names_xmm;
-	  break;
 	case mask_bd_mode:
 	case mask_mode:
 	  if (reg > 0x7)