Commit c0a30a9f authored by H.J. Lu's avatar H.J. Lu

Enable Intel MOVDIRI, MOVDIR64B instructions

gas/

	* config/tc-i386.c (cpu_arch): Add .movdir, .movdir64b.
	(cpu_noarch): Likewise.
	(process_suffix): Add check for register size.
	* doc/c-i386.texi: Document movdiri, movdir64b.
	* testsuite/gas/i386/i386.exp: Run MOVDIR{I,64B} tests.
	* testsuite/gas/i386/movdir-intel.d: New file.
	* testsuite/gas/i386/movdir.d: Likewise.
	* testsuite/gas/i386/movdir.s: Likewise.
	* testsuite/gas/i386/movdir64b-reg.s: Likewise.
	* testsuite/gas/i386/movdir64b-reg.l: Likewise.
	* testsuite/gas/i386/x86-64-movdir-intel.d: Likewise.
	* testsuite/gas/i386/x86-64-movdir.d: Likewise.
	* testsuite/gas/i386/x86-64-movdir.s: Likewise.
	* testsuite/gas/i386/x86-64-movdir64b-reg.s: Likewise.
	* testsuite/gas/i386/x86-64-movdir64b-reg.l: Likewise.

opcodes/

	* i386-dis.c (Gva): New.
	(enum): Add PREFIX_0F38F8, PREFIX_0F38F9,
	MOD_0F38F8_PREFIX_2, MOD_0F38F9_PREFIX_0.
	(prefix_table): New instructions (see prefix above).
	(mod_table): New instructions (see prefix above).
	(OP_G): Handle va_mode.
	* i386-gen.c (cpu_flag_init): Add CPU_MOVDIRI_FLAGS,
	CPU_MOVDIR64B_FLAGS.
	(cpu_flags): Add CpuMOVDIRI and CpuMOVDIR64B.
	* i386-opc.h (enum): Add CpuMOVDIRI, CpuMOVDIR64B.
	(i386_cpu_flags): Add cpumovdiri and cpumovdir64b.
	* i386-opc.tbl: Add movidir{i,64b}.
	* i386-init.h: Regenerated.
	* i386-tbl.h: Likewise.
