i386: Check vector length for EVEX broadcast instructions

Message ID CAMe9rOpRBZ-CrHb7=64nEiQauGmz6nGXsUeU+8t3HEWxrEggpQ@mail.gmail.com
State New
Headers show
Series
  • i386: Check vector length for EVEX broadcast instructions
Related show

Commit Message

H.J. Lu June 19, 2019, 4:58 p.m.
Since not all vector lengths are supported by EVEX broadcast instructions,
decode them only with supported vector lengths.

gas/

PR binutils/24700
* testsuite/gas/i386/disassem.s: Add test for vbroadcasti32x8
with invalid vector length.
* testsuite/gas/i386/x86-64-disassem.s: Likewise.
* testsuite/gas/i386/disassem.d: Updated.
* testsuite/gas/i386/x86-64-disassem.d: Likewise.

opcodes/

PR binutils/24700
* i386-dis-evex.h (evex_table): Update EVEX_W_0F3819_P_2,
EVEX_W_0F381A_P_2, EVEX_W_0F381B_P_2, EVEX_W_0F385A_P_2 and
EVEX_W_0F385B_P_2.
(evex_len_table): Add EVEX_LEN_0F3819_P_2_W_0,
EVEX_LEN_0F3819_P_2_W_1, EVEX_LEN_0F381A_P_2_W_0,
EVEX_LEN_0F381A_P_2_W_1, EVEX_LEN_0F381B_P_2_W_0,
EVEX_LEN_0F381B_P_2_W_1, EVEX_LEN_0F385A_P_2_W_0,
EVEX_LEN_0F385A_P_2_W_1, EVEX_LEN_0F385B_P_2_W_0 and
EVEX_LEN_0F385B_P_2_W_1.
* i386-dis.c (EVEX_LEN_0F3819_P_2_W_0): New enum.
(EVEX_LEN_0F3819_P_2_W_1): Likewise.
(EVEX_LEN_0F381A_P_2_W_0): Likewise.
(EVEX_LEN_0F381A_P_2_W_1): Likewise.
(EVEX_LEN_0F381B_P_2_W_0): Likewise.
(EVEX_LEN_0F381B_P_2_W_1): Likewise.
(EVEX_LEN_0F385A_P_2_W_0): Likewise.
(EVEX_LEN_0F385A_P_2_W_1): Likewise.
(EVEX_LEN_0F385B_P_2_W_0): Likewise.
(EVEX_LEN_0F385B_P_2_W_1): Likewise.

-- 
H.J.

Patch

From b25c79a5e12bbb7b0969606cc627f496ec3cdb0c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 19 Jun 2019 09:50:27 -0700
Subject: [PATCH] i386: Check vector length for EVEX broadcast instructions

Since not all vector lengths are supported by EVEX broadcast instructions,
decode them only with supported vector lengths.

gas/

	PR binutils/24700
	* testsuite/gas/i386/disassem.s: Add test for vbroadcasti32x8
	with invalid vector length.
	* testsuite/gas/i386/x86-64-disassem.s: Likewise.
	* testsuite/gas/i386/disassem.d: Updated.
	* testsuite/gas/i386/x86-64-disassem.d: Likewise.

