[binutils-gdb] x86: Properly decode EVEX.W in vcvt[u]si2s[sd] in 32-bit mode

H.J.Lu hjl@sourceware.org
Fri Sep 14 17:50:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d20dee9efad3c23c9098f03ac785037572258483

commit d20dee9efad3c23c9098f03ac785037572258483
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Sep 14 10:49:43 2018 -0700

    x86: Properly decode EVEX.W in vcvt[u]si2s[sd] in 32-bit mode
    
    Update x86 disassembler to ignore the EVEX.W bit in EVEX vcvt[u]si2s[sd]
    instructions in 32-bit mode.
    
    gas/
    
    	PR binutils/23655
    	* testsuite/gas/i386/evex.d: New file.
    	* testsuite/gas/i386/evex.s: Likewise.
    	* testsuite/gas/i386/i386.exp: Run evex.
    
    opcodes/
    
    	PR binutils/23655
    	* i386-dis-evex.h (evex_table): Replace Eq with Edqa for
    	vcvtsi2ss%LQ, vcvtsi2sd%LQ, vcvtusi2ss%LQ and vcvtusi2sd%LQ.
    	* i386-dis.c (Edqa): New.
    	(dqa_mode): Likewise.
    	(intel_operand_size): Handle dqa_mode as m_mode.
    	(OP_E_register): Handle dqa_mode as dq_mode.
    	(OP_E_memory): Set shift for dqa_mode based on address_mode.

Diff:
---
 gas/ChangeLog                   |  7 +++++++
 gas/testsuite/gas/i386/evex.d   | 16 ++++++++++++++++
 gas/testsuite/gas/i386/evex.s   | 11 +++++++++++
 gas/testsuite/gas/i386/i386.exp |  1 +
 opcodes/ChangeLog               | 11 +++++++++++
 opcodes/i386-dis-evex.h         |  8 ++++----
 opcodes/i386-dis.c              |  8 ++++++++
 7 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 37a864a..52346d7 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR binutils/23655
+	* testsuite/gas/i386/evex.d: New file.
+	* testsuite/gas/i386/evex.s: Likewise.
+	* testsuite/gas/i386/i386.exp: Run evex.
+
 2018-09-10  Lifang Xia <lifang_xia@c-sky.com>
 
 	* config/tc-csky.c (md_apply_fix): Transmit BFD_RELOC_32_PCREL to
diff --git a/gas/testsuite/gas/i386/evex.d b/gas/testsuite/gas/i386/evex.d
new file mode 100644
index 0000000..ffbcdc1
--- /dev/null
+++ b/gas/testsuite/gas/i386/evex.d
@@ -0,0 +1,16 @@
+#objdump: -dw -Msuffix
+#name: i386 EVX insns
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+:	62 f1 d6 38 2a f0    	vcvtsi2ssl %eax,\{rd-sae\},%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d7 38 2a f0    	vcvtsi2sdl %eax,\{rd-sae\},%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d6 08 7b f0    	vcvtusi2ssl %eax,%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d7 08 7b f0    	vcvtusi2sdl %eax,%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d6 38 7b f0    	vcvtusi2ssl %eax,\{rd-sae\},%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d7 38 7b f0    	vcvtusi2sdl %eax,\{rd-sae\},%xmm5,%xmm6
+#pass
diff --git a/gas/testsuite/gas/i386/evex.s b/gas/testsuite/gas/i386/evex.s
new file mode 100644
index 0000000..a64cc57
--- /dev/null
+++ b/gas/testsuite/gas/i386/evex.s
@@ -0,0 +1,11 @@
+# Check EVEX instructions
+
+	.allow_index_reg
+	.text
+_start:
+	.byte 0x62, 0xf1, 0xd6, 0x38, 0x2a, 0xf0
+	.byte 0x62, 0xf1, 0xd7, 0x38, 0x2a, 0xf0
+	.byte 0x62, 0xf1, 0xd6, 0x08, 0x7b, 0xf0
+	.byte 0x62, 0xf1, 0xd7, 0x08, 0x7b, 0xf0
+	.byte 0x62, 0xf1, 0xd6, 0x38, 0x7b, 0xf0
+	.byte 0x62, 0xf1, 0xd7, 0x38, 0x7b, 0xf0
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 088fece..203def9 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -226,6 +226,7 @@ if [expr ([istarget "i*86-*-*"] ||  [istarget "x86_64-*-*"]) && [gas_32_check]]
     run_dump_test "avx512er-intel"
     run_dump_test "avx512pf"
     run_dump_test "avx512pf-intel"
+    run_dump_test "evex"
     run_dump_test "evex-lig256"
     run_dump_test "evex-lig512"
     run_dump_test "evex-lig256-intel"
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 4895fc3..7def411 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,16 @@
 2018-09-14  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR binutils/23655