parent 75c0a438
2018-05-07 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (cpu_arch): Add .movdir, .movdir64b.
(cpu_noarch): Likewise.
(process_suffix): Add check for register size.
* doc/c-i386.texi: Document movdiri, movdir64b.
* testsuite/gas/i386/i386.exp: Run MOVDIR{I,64B} tests.
* testsuite/gas/i386/movdir-intel.d: New file.
* testsuite/gas/i386/movdir.d: Likewise.
* testsuite/gas/i386/movdir.s: Likewise.
* testsuite/gas/i386/movdir64b-reg.s: Likewise.
* testsuite/gas/i386/movdir64b-reg.l: Likewise.
* testsuite/gas/i386/x86-64-movdir-intel.d: Likewise.
* testsuite/gas/i386/x86-64-movdir.d: Likewise.
* testsuite/gas/i386/x86-64-movdir.s: Likewise.
* testsuite/gas/i386/x86-64-movdir64b-reg.s: Likewise.
* testsuite/gas/i386/x86-64-movdir64b-reg.l: Likewise.
2018-05-07 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (process_suffix): Check addrprefixopreg
......
......@@ -1029,6 +1029,10 @@ static const arch_entry cpu_arch[] =
CPU_WAITPKG_FLAGS, 0 },
{ STRING_COMMA_LEN (".cldemote"), PROCESSOR_UNKNOWN,
CPU_CLDEMOTE_FLAGS, 0 },
{ STRING_COMMA_LEN (".movdiri"), PROCESSOR_UNKNOWN,
CPU_MOVDIRI_FLAGS, 0 },
{ STRING_COMMA_LEN (".movdir64b"), PROCESSOR_UNKNOWN,
CPU_MOVDIR64B_FLAGS, 0 },
};
static const noarch_entry cpu_noarch[] =
......@@ -1064,6 +1068,8 @@ static const noarch_entry cpu_noarch[] =
{ STRING_COMMA_LEN ("noavx512_bitalg"), CPU_ANY_AVX512_BITALG_FLAGS },
{ STRING_COMMA_LEN ("noibt"), CPU_ANY_IBT_FLAGS },
{ STRING_COMMA_LEN ("noshstk"), CPU_ANY_SHSTK_FLAGS },
{ STRING_COMMA_LEN ("nomovdiri"), CPU_ANY_MOVDIRI_FLAGS },
{ STRING_COMMA_LEN ("nomovdir64b"), CPU_ANY_MOVDIR64B_FLAGS },
};
#ifdef I386COFF
......@@ -6044,6 +6050,41 @@ process_suffix (void)
break;
}
if (i.reg_operands != 0
&& i.operands > 1
&& i.tm.opcode_modifier.addrprefixopreg
&& !i.tm.opcode_modifier.immext)
{
/* Check invalid register operand when the address size override
prefix changes the size of register operands. */
unsigned int op;
enum { need_word, need_dword, need_qword } need;
if (flag_code == CODE_32BIT)
need = i.prefix[ADDR_PREFIX] ? need_word : need_dword;
else
{
if (i.prefix[ADDR_PREFIX])
need = need_dword;
else
need = flag_code == CODE_64BIT ? need_qword : need_word;
}
for (op = 0; op < i.operands; op++)
if (i.types[op].bitfield.reg
&& ((need == need_word
&& !i.op[op].regs->reg_type.bitfield.word)
|| (need == need_dword
&& !i.op[op].regs->reg_type.bitfield.dword)
|| (need == need_qword
&& !i.op[op].regs->reg_type.bitfield.qword)))
{
as_bad (_("invalid register operand size for `%s'"),
i.tm.name);
return 0;
}
}
return 1;
}
......
......@@ -176,6 +176,8 @@ accept various extension mnemonics. For example,
@code{clflushopt},
@code{se1},
@code{clwb},
@code{movdiri},
@code{movdir64b},
@code{avx512f},
@code{avx512cd},
@code{avx512er},
......@@ -1276,6 +1278,7 @@ supported on the CPU specified. The choices for @var{cpu_type} are:
@item @samp{.clwb} @tab @samp{.rdpid} @tab @samp{.ptwrite} @tab @item @samp{.ibt}
@item @samp{.wbnoinvd} @tab @samp{.pconfig} @tab @samp{.waitpkg} @tab @samp{.cldemote}
@item @samp{.shstk} @tab @samp{.gfni} @tab @samp{.vaes} @tab @samp{.vpclmulqdq}
@item @samp{.movdiri} @tab @samp{.movdir64b}
@item @samp{.3dnow} @tab @samp{.3dnowa} @tab @samp{.sse4a} @tab @samp{.sse5}
@item @samp{.syscall} @tab @samp{.rdtscp} @tab @samp{.svme} @tab @samp{.abm}
@item @samp{.lwp} @tab @samp{.fma4} @tab @samp{.xop} @tab @samp{.cx16}
......
......@@ -431,6 +431,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
run_dump_test "waitpkg-intel"
run_dump_test "cldemote"
run_dump_test "cldemote-intel"
run_dump_test "movdir"
run_dump_test "movdir-intel"
run_list_test "movdir64b-reg"
run_list_test "avx512vl-1" "-al"
run_list_test "avx512vl-2" "-al"
run_list_test "avx512vl-plain" "-al"
......@@ -924,6 +927,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
run_dump_test "x86-64-waitpkg-intel"
run_dump_test "x86-64-cldemote"
run_dump_test "x86-64-cldemote-intel"
run_dump_test "x86-64-movdir"
run_dump_test "x86-64-movdir-intel"
run_list_test "x86-64-movdir64b-reg"
run_dump_test "x86-64-fence-as-lock-add-yes"
run_dump_test "x86-64-fence-as-lock-add-no"
run_dump_test "x86-64-pr20141"
......
#as:
#objdump: -dw -Mintel
#name: i386 MOVDIR[I,64B] insns (Intel disassembly)
#source: movdir.s
.*: +file format .*
Disassembly of section \.text:
00000000 <_start>:
[ ]*[a-f0-9]+:[ ]*0f 38 f9 01[ ]*movdiri DWORD PTR \[ecx\],eax
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b eax,\[ecx\]
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 04[ ]*movdir64b ax,\[si\]
[ ]*[a-f0-9]+:[ ]*0f 38 f9 01[ ]*movdiri DWORD PTR \[ecx\],eax
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b eax,\[ecx\]
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 04[ ]*movdir64b ax,\[si\]
#pass
#as:
#objdump: -dw
#name: i386 MOVDIR[I,64B] insns
#source: movdir.s
.*: +file format .*
Disassembly of section \.text:
00000000 <_start>:
[ ]*[a-f0-9]+:[ ]*0f 38 f9 01[ ]*movdiri %eax,\(%ecx\)
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b \(%ecx\),%eax
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 04[ ]*movdir64b \(%si\),%ax
[ ]*[a-f0-9]+:[ ]*0f 38 f9 01[ ]*movdiri %eax,\(%ecx\)
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b \(%ecx\),%eax
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 04[ ]*movdir64b \(%si\),%ax
#pass
# Check MOVDIR[I,64B] 32-bit instructions
.allow_index_reg
.text
_start:
movdiri %eax, (%ecx)
movdir64b (%ecx),%eax
movdir64b (%si),%ax
.intel_syntax noprefix
movdiri [ecx], eax
movdir64b eax,[ecx]
movdir64b ax,[si]
.*: Assembler messages:
.*:6: Error: invalid register operand size for `movdir64b'
.*:7: Error: invalid register operand size for `movdir64b'
.*:10: Error: invalid register operand size for `movdir64b'
.*:11: Error: invalid register operand size for `movdir64b'
# Check error for MOVDIR64B 32-bit instructions
.allow_index_reg
.text
_start:
movdir64b (%si),%eax
movdir64b (%esi),%ax
.intel_syntax noprefix
movdir64b eax,[si]
movdir64b ax,[esi]
#as:
#objdump: -dw -Mintel
#name: x86_64 MOVDIR[I,64B] insns (Intel disassembly)
#source: x86-64-movdir.s
.*: +file format .*
Disassembly of section \.text:
0+ <_start>:
[ ]*[a-f0-9]+:[ ]*48 0f 38 f9 01[ ]*movdiri QWORD PTR \[rcx\],rax
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b rax,\[rcx\]
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 01[ ]*movdir64b eax,\[ecx]
[ ]*[a-f0-9]+:[ ]*48 0f 38 f9 01[ ]*movdiri QWORD PTR \[rcx\],rax
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b rax,\[rcx\]
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 01[ ]*movdir64b eax,\[ecx\]
#pass
#as:
#objdump: -dw
#name: x86_64 MOVDIR[I,64B] insns
#source: x86-64-movdir.s
.*: +file format .*
Disassembly of section \.text:
0+ <_start>:
[ ]*[a-f0-9]+:[ ]*48 0f 38 f9 01[ ]*movdiri %rax,\(%rcx\)
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b \(%rcx\),%rax
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 01[ ]*movdir64b \(%ecx\),%eax
[ ]*[a-f0-9]+:[ ]*48 0f 38 f9 01[ ]*movdiri %rax,\(%rcx\)
[ ]*[a-f0-9]+:[ ]*66 0f 38 f8 01[ ]*movdir64b \(%rcx\),%rax
[ ]*[a-f0-9]+:[ ]*67 66 0f 38 f8 01[ ]*movdir64b \(%ecx\),%eax
#pass
# Check MOVDIR[I,64B] 64-bit instructions
.allow_index_reg
.text
_start:
movdiri %rax, (%rcx)
movdir64b (%rcx),%rax
movdir64b (%ecx),%eax
.intel_syntax noprefix
movdiri [rcx],rax
movdir64b rax,[rcx]
movdir64b eax,[ecx]
.*: Assembler messages:
.*:6: Error: invalid register operand size for `movdir64b'
.*:7: Error: invalid register operand size for `movdir64b'
.*:10: Error: invalid register operand size for `movdir64b'
.*:11: Error: invalid register operand size for `movdir64b'
# Check error for MOVDIR64B 32-bit instructions
.allow_index_reg
.text
_start:
movdir64b (%esi),%rax
movdir64b (%rsi),%eax
.intel_syntax noprefix
movdir64b rax,[esi]
movdir64b eax,[rsi]
2018-05-07 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
H.J. Lu <hongjiu.lu@intel.com>
* i386-dis.c (Gva): New.
(enum): Add PREFIX_0F38F8, PREFIX_0F38F9,
MOD_0F38F8_PREFIX_2, MOD_0F38F9_PREFIX_0.
(prefix_table): New instructions (see prefix above).
(mod_table): New instructions (see prefix above).
(OP_G): Handle va_mode.
* i386-gen.c (cpu_flag_init): Add CPU_MOVDIRI_FLAGS,
CPU_MOVDIR64B_FLAGS.
(cpu_flags): Add CpuMOVDIRI and CpuMOVDIR64B.
* i386-opc.h (enum): Add CpuMOVDIRI, CpuMOVDIR64B.
(i386_cpu_flags): Add cpumovdiri and cpumovdir64b.
* i386-opc.tbl: Add movidir{i,64b}.
* i386-init.h: Regenerated.
* i386-tbl.h: Likewise.
2018-05-07 H.J. Lu <hongjiu.lu@intel.com>
* i386-gen.c (opcode_modifiers): Replace AddrPrefixOp0 with
......
......@@ -281,6 +281,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define Gd { OP_G, d_mode }
#define Gdq { OP_G, dq_mode }
#define Gm { OP_G, m_mode }
#define Gva { OP_G, va_mode }
#define Gw { OP_G, w_mode }
#define Rd { OP_R, d_mode }
#define Rdq { OP_R, dq_mode }
......@@ -835,6 +836,8 @@ enum
MOD_0F382A_PREFIX_2,
MOD_0F38F5_PREFIX_2,
MOD_0F38F6_PREFIX_0,
MOD_0F38F8_PREFIX_2,
MOD_0F38F9_PREFIX_0,
MOD_62_32BIT,
MOD_C4_32BIT,
MOD_C5_32BIT,
......@@ -1081,6 +1084,8 @@ enum
PREFIX_0F38F1,
PREFIX_0F38F5,
PREFIX_0F38F6,
PREFIX_0F38F8,
PREFIX_0F38F9,
PREFIX_0F3A08,
PREFIX_0F3A09,
PREFIX_0F3A0A,
......@@ -4680,6 +4685,18 @@ static const struct dis386 prefix_table[][4] = {
{ Bad_Opcode },
},
/* PREFIX_0F38F8 */
{
{ Bad_Opcode },
{ Bad_Opcode },
{ MOD_TABLE (MOD_0F38F8_PREFIX_2) },
},
/* PREFIX_0F38F9 */
{
{ MOD_TABLE (MOD_0F38F9_PREFIX_0) },
},
/* PREFIX_0F3A08 */
{
{ Bad_Opcode },
......@@ -7444,8 +7461,8 @@ static const struct dis386 three_byte_table[][256] = {
{ PREFIX_TABLE (PREFIX_0F38F6) },
{ Bad_Opcode },
/* f8 */
{ Bad_Opcode },
{ Bad_Opcode },
{ PREFIX_TABLE (PREFIX_0F38F8) },
{ PREFIX_TABLE (PREFIX_0F38F9) },
{ Bad_Opcode },
{ Bad_Opcode },
{ Bad_Opcode },
......@@ -11836,6 +11853,14 @@ static const struct dis386 mod_table[][2] = {
/* MOD_0F38F6_PREFIX_0 */
{ "wrssK", { M, Gdq }, PREFIX_OPCODE },
},
{
/* MOD_0F38F8_PREFIX_2 */
{ "movdir64b", { Gva, M }, PREFIX_OPCODE },
},
{
/* MOD_0F38F9_PREFIX_0 */
{ "movdiri", { Em, Gv }, PREFIX_OPCODE },
},
{
/* MOD_62_32BIT */
{ "bound{S|}", { Gv, Ma }, 0 },
......@@ -15652,6 +15677,7 @@ static void
OP_G (int bytemode, int sizeflag)
{
int add = 0;
const char **names;
USED_REX (REX_R);
if (rex & REX_R)
add += 8;
......@@ -15700,6 +15726,24 @@ OP_G (int bytemode, int sizeflag)
used_prefixes |= (prefixes & PREFIX_DATA);
}
break;
case va_mode:
names = (address_mode == mode_64bit
? names64 : names32);
if (!(prefixes & PREFIX_ADDR))
{
if (address_mode == mode_16bit)
names = names16;
}
else
{
/* Remove "addr16/addr32". */
all_prefixes[last_addr_prefix] = 0;
names = (address_mode != mode_32bit
? names32 : names16);
used_prefixes |= PREFIX_ADDR;
}
oappend (names[modrm.reg + add]);
break;
case m_mode:
if (address_mode == mode_64bit)
oappend (names64[modrm.reg + add]);
......
......@@ -283,6 +283,10 @@ static initializer cpu_flag_init[] =
"CpuWAITPKG" },
{ "CPU_CLDEMOTE_FLAGS",
"CpuCLDEMOTE" },
{ "CPU_MOVDIRI_FLAGS",
"CpuMOVDIRI" },
{ "CPU_MOVDIR64B_FLAGS",
"CpuMOVDIR64B" },
{ "CPU_ANY_X87_FLAGS",
"CPU_ANY_287_FLAGS|Cpu8087" },
{ "CPU_ANY_287_FLAGS",
......@@ -343,6 +347,10 @@ static initializer cpu_flag_init[] =
"CpuAVX512_VNNI" },
{ "CPU_ANY_AVX512_BITALG_FLAGS",
"CpuAVX512_BITALG" },
{ "CPU_ANY_MOVDIRI_FLAGS",
"CpuMOVDIRI" },
{ "CPU_ANY_MOVDIR64B_FLAGS",
"CpuMOVDIR64B" },
};
static const initializer operand_type_shorthands[] =
......@@ -577,6 +585,8 @@ static bitfield cpu_flags[] =
BITFIELD (CpuPCONFIG),
BITFIELD (CpuWAITPKG),
BITFIELD (CpuCLDEMOTE),
BITFIELD (CpuMOVDIRI),
BITFIELD (CpuMOVDIR64B),
#ifdef CpuUnused
BITFIELD (CpuUnused),
#endif
......
This diff is collapsed.
......@@ -231,6 +231,10 @@ enum
CpuWAITPKG,
/* CLDEMOTE instruction required */
CpuCLDEMOTE,
/* MOVDIRI instruction support required */
CpuMOVDIRI,
/* MOVDIRR64B instruction required */
CpuMOVDIR64B,
/* 64bit support required */
Cpu64,
/* Not supported in the 64bit mode */
......@@ -354,6 +358,8 @@ typedef union i386_cpu_flags
unsigned int cpupconfig:1;
unsigned int cpuwaitpkg:1;
unsigned int cpucldemote:1;
unsigned int cpumovdiri:1;
unsigned int cpumovdir64b:1;
unsigned int cpu64:1;
unsigned int cpuno64:1;
#ifdef CpuUnused
......
......@@ -5829,3 +5829,12 @@ umwait, 1, 0xf20fae, 0x6, 2, CpuWAITPKG, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|N
cldemote, 1, 0x0f1c, 0x0, 2, CpuCLDEMOTE, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Anysize|BaseIndex }
// CLDEMOTE instructions end.
// MOVDIR[I,64B] instructions.
movdiri, 2, 0xf38f9, None, 3, CpuMOVDIRI, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Reg64, Dword|Qword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S }
movdir64b, 2, 0x660f38f8, None, 3, CpuMOVDIR64B|CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|AddrPrefixOpReg, { Unspecified|BaseIndex|Disp8|Disp16|Disp32, Reg16|Reg32 }
movdir64b, 2, 0x660f38f8, None, 3, CpuMOVDIR64B|Cpu64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoRex64|AddrPrefixOpReg, { Unspecified|BaseIndex|Disp8|Disp32|Disp32S, Reg32|Reg64 }
// MOVEDIR instructions end.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment