This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 3/3] Enable Intel MOVDIRI, MOVDIR64B instructions.


On Thu, Apr 26, 2018 at 11:40 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 26.04.18 at 21:49, <igor.v.tsimbalist@intel.com> wrote:
>>--- /dev/null
>>+++ b/gas/testsuite/gas/i386/x86-64-movdir-intel.d
>>@@ -0,0 +1,18 @@
>>+#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[       ]*rex\.W 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[       ]*rex\.W movdiri QWORD PTR \[rcx\],rax
>
> What are the REX.W doing here (also in the AT&T counterpart)?
>
>>--- a/opcodes/i386-opc.h
>>+++ b/opcodes/i386-opc.h
>>@@ -231,6 +231,10 @@ enum
>>   CpuWAITPKG,
>>   /* CLDEMOTE instruction required */
>>   CpuCLDEMOTE,
>>+  /* MOVDIRI instruction support required */
>>+  CpuMOVDIRI,
>>+  /* MOVDIRR64B instruction required */
>>+  CpuMOVDIR64B,
>>   /* MMX register support required */
>>   CpuRegMMX,
>>   /* XMM register support required */
>
> Considering patch context here, this clearly wasn't re-based onto the
> tip of master before submitting.

Fixed.

>>@@ -628,6 +638,7 @@ static bitfield opcode_modifiers[] =
>>   BITFIELD (ToDword),
>>   BITFIELD (ToQword),
>>   BITFIELD (AddrPrefixOp0),
>>+  BITFIELD (AddrPrefixOpReg),
>
> I'm not convinced this new attribute is needed - I'd much rather see
> AddrPrefixOp0 re-purposed/generalized (and suitably renamed, e.g.
> simply the 0 stripped). This is based on the fact that so far that
> existing attribute is used only in templates not allowing for a memory
> operand at all.

AddrPrefixOp0 has been renamed to AddrPrefixOpReg by

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=75c0a438994f00240ecd1baca3e3c11cc3b219e5

> H.J., considering the effort I'm putting in to overcome some of the
> easiest-possible-solution things that have been allowed in, I'd much
> appreciate if you would push for at least investigation of whether a
> more elaborate approach exists before allowing in in particular single
> use new insn attributes.
>
>>+movdiri, 2, 0xf38f9, None, 3, CpuMOVDIRI, Modrm|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32, Dword|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S }
>>+movdiri, 2, 0xf38f9, None, 3, CpuMOVDIRI|Cpu64, Modrm|CheckRegSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg64, Dword|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S }
>
> I don't understand why you need two templates here. And if you really
> do, Dword on the 64-bit one looks wrong as do Qword and Disp32S on
> the 32-bit one. Disp16 is missing in any case. I also don't see the point
> of CheckRegSize - there is only a single register operand (the attribute
> has meaning for memory operands only on SIMD templates).

Fixed.

>>+movdir64b, 2, 0x660f38f8, None, 3, CpuMOVDIR64B|CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|AddrPrefixOpReg, { Unspecified|ZMMword|BaseIndex|Disp8|Disp32|Disp32S, 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|ZMMword|BaseIndex|Disp8|Disp32|Disp32S, Reg32|Reg64 }
>
> Almost all the same here. Additionally, while I can see that ZMMword fits
> the 64-byte operand size, I really think it would look rather odd to have
> "zmmword ptr" used on an operand here. Simply require no operand size
> prefix (in Intel syntax mode), just like you make the disassembler not
> produce any?
>

Fixed.  We need 2 templates since Reg16 isn't supported in 64-bit mode.

This is the patch I am going to check in later.

Thanks.

-- 
H.J.
From a597b088f75552fec1d3fc4275db509b81b2f1c2 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 7 May 2018 09:30:02 -0700
Subject: [PATCH] Enable Intel MOVDIRI, MOVDIR64B instruction

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.
---
 gas/ChangeLog                                 |   19 +
 gas/config/tc-i386.c                          |   41 +
 gas/doc/c-i386.texi                           |    3 +
 gas/testsuite/gas/i386/i386.exp               |    6 +
 gas/testsuite/gas/i386/movdir-intel.d         |   18 +
 gas/testsuite/gas/i386/movdir.d               |   18 +
 gas/testsuite/gas/i386/movdir.s               |   13 +
 gas/testsuite/gas/i386/movdir64b-reg.l        |    5 +
 gas/testsuite/gas/i386/movdir64b-reg.s        |   11 +
 gas/testsuite/gas/i386/x86-64-movdir-intel.d  |   18 +
 gas/testsuite/gas/i386/x86-64-movdir.d        |   18 +
 gas/testsuite/gas/i386/x86-64-movdir.s        |   13 +
 gas/testsuite/gas/i386/x86-64-movdir64b-reg.l |    5 +
 gas/testsuite/gas/i386/x86-64-movdir64b-reg.s |   11 +
 opcodes/ChangeLog                             |   18 +
 opcodes/i386-dis.c                            |   48 +-
 opcodes/i386-gen.c                            |   10 +
 opcodes/i386-init.h                           |  334 +-
 opcodes/i386-opc.h                            |    6 +
 opcodes/i386-opc.tbl                          |    9 +
 opcodes/i386-tbl.h                            | 9975 +++++++++--------
 21 files changed, 5484 insertions(+), 5115 deletions(-)
 create mode 100644 gas/testsuite/gas/i386/movdir-intel.d
 create mode 100644 gas/testsuite/gas/i386/movdir.d
 create mode 100644 gas/testsuite/gas/i386/movdir.s
 create mode 100644 gas/testsuite/gas/i386/movdir64b-reg.l
 create mode 100644 gas/testsuite/gas/i386/movdir64b-reg.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-movdir-intel.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-movdir.d
 create mode 100644 gas/testsuite/gas/i386/x86-64-movdir.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-movdir64b-reg.l
 create mode 100644 gas/testsuite/gas/i386/x86-64-movdir64b-reg.s