+	* i386-dis-evex.h (evex_table): Replace Eq with Edqa for
+	vcvtsi2ss%LQ, vcvtsi2sd%LQ, vcvtusi2ss%LQ and vcvtusi2sd%LQ.
+	* i386-dis.c (Edqa): New.
+	(dqa_mode): Likewise.
+	(intel_operand_size): Handle dqa_mode as m_mode.
+	(OP_E_register): Handle dqa_mode as dq_mode.
+	(OP_E_memory): Set shift for dqa_mode based on address_mode.
+
+2018-09-14  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* i386-dis.c (OP_E_memory): Reformat.
 
 2018-09-14  Jan Beulich  <jbeulich@suse.com>
diff --git a/opcodes/i386-dis-evex.h b/opcodes/i386-dis-evex.h
index 8b82578..f59c7cc 100644
--- a/opcodes/i386-dis-evex.h
+++ b/opcodes/i386-dis-evex.h
@@ -3046,12 +3046,12 @@ static const struct dis386 evex_table[][256] = {
   /* EVEX_W_0F2A_P_1 */
   {
     { "vcvtsi2ss%LQ",	{ XMScalar, VexScalar, EXxEVexR, Ed }, 0 },
-    { "vcvtsi2ss%LQ",	{ XMScalar, VexScalar, EXxEVexR, Eq }, 0 },
+    { "vcvtsi2ss%LQ",	{ XMScalar, VexScalar, EXxEVexR, Edqa }, 0 },
   },
   /* EVEX_W_0F2A_P_3 */
   {
     { "vcvtsi2sd%LQ",	{ XMScalar, VexScalar, Ed }, 0 },
-    { "vcvtsi2sd%LQ",	{ XMScalar, VexScalar, EXxEVexR, Eq }, 0 },
+    { "vcvtsi2sd%LQ",	{ XMScalar, VexScalar, EXxEVexR, Edqa }, 0 },
   },
   /* EVEX_W_0F2B_P_0 */
   {
@@ -3383,7 +3383,7 @@ static const struct dis386 evex_table[][256] = {
   /* EVEX_W_0F7B_P_1 */
   {
     { "vcvtusi2ss%LQ",	{ XMScalar, VexScalar, EXxEVexR, Ed }, 0 },
-    { "vcvtusi2ss%LQ",	{ XMScalar, VexScalar, EXxEVexR, Eq }, 0 },
+    { "vcvtusi2ss%LQ",	{ XMScalar, VexScalar, EXxEVexR, Edqa }, 0 },
   },
   /* EVEX_W_0F7B_P_2 */
   {
@@ -3393,7 +3393,7 @@ static const struct dis386 evex_table[][256] = {
   /* EVEX_W_0F7B_P_3 */
   {
     { "vcvtusi2sd%LQ",	{ XMScalar, VexScalar, Ed }, 0 },
-    { "vcvtusi2sd%LQ",	{ XMScalar, VexScalar, EXxEVexR, Eq }, 0 },
+    { "vcvtusi2sd%LQ",	{ XMScalar, VexScalar, EXxEVexR, Edqa }, 0 },
   },
   /* EVEX_W_0F7E_P_1 */
   {
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index f453989..83c6107 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -260,6 +260,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Edb { OP_E, db_mode }
 #define Edw { OP_E, dw_mode }
 #define Edqd { OP_E, dqd_mode }
+#define Edqa { OP_E, dqa_mode }
 #define Eq { OP_E, q_mode }
 #define indirEv { OP_indirE, indir_v_mode }
 #define indirEp { OP_indirE, f_mode }
@@ -591,6 +592,8 @@ enum
   dw_mode,
   /* registers like dq_mode, memory like d_mode.  */
   dqd_mode,
+  /* operand size depends on the W bit as well as address mode.  */
+  dqa_mode,
   /* normal vex mode */
   vex_mode,
   /* 128bit vex mode */
@@ -14805,6 +14808,7 @@ intel_operand_size (int bytemode, int sizeflag)
     case q_swap_mode:
       oappend ("QWORD PTR ");
       break;
+    case dqa_mode:
     case m_mode:
       if (address_mode == mode_64bit)
 	oappend ("QWORD PTR ");
@@ -15163,6 +15167,7 @@ OP_E_register (int bytemode, int sizeflag)
     case dqb_mode:
     case dqd_mode:
     case dqw_mode:
+    case dqa_mode:
       USED_REX (REX_W);
       if (rex & REX_W)
 	names = names64;
@@ -15305,6 +15310,9 @@ OP_E_memory (int bytemode, int sizeflag)
 	case xmm_mb_mode:
 	  shift = 0;
 	  break;
+	case dqa_mode:
+	  shift = address_mode == mode_64bit ? 3 : 2;
+	  break;
 	default:
 	  abort ();
 	}



More information about the Binutils-cvs mailing list