opcodes/

	PR binutils/24700
	* i386-dis-evex.h (evex_table): Update EVEX_W_0F3819_P_2,
	EVEX_W_0F381A_P_2, EVEX_W_0F381B_P_2, EVEX_W_0F385A_P_2 and
	EVEX_W_0F385B_P_2.
	(evex_len_table): Add EVEX_LEN_0F3819_P_2_W_0,
	EVEX_LEN_0F3819_P_2_W_1, EVEX_LEN_0F381A_P_2_W_0,
	EVEX_LEN_0F381A_P_2_W_1, EVEX_LEN_0F381B_P_2_W_0,
	EVEX_LEN_0F381B_P_2_W_1, EVEX_LEN_0F385A_P_2_W_0,
	EVEX_LEN_0F385A_P_2_W_1, EVEX_LEN_0F385B_P_2_W_0 and
	EVEX_LEN_0F385B_P_2_W_1.
	* i386-dis.c (EVEX_LEN_0F3819_P_2_W_0): New enum.
	(EVEX_LEN_0F3819_P_2_W_1): Likewise.
	(EVEX_LEN_0F381A_P_2_W_0): Likewise.
	(EVEX_LEN_0F381A_P_2_W_1): Likewise.
	(EVEX_LEN_0F381B_P_2_W_0): Likewise.
	(EVEX_LEN_0F381B_P_2_W_1): Likewise.
	(EVEX_LEN_0F385A_P_2_W_0): Likewise.
	(EVEX_LEN_0F385A_P_2_W_1): Likewise.
	(EVEX_LEN_0F385B_P_2_W_0): Likewise.
	(EVEX_LEN_0F385B_P_2_W_1): Likewise.
---
 gas/testsuite/gas/i386/disassem.d        |  6 +-
 gas/testsuite/gas/i386/disassem.s        |  2 +
 gas/testsuite/gas/i386/x86-64-disassem.d |  5 +-
 gas/testsuite/gas/i386/x86-64-disassem.s |  2 +
 opcodes/i386-dis-evex.h                  | 90 +++++++++++++++++++++---
 opcodes/i386-dis.c                       | 10 +++
 6 files changed, 101 insertions(+), 14 deletions(-)

diff --git a/gas/testsuite/gas/i386/disassem.d b/gas/testsuite/gas/i386/disassem.d
index 27f37b6e2f..9a805a4907 100644
--- a/gas/testsuite/gas/i386/disassem.d
+++ b/gas/testsuite/gas/i386/disassem.d
@@ -349,6 +349,8 @@  Disassembly of section \.text:
 [ 	]*[a-f0-9]+:[ 	]*62 f3 7d 28 1b[ 	]*\(bad\)[ ]*
 [ 	]*[a-f0-9]+:[ 	]*c8 25 62 f3[ 	]*enter[ ]*\$0x6225,\$0xf3
 [ 	]*[a-f0-9]+:[ 	]*62 f3 75 08 23[ 	]*\(bad\)[ ]*
-[ 	]*[a-f0-9]+:[ 	]*c2[ 	]*.byte[ 	]*0xc2
-[ 	]*[a-f0-9]+:[ 	]*25[ 	]*.byte[ 	]*0x25
+[ 	]*[a-f0-9]+:[ 	]*c2 25 62[ 	]*ret[ ]*\$0x6225
+[ 	]*[a-f0-9]+:[ 	]*62 f2 7d 28 5b[ 	]*\(bad\)[ ]*
+[ 	]*[a-f0-9]+:[ 	]*41[ 	]*inc[ 	]*%ecx
+[ 	]*[a-f0-9]+:[ 	]*37[ 	]*aaa[ ]*
 #pass
diff --git a/gas/testsuite/gas/i386/disassem.s b/gas/testsuite/gas/i386/disassem.s
index d330018756..9a4aa5ad6e 100644
--- a/gas/testsuite/gas/i386/disassem.s
+++ b/gas/testsuite/gas/i386/disassem.s
@@ -173,3 +173,5 @@ 
 .byte 0x62, 0xf3, 0x7d, 0x28, 0x1b, 0xc8, 0x25
 .byte 0x62, 0xf3
 .byte 0x62, 0xf3, 0x75, 0x08, 0x23, 0xc2, 0x25
+.byte 0x62
+.byte 0x62, 0xf2, 0x7d, 0x28, 0x5b, 0x41, 0x37
diff --git a/gas/testsuite/gas/i386/x86-64-disassem.d b/gas/testsuite/gas/i386/x86-64-disassem.d
index 3dcbc104eb..62b8c44c90 100644
--- a/gas/testsuite/gas/i386/x86-64-disassem.d
+++ b/gas/testsuite/gas/i386/x86-64-disassem.d
@@ -348,6 +348,7 @@  Disassembly of section \.text:
 [ 	]*[a-f0-9]+:[ 	]*62 f3 7d 28 1b[ 	]*\(bad\)[ ]*
 [ 	]*[a-f0-9]+:[ 	]*c8 25 62 f3[ 	]*enterq[ ]*\$0x6225,\$0xf3
 [ 	]*[a-f0-9]+:[ 	]*62 f3 75 08 23[ 	]*\(bad\)[ ]*
-[ 	]*[a-f0-9]+:[ 	]*c2[ 	]*.byte[ 	]*0xc2
-[ 	]*[a-f0-9]+:[ 	]*25[ 	]*.byte[ 	]*0x25
+[ 	]*[a-f0-9]+:[ 	]*c2 25 62[ 	]*retq[ ]*\$0x6225
+[ 	]*[a-f0-9]+:[ 	]*62 f2 7d 28 5b[ 	]*\(bad\)[ ]*
+[ 	]*[a-f0-9]+:[ 	]*41 37[ 	]*rex.B \(bad\)[ ]*
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-disassem.s b/gas/testsuite/gas/i386/x86-64-disassem.s
index 7535052760..7184e3f825 100644
--- a/gas/testsuite/gas/i386/x86-64-disassem.s
+++ b/gas/testsuite/gas/i386/x86-64-disassem.s
@@ -173,3 +173,5 @@ 
 .byte 0x62, 0xf3, 0x7d, 0x28, 0x1b, 0xc8, 0x25
 .byte 0x62, 0xf3
 .byte 0x62, 0xf3, 0x75, 0x08, 0x23, 0xc2, 0x25