diff --git a/gas/ChangeLog b/gas/ChangeLog
index fe622f81ec..971e42a4c5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,22 @@
+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
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index b4c93a2d2c..be31d9e6f1 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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;
 }
 
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 3d459e2f75..7e07755b72 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -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}
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index e061c67fbe..c691a025cc 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -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"
diff --git a/gas/testsuite/gas/i386/movdir-intel.d b/gas/testsuite/gas/i386/movdir-intel.d
new file mode 100644
index 0000000000..d6eab9c0c2
--- /dev/null
+++ b/gas/testsuite/gas/i386/movdir-intel.d
@@ -0,0 +1,18 @@
+#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
diff --git a/gas/testsuite/gas/i386/movdir.d b/gas/testsuite/gas/i386/movdir.d
new file mode 100644
index 0000000000..852b20d8a3
--- /dev/null
+++ b/gas/testsuite/gas/i386/movdir.d
@@ -0,0 +1,18 @@
+#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
diff --git a/gas/testsuite/gas/i386/movdir.s b/gas/testsuite/gas/i386/movdir.s
new file mode 100644
index 0000000000..28dfa6154a
--- /dev/null
+++ b/gas/testsuite/gas/i386/movdir.s
@@ -0,0 +1,13 @@
+# 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]
diff --git a/gas/testsuite/gas/i386/movdir64b-reg.l b/gas/testsuite/gas/i386/movdir64b-reg.l
new file mode 100644
index 0000000000..e01d20deb3
--- /dev/null
+++ b/gas/testsuite/gas/i386/movdir64b-reg.l
@@ -0,0 +1,5 @@
+.*: 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'
diff --git a/gas/testsuite/gas/i386/movdir64b-reg.s b/gas/testsuite/gas/i386/movdir64b-reg.s
new file mode 100644
index 0000000000..ace5e86edb
--- /dev/null
+++ b/gas/testsuite/gas/i386/movdir64b-reg.s
@@ -0,0 +1,11 @@
+# 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]
diff --git a/gas/testsuite/gas/i386/x86-64-movdir-intel.d b/gas/testsuite/gas/i386/x86-64-movdir-intel.d
new file mode 100644
index 0000000000..f6c2548d1c
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movdir-intel.d
@@ -0,0 +1,18 @@
+#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
diff --git a/gas/testsuite/gas/i386/x86-64-movdir.d b/gas/testsuite/gas/i386/x86-64-movdir.d
new file mode 100644
index 0000000000..fd7f4e5864
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movdir.d
@@ -0,0 +1,18 @@
+#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
diff --git a/gas/testsuite/gas/i386/x86-64-movdir.s b/gas/testsuite/gas/i386/x86-64-movdir.s
new file mode 100644
index 0000000000..f0fe267978
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movdir.s
@@ -0,0 +1,13 @@
+# 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]
diff --git a/gas/testsuite/gas/i386/x86-64-movdir64b-reg.l b/gas/testsuite/gas/i386/x86-64-movdir64b-reg.l
new file mode 100644
index 0000000000..e01d20deb3
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movdir64b-reg.l
@@ -0,0 +1,5 @@
+.*: 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'
diff --git a/gas/testsuite/gas/i386/x86-64-movdir64b-reg.s b/gas/testsuite/gas/i386/x86-64-movdir64b-reg.s
new file mode 100644
index 0000000000..4aeb6d3705
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-movdir64b-reg.s
@@ -0,0 +1,11 @@
+# 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]
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 6da4fc07d8..b1abf301f9 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,21 @@
+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
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 98950e20f0..42d219cb11 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -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]);
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 8334c4ac85..66f20fd09d 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -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
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index 570da28955..9a22b3c95f 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -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
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index 2382c61971..b3ccaa4f8c 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]