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.
This commit is contained in:
H.J. Lu 2018-09-14 10:49:43 -07:00
parent 5074ad8a66
commit d20dee9efa
7 changed files with 58 additions and 4 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -1,3 +1,14 @@
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.

View File

@ -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 */
{

View File

@ -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 ();
}