+.byte 0x62
+.byte 0x62, 0xf2, 0x7d, 0x28, 0x5b, 0x41, 0x37
diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h
index f34f8bc1a1..e9a9d923bf 100644
--- a/opcodes/i386-dis-evex.h
+++ b/opcodes/i386-dis-evex.h
@@ -3568,18 +3568,18 @@  static const struct dis386 evex_table[][256] = {
   },
   /* EVEX_W_0F3819_P_2 */
   {
-    { "vbroadcastf32x2",	{ XM, EXxmm_mq }, 0 },
-    { "vbroadcastsd",	{ XM, EXxmm_mq }, 0 },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F3819_P_2_W_0) },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F3819_P_2_W_1) },
   },
   /* EVEX_W_0F381A_P_2 */
   {
-    { "vbroadcastf32x4",	{ XM, EXxmm }, 0 },
-    { "vbroadcastf64x2",	{ XM, EXxmm }, 0 },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F381A_P_2_W_0) },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F381A_P_2_W_1) },
   },
   /* EVEX_W_0F381B_P_2 */
   {
-    { "vbroadcastf32x8",	{ XM, EXxmmq }, 0 },
-    { "vbroadcastf64x4",	{ XM, EXymm }, 0 },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F381B_P_2_W_0) },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F381B_P_2_W_1) },
   },
   /* EVEX_W_0F381E_P_2 */
   {
@@ -3739,13 +3739,13 @@  static const struct dis386 evex_table[][256] = {
   },
   /* EVEX_W_0F385A_P_2 */
   {
-    { "vbroadcasti32x4",	{ XM, EXxmm }, 0 },
-    { "vbroadcasti64x2",	{ XM, EXxmm }, 0 },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F385A_P_2_W_0) },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F385A_P_2_W_1) },
   },
   /* EVEX_W_0F385B_P_2 */
   {
-    { "vbroadcasti32x8",	{ XM, EXxmmq }, 0 },
-    { "vbroadcasti64x4",	{ XM, EXymm }, 0 },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F385B_P_2_W_0) },
+    { EVEX_LEN_TABLE (EVEX_LEN_0F385B_P_2_W_1) },
   },
   /* EVEX_W_0F3862_P_2 */
   {
@@ -4129,6 +4129,76 @@  static const struct dis386 evex_table[][256] = {
     { VEX_W_TABLE (EVEX_W_0FD6_P_2) },
   },
 
+  /* EVEX_LEN_0F3819_P_2_W_0 */
+  {
+    { Bad_Opcode },
+    { "vbroadcastf32x2",	{ XM, EXxmm_mq }, 0 },
+    { "vbroadcastf32x2",	{ XM, EXxmm_mq }, 0 },
+  },
+
+  /* EVEX_LEN_0F3819_P_2_W_1 */
+  {
+    { Bad_Opcode },
+    { "vbroadcastsd",	{ XM, EXxmm_mq }, 0 },
+    { "vbroadcastsd",	{ XM, EXxmm_mq }, 0 },
+  },
+
+  /* EVEX_LEN_0F381A_P_2_W_0 */
+  {
+    { Bad_Opcode },
+    { "vbroadcastf32x4",	{ XM, EXxmm }, 0 },
+    { "vbroadcastf32x4",	{ XM, EXxmm }, 0 },
+  },
+
+  /* EVEX_LEN_0F381A_P_2_W_1 */
+  {
+    { Bad_Opcode },
+    { "vbroadcastf64x2",	{ XM, EXxmm }, 0 },
+    { "vbroadcastf64x2",	{ XM, EXxmm }, 0 },
+  },
+
+  /* EVEX_LEN_0F381B_P_2_W_0 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "vbroadcastf32x8",	{ XM, EXxmmq }, 0 },
+  },
+
+  /* EVEX_LEN_0F381B_P_2_W_1 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "vbroadcastf64x4",	{ XM, EXymm }, 0 },
+  },
+
+  /* EVEX_LEN_0F385A_P_2_W_0 */
+  {
+    { Bad_Opcode },
+    { "vbroadcasti32x4",	{ XM, EXxmm }, 0 },
+    { "vbroadcasti32x4",	{ XM, EXxmm }, 0 },
+  },
+
+  /* EVEX_LEN_0F385A_P_2_W_1 */
+  {
+    { Bad_Opcode },
+    { "vbroadcasti64x2",	{ XM, EXxmm }, 0 },
+    { "vbroadcasti64x2",	{ XM, EXxmm }, 0 },
+  },
+
+  /* EVEX_LEN_0F385B_P_2_W_0 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "vbroadcasti32x8",	{ XM, EXxmmq }, 0 },
+  },
+
+  /* EVEX_LEN_0F385B_P_2_W_1 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { "vbroadcasti64x4",	{ XM, EXymm }, 0 },
+  },
+
   /* EVEX_LEN_0F3A18_P_2_W_0 */
   {
     { Bad_Opcode },
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 496b8f26a8..c765c849e5 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1938,6 +1938,16 @@  enum
   EVEX_LEN_0F7E_P_1,
   EVEX_LEN_0F7E_P_2,
   EVEX_LEN_0FD6_P_2,
+  EVEX_LEN_0F3819_P_2_W_0,
+  EVEX_LEN_0F3819_P_2_W_1,
+  EVEX_LEN_0F381A_P_2_W_0,
+  EVEX_LEN_0F381A_P_2_W_1,
+  EVEX_LEN_0F381B_P_2_W_0,
+  EVEX_LEN_0F381B_P_2_W_1,
+  EVEX_LEN_0F385A_P_2_W_0,
+  EVEX_LEN_0F385A_P_2_W_1,
+  EVEX_LEN_0F385B_P_2_W_0,
+  EVEX_LEN_0F385B_P_2_W_1,
   EVEX_LEN_0F3A18_P_2_W_0,
   EVEX_LEN_0F3A18_P_2_W_1,
   EVEX_LEN_0F3A19_P_2_W_0,
-- 
2.20